我有一个含糊不清的无上下文文法,其中包括以下内容:
s --> [0],s,[1].
s --> [0],s.
s --> [].
当然,对于00011,我可以绘制出两个不同的解析树,这显然是有歧义的。因此,我需要编写一个无歧义的语法来描述相同的语言。我的想法是:
s --> [0],s,[1].
s --> [0],a.
s --> [].
a --> [0],a.
a --> [].
这个好吗?我怎么证明呢?
我有一个含糊不清的无上下文文法,其中包括以下内容:
s --> [0],s,[1].
s --> [0],s.
s --> [].
当然,对于00011,我可以绘制出两个不同的解析树,这显然是有歧义的。因此,我需要编写一个无歧义的语法来描述相同的语言。我的想法是:
s --> [0],s,[1].
s --> [0],a.
s --> [].
a --> [0],a.
a --> [].
这个好吗?我怎么证明呢?
那么如何证明模糊性呢?在Prolog中,对于具体的句子,这是很容易实现的:
?- length(Xs,N), bagof(t,phrase(s,Xs),[_,_|_]).
Xs = [0,0,1], N = 3
; Xs = [0,0,0,1], N = 4
; Xs = [0,0,0,0,1], N = 5
; Xs = [0,0,0,1,1], N = 5
; Xs = [0,0,0,0,0,1], N = 6
; Xs = [0,0,0,0,1,1], N = 6
; Xs = [0,0,0,0,0,0,1], N = 7
; ... .
bagof/3
必须以某种方式存储整个解集。因此,如果这个集合非常大,bagof/3
可能会溢出。以下查询避免了这个错误,但代价是得到了冗余的解:?- length(Xs,N), phrase(s,Xs), bagof(t,phrase(s,Xs),[_,_|_]).
Xs = [0,0,1], N = 3
; Xs = [0,0,1], N = 3
; Xs = [0,0,0,1], N = 4
; Xs = [0,0,0,1], N = 4
; Xs = [0,0,0,1], N = 4
; Xs = [0,0,0,1,1], N = 5
; Xs = [0,0,0,1,1], N = 5
; Xs = [0,0,0,0,1], N = 5
; Xs = [0,0,0,1,1], N = 5
; Xs = [0,0,0,0,1], N = 5
; Xs = [0,0,0,0,1], N = 5
; Xs = [0,0,0,0,1], N = 5
; Xs = [0,0,0,0,1,1], N = 6
; ... .
通过您改进的语法,查询循环。这意味着系统无法找到反例。至少不是长度低于1000的反例,这是我测试的内容。
关于在Prolog中编写DCGs的一些常规注释:
尝试将递归情况放在最后,这可能会节省一些空间。
您可能希望使用双引号字符串来表示终端。有关更多信息,请参见此答案。
s--> [0],a.
产生式,就不能再添加1。 (如果您认为0
和1
都是运算符,则0
的优先级高于1
,因为它在解析树中的位置较低)”。 您可以阅读此答案以了解优先级概念:https://dev59.com/KHPYa4cB1Zd3GeqPim-R#17170820 - Grijesh Chauhan