我正在攻读考试自动机和正式语言,我必须设计一个识别语言的PDA:
a^n b^m | n<= m <= 3n
我有点想法,但我坚持这个:
首先想到处理所有的“a”和每个“a”推动一个“A”
(q0, a, Z)= (q0, AZ)
(q0, a, A)= (q0, AA)
(q0, b, A)= (q1, A)
(q1, b, A)= (q2, A)
(q2, b, A)= (q3, lambda)
(q3, b, A)= (q1, A)
(q3, lambda, A)= (qf, Z)
(q3, lambda, Z)= (qf, Z)
qf = final state, lambda= delete top of stack, Z= initial symbol of the stack
所以我认为解决方案,但我认为不正确,我做错了什么?
答案 0 :(得分:2)
是的,你的自动机不正确,因为它不接受字符串ab,或者是空字符串。您将获得以下机器状态序列:
- q0 Z
a q0 AZ
b q1 AZ
(doesn't accept)
- q0 Z
(doesn't accept)
由于q1不接受,因此您的机器无法接受ab,这是您所描述的语言。
您有正确的一般想法:为您看到的每个a添加A,然后为您看到的每组1,2或3 b删除A.这个表述显然是不确定的,但除非要求DPDA,否则我们会认为没问题。
(q0, a, Z) => (q0, AZ)
(q0, a, A) => (q0, AA)
(q0, -, Z) => (q1, Z)
(q0, -, A) => (q1, A)
这些转换计算a并将A添加到堆栈中。当你读完一个时,我们可以进入下一个状态q1,然后开始计算b并弹出A。
(q1, -, A) => (q2, A)
(q1, -, A) => (q3, A)
(q1, -, A) => (q4, A)
这些过渡允许机器不确定地选择是否计算特定A的一个,两个或三个b。
(q2, b, A) => (q1, -)
(q3, b, A) => (q5, A)
(q5, b, A) => (q1, -)
(q4, b, A) => (q6, A)
(q6, b, A) => (q7, A)
(q7, b, A) => (q1, -)
这些转换实际上处理一个,两个或三个b的计数并移除A,返回q1以允许从堆栈中移除额外的A。
(q1, -, Z) => (qf, Z)
这种转换允许PDA在A的堆栈耗尽后接受字符串。请注意,如果输入上还有任何b,则PDA将以qf崩溃,因为那里没有定义转换;并且因为它崩溃了,所以不接受该字符串(即使堆栈为空并且它在接受状态下崩溃)。
解决此问题的另一种方法是为此语言构造CFG,然后构建自上而下或自下而上的解析器。这种语言的简易CFG是:
S := aSb | aSbb | aSbbb
如果需要DPDA,这是一个更难的问题,答案可能是“没有DPDA存在”。说实话,我没有考虑过为这种语言建立DPDA。
答案 1 :(得分:0)
我知道这有点晚了,但是我遇到了一个相同的问题,我想如果有一个不同的解决方案,那么基本的想法是你将你的堆栈分成3个具有以下属性的分区
最上面的分区 - 第三个分区 - 其目的是确保b的计数至少等于a的计数-n-,中间分区 - 第二个 - 是为了确保b的计数小于或者等于2n,最后一个分区是为了确保b的计数不超过2n;所以这是基本的想法,当然它是NPDA,这里是确切的过渡:
(q0 , a , #) => (q0 , A#)
(q0 , a , A) => (q0 , AA)
(q0 , a , B) => (q0 , AB)
(q0 , b , A) => (q0 , BA)
(q0 , b , B) => (q0 , BB)
(q0 , lambda , A) => (q0 , AA)
(q0 , lambda , B) => (q0 , AB)
(q0 , lambda , B) => (q0 , BB)
(q0 , lambda , A) => (q0 , BA)
(q0 , b , A) => (q1 , match) >> -match means removing the top of the stack with the current element-
现在我们转到q1以确保b的计数至少等于a的计数:
(q1 , b , A) => (q1 , match)
(q1 , # , B) => (qf , -) >> -this means that i matched equal number of a's and b's and i can halt if there is no more input-
(q1 , b , B) => (q2 , match)
现在我们转到q2以确保b的计数小于或等于2n:
(q2 , b , B) => (q2 , match)
(q2 , # , A) => (qf , -)
(q2 , # , B) => (qf , -)