一道上下文无关文法题目
(2012-04-30 11:09:13)
标签:
context-freegrammercomputersciencepushdownautomatonit |
分类: 计算机科学 |
令语言G={x#y|x,y∈{0,1}*且x≠y},证明G是一个上下文无关语言。
这是一道非常简短的上下文无关语言题目,出自《计算理论导引》,不过解这道题的过程和思路比较有意思……所以记录下来。
一、起初的错误答案
证明一个语言是CFG
i)
ii)
都是构造性证明。看着这道题没过多久,我就得到了一个“答案”:
S
T
X
B
乍一看,好像是对的,S必须由T派生出来,而T的左边和右边是肯定不一样的,这样S的左边和右边也肯定不一样。然而稍加考虑就会发现反例:
S
从S推出了一个串,#左边的部分等于#右边的部分,显然这个解答是错误的。
这一题确实容易误导人,原因就在于我们设计派生文法的时候,通常遵循这样的步骤:先设计文法“基元”,然后再补充派生规则。在做这题的时候,我先写下一个#左边不等于#右边的基元规则T
不过我的文法可以生成这样的串……那就是#左右不对称的串。
二、不确定性和简化的问题
初次尝试失败,我的直觉是很难设计出描述这个语言的CFG,因为在用CFG同时顾及到#左右两边这方面完全没有思路。于是果断放弃文法,尝试构造相应的PDA。
与DFA
可见一次性地让自动机顾及#两边是不可能的,但自动机还有一个重要的特性(是什么?)没有用到:既然一台自动机不能判断整个串,就让许多台自动机共同来判断,每个自动机判断一对特定的符号。这样简化过的任务,自动机是绝对能办到的!
准确地说,没有“许多自动机”,而是让一台自动机产生“许多个分支”,每一个分支猜测一对符号。第一个分支判定x1=y1、第二个分支判定x2=y2、第三个分支判定x3=y3……xn表示x的第n个符号,依此类推。能够让自动机完成这种行为的特性,就是不确定性。
利用自动机的不确定性,问题被分解。
三、不确定性下推自动机的正确解答
OK,现在栈的作用性重新体现出来:栈不仅能让自动机看到历史,还能计数。我们必须通过栈的辅助,才能知道当前所在的分支判定的是x或y的第几个符号。
有了上面的分析,就可以构造PDA了,在构造之前,先介绍本文描述PDA的记法,本文采用与《计算理论导引》一致的记法,用来表示PDA,例如:
http://s3/bmiddle/4dff8712gbedcebc19ba2&690
表示PDA在状态a且读取到0时,跳转到状态b,并弹出栈顶的1;但有时候无论栈顶符是什么都弹出,但又不知道栈顶内容,此时就写出所有可能:
http://s6/bmiddle/4dff8712gbedce156d2e5&690
这表示只要在状态a时读到0,无论栈顶是什么,都弹出;当然有时候只简单地跳转而不改变栈:
http://s16/bmiddle/4dff8712gbedce2c3b46f&690
现在可以展示最终答案了。哦,对了,接受状态还是老规矩:http://s10/bmiddle/4dff8712gbedce82d8349&690
http://s9/bmiddle/4dff8712gbedcecceeb28&690
(PDA真难画-0-
解释一下工作流程:
1)
2)
3)
4)
i.
ii.
iii.
5)
6)
至此,这个PDA已经考虑到所有可能情况,也就解决了文章最开始的问题。其实这只是一道小小的题目,但却给自己上了一课:遇到问题的时候,要动用手头工具的所有特性!