fal*_*lse 8 prolog dcg iso-prolog
在语法规则(dcg)中,有几个预定义的构造:(',')//2意思是连接,('|')//2意思是交替等.一个由几个但不是所有Prolog系统支持的构造是(\+)//1.
就个人而言,我只是为了使用它而使用它.我从未在其他人编写的代码中看到它.
那么,有合法用途(\+)//1吗?
编辑:,另外,是否有合法的使用(\+)//1在查询中phrase(nt, L)使用L一个非实例变量.
小智 2
\+ 可用于创建不太模糊的语法。使用 \+ 的优点超过 ! 例如, 是 \+ 的某种声明性,因此可以对生成的 DCG 规则进行重新排序。
让我们举个例子,考虑以下语法:
s([X|Y]) --> t(X), s(Y). % 1
s([]) --> []. % 2
t(2) --> [a,a]. % 3
t(1) --> [a]. % 4
Run Code Online (Sandbox Code Playgroud)
上面的语法非常不明确,例如我对以下输入进行了多次解析:
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
A = [2,1,2] ;
A = [2,1,1,1] ;
etc..
Run Code Online (Sandbox Code Playgroud)
现在假设我想更喜欢 t 的长解析而不是 t 的短解析。我可以通过剪切来做到这一点,如下所示:
t(2) --> [a,a], !. % 5
t(1) --> [a]. % 6
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
No
Run Code Online (Sandbox Code Playgroud)
不幸的是我无法重新订购。因为执行以下操作不会给出所需的结果。尽管 s(A) 现在以不同的顺序产生结果,但我们又回到了原点,因为语法再次不明确:
t(1) --> [a]. % 7
t(2) --> [a,a], !. % 8
?- phrase(s(A),[a,a,a,a,a]).
A = [1,1,1,1,1] ;
A = [1,1,1,2] ;
A = [1,1,2,1] ;
etc...
Run Code Online (Sandbox Code Playgroud)
现在让我们尝试使用 \+ 进行同样的操作。我们可以用以下否定来替换剪切:
t(2) --> [a,a]. % 9
t(1) --> [a], \+ [a]. % 10
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
No
Run Code Online (Sandbox Code Playgroud)
现在让我们尝试一下是否可以重新排序。我们重新排序 t//1 的语法规则:
t(1) --> [a], \+ [a]. % 11
t(2) --> [a,a]. % 12
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
No
Run Code Online (Sandbox Code Playgroud)
声明性非常有用。这意味着我们可以在从右到左的图表解析器中使用 \+ 以任意顺序选择语法规则。声明性确保图表解析器的自下而上的前向链接产生相同的结果,而与 DCG 规则的输入顺序无关。
然后就可以将 DCG 技术应用到大型自然语言 (NL) 项目中,并且可以很好地扩展。NL 语法可以凭经验调整为决定论。语法越确定,其解析就越高效。原本难以处理的复杂自然语言语法变得可行。
再见