宗成庆《自然语言理解》第三章作业

3-1. 构造上下文无关文法用以产生:
(a) 有相同数目的0 和1 的所有0, 1 符号串。
(b) {a1a2…anan…a2a1|ai∈{0,1}, 1≤ i ≤n}。

(a)解题思路:L(G) ={0^{n}1^{n}},n\geq 0

P:   S->0S1|\varepsilon,     G={{S},{0,1},P,S}

 

(b)

P:S->0S0|1S1|\varepsilon, G={{S},{0,1},P,S}


3-2. 有以下文法:G = ({S,B,C},{a,b,c},P, S),其中:P:

1)S → aSBC | abC,

2)CB → BC,

3)bB → bb,

4)bC → bc,

5)cC → cc,

求L(G)=?

一步步推导可得L(G) ={a^{n}b^{n}c^{n}},n\geq 1

 

3-3. 设文法G 由如下规则定义:
S → AB A → Aa|bB
B → a|Sb
给出下列句子形式的派生树:
(1) baabaab (2) bBABb

(1)

 

(2)


3-4. 写一个程序模拟一个确定性的PDA。

#-------------------------------------------------------------------------------
# Name:        PDA
# Purpose:
#
# Author:      nkenen
#
# Created:     18/02/2020
# Copyright:   (c) postgres 2020
# Licence:     <your licence>
#-------------------------------------------------------------------------------
#构造下推自动器PDA
#确定性和非确定由规则确定和非确定来确定
#当转移时确定只有一个状态为确定性,否则为非确定性
import random

#PDA的栈
class Stack(object):
    def __init__(self):
        self.list = []

    def is_empty(self):
        return self.list == []

    def push(self,item):
        self.list.append(item)

    def pop(self):
        if self.is_empty():
            return
        else:
            return self.list.pop()

    def top(self):
        if self.is_empty():
            return
        else:
            return self.list[-1]

#PDA的跳转规则,由两个列表映射
class Rule(object):
    def __init__(self):
        self.input3p = []#输入条件
        self.output2p = []#输出规则

    def copy(self,other_rule):
        self.input3p = list(other_rule.input3p)
        self.output2p = list(other_rule.output2p)

    def append(self,lsti,lsto):
        self.input3p.append(lsti)#增加条件
        self.output2p.append(lsto)#与之对应增加输出规则

    def out(self,lst):
        index = 0
        index = self.input3p.index(lst)#找到对应规则定位
        return self.output2p[index]#输出映射规则

    def clear(self):
        self.input3p.clear()
        self.output2p.clear()

#PDA结构
class PDA(object):
    def __init__(self,Input,sigma,Q,Gamma,Belta,q0,z0,F):
        self.Input = Input
        self.Sigma =sigma
        self.Q = Q
        self.Gamma = Gamma
        self.rule = Rule()
        self.rule.copy(Belta)
        self.stack = Stack()
        self.q0 = q0
        self.z0 = z0
        self.F = F

    def ruleappend(self,qi,ai,zi,qo,zo):
        self.rule.append(qi,ai,zi,qo,zo)
    
    #下一次跳转条件
    def nextrule(self,lst):
        #(qo,zo)
        return self.rule.out(lst)
    
    #该函数为本次PDA的对应操作函数
    #若为不同的规则不同的输入字符串需要修改
    def PushDownString(self):
        q = self.q0
        zi = None
        zo = self.z0
        for i in range(len(self.Input)+1):
            if q == 1:
                if zi == self.stack.top():
                    self.stack.pop()
                zi = self.stack.top()
            elif q == 0 and zo != None:
                self.stack.push(zo)
                zi = None
            print(self.Input[i:],q,self.stack.list)
            if i < len(self.Input):
                [q,zo] = self.nextrule([q,self.Input[i],zi])
            else:
                self.stack.pop()

class Lanug(object):
    def __init__(self,Gamma):
        self.string = 'c'
        self.Gamma = Gamma

    def create(self,len,num):
        w = ''
        for _ in range(len):
            i = random.randint(0,num)
            w += self.Gamma[i]
        return w+self.string+w[::-1]

#该程序只是模拟一个确定性pda题目的解题步骤
#就是课程ppt上的一个例题,算不算模拟了PDA我也不知道
def main():
    sigma = ['a','b','c']
    Q = [0,1]
    Gamma = {'A','B'}
    Belta = Rule()
    q0 = 0
    z0 = '#'
    F = {1}
    L_creater = Lanug(['a','b','c'])
    Input = L_creater.create(20,1)

    Belta.append([0,'a',None],[0,'A'])
    Belta.append([0,'b',None],[0,'B'])
    Belta.append([0,'c',None],[1,None])
    Belta.append([1,'a','A'],[1,None])
    Belta.append([1,'b','B'],[1,None])

    pda = PDA(Input,sigma,Q,Gamma,Belta,q0,z0,F)
    pda.PushDownString()


    pass

if __name__ == '__main__':
    main()


3-5. 写一个程序以正则文法G 作为输入,构造G 相应的有限自动机。

#-------------------------------------------------------------------------------
# Name:        NFA
# Purpose:
#
# Author:      nkenen
#
# Created:     18/02/2020
# Copyright:   (c) postgres 2020
# Licence:     <your licence>
#-------------------------------------------------------------------------------
class Reggram(object):
    def __init__(self,Vn=[],Vt=[],P={},S=None):
        self.Vn = Vn
        self.Vt = Vt
        self.P = P
        self.S = S
    #打印函数
    def Print(self):
        print("正则文法G:")
        print("VN =",self.Vn)
        print("VT =",self.Vt)
        print("P =",self.P)
        print("S =",self.S)

class Delta(object):
    def __init__(self):
        self.inputp = []
        self.outputp = []

    def copy(self,other_delta):
        self.inputp = list(other_delta.inputp)
        self.outputp = list(other_delta.outputp)

    def append(self,lsti,lsto):
        self.inputp.append(lsti)
        self.outputp.append(lsto)

    #映射的状态空间增值
    def varappend(self,lst,input):
        index = 0
        index = self.inputp.index(lst)
        self.outputp[index].append(input)

    def out(self,lst):
        index = 0
        index = self.inputp.index(lst)
        return self.outputp[index]

    def clear(self):
        self.inputp.clear()
        self.outputp.clear()

    def Print(self):
        for i in range(len(self.inputp)):
            print("δ",self.inputp[i],"=",self.outputp[i])

#注意:DFA与NFA区别在于转移规则是否对应唯一状态
#在程序我就直接用的NFA标注,感觉DFA就是NFA一种特殊情况
class NFA(object):
    def __init__(self,Sigma=[],Q=[],delta=Delta(),q0=None,F=[]):
        self.Sigma = Sigma
        self.Q = Q
        self.delta=delta
        self.q0=q0
        self.F=F

    #将文法转换成自动机的函数
    #根据转化规则
    def gramtonfa(self,G=Reggram()):
        self.Sigma = list(G.Vt)
        self.Q = list(G.Vn)
        self.Q.append('T')
        self.q0 = 'S'
        if None in G.P['S']:
            self.F.append('S')
            self.F.append('T')
        else:
            self.F.append('T')
        for vn in G.Vn:
            if len(vn) ==1:
                for vt in G.Vt:
                    flag = 1
                    self.delta.append([vn,vt],[])
                    for i in G.P[vn]:
                        if i!= None and len(i) == 1:
                            if i[0] == vt:
                                if flag == 1:
                                    self.delta.varappend([vn,vt],'T')
                                    flag = 0
                        elif i!= None and len(i) > 1:
                            if i[0] == vt:
                                if i[1] in G.Vn:
                                    self.delta.varappend([vn,vt],i[1])
        for vt in G.Vt:
            self.delta.append(['T',vt],[])

    def Print(self):
        print("正则文法G相应的有限自动机M:")
        print("∑ =",self.Sigma)
        print("Q =",self.Q)
        self.delta.Print()
        print("q0 =",self.q0)
        print("F =",self.F)


def main():
    #第三张ppt的正则转化例题
    G = Reggram(['S','B'],['a','b'],{'S':['aB'],'B':['bS','aB','a']},'S')
    G.Print()
    M = NFA()
    M.gramtonfa(G)
    M.Print()
    pass

if __name__ == '__main__':
    main()

 

  • 4
    点赞
  • 20
    收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 2

打赏作者

nkenen

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值