从含糊不清的语法转换为明确的语法

时间:2014-04-07 16:11:32

标签: prolog grammar dcg ambiguous-grammar

我的模糊无语境语法有产品:

s --> [0],s,[1].
s --> [0],s.
s --> [].

这当然是模棱两可的,因为对于00011我可以画另外两个解析树。我必须编写我的语法,这是一种明确的语法并描述相同的语言。我的想法是:

   s --> [0],s,[1].
   s --> [0],a.
   s --> [].
   a --> [0],a.
   a --> [].

这很好吗?我怎么能证明这一点?

1 个答案:

答案 0 :(得分:2)

那你怎么能证明模棱两可?在Prolog中,对于具体的句子来说很容易实现:

| ?- length(Xs,N), bagof(t,phrase(s,Xs),[_,_|_]).              

N = 3
Xs = [0,0,1] ? ;

N = 4
Xs = [0,0,0,1] ? ;

N = 5
Xs = [0,0,0,0,1] ? ;

N = 5
Xs = [0,0,0,1,1] ? ;

N = 6
Xs = [0,0,0,0,0,1] ? 

这证明了混凝土长度的模糊性并给出了相关的反例。

但是有一个警告可能只在一段时间后显示:bagof/3必须以某种方式存储整套解决方案。因此,如果此集非常大,bagof/3可能会溢出。以下查询以获取冗余解决方案为代价避免了此错误:

| ?- length(Xs,N), phrase(s,Xs), bagof(t,phrase(s,Xs),[_,_|_]).

N = 3
Xs = [0,0,1] ? ;

N = 3
Xs = [0,0,1] ? ;

N = 4
Xs = [0,0,0,1] ? ;

N = 4
Xs = [0,0,0,1] ? ;

N = 4
Xs = [0,0,0,1] ? ;

N = 5
Xs = [0,0,0,1,1] ...

通过改进的语法,查询循环。这意味着系统无法找到反例。至少不是长度低于1000,这是我测试的。

关于在Prolog中编写DCG的一些一般性评论:

  • 尝试将递归案例放在最后,这可能会节省一些空间。

  • 您可能希望使用双引号字符串来表示终端。有关详情,请参阅this answer