英语约束免费语法序言

Kho*_*eir 4 prolog infinite-loop left-recursion dcg failure-slice

我试图在prolog中实现一个非常简单的约束自由语法时遇到了无限递归问题.

这是我的规则:(vp - >动词短语,np - >名词短语,ap - > adj短语,pp - >预备短语)

    verb(S) :- member(S, [put,  pickup, stack, unstack]).
    det(S) :- member(S, [the]).
    adj(S) :- member(S, [big, small, green, red, yellow, blue]).
    noun(S) :- member(S, [block, table]).
    prep(S) :- member(S, [on, from]).

    vp([V|R]) :- verb(V), pp(PP), np(NP), append(NP, PP, R).
    np([D, N]) :- det(D), noun(N).
    np([D|R]) :- det(D), ap(AP), noun(N), append(AP, [N], R).
    ap([A]) :- adj(A).
    ap([A|R]) :- adj(A), ap(R).
    pp([P|R]) :- prep(P), np(R).
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是ap的规则可以产生任意长的形容词串,所以在某些时候,我试图通过尝试所有这些无限的可能性来试图满足查询.

例如,以下查询将永远不会产生S = [put,the,red,block,on,the,green,block],因为它会首先将左侧"红色"上的形容词短语扩展为无限可能性,然后再尝试对.

?- vp(S)
S = [put, the, red, green, block, on, the, block] ;
Run Code Online (Sandbox Code Playgroud)

fal*_*lse 5

简短的回答是:使用Definite Clause Grammars()来表示你的语法.有关典型编码,请参阅此答案.

但现在你的程序中的实际问题.你不仅得不到想要的答案; 情况更糟:即使在一个更简单的程序片段中,你也会遇到同样的问题.这是程序中仍然没有终止的最小片段:

verb(S) :- member(S, [put,  pickup, stack, unstack]).
det(S) :- member(S, [the]).
adj(S) :- member(S, [big, small, green, red, yellow, blue]).
noun(S) :- false, member(S, [block, table]).
prep(S) :- member(S, [on, from]).

vp([V|R]) :- verb(V), pp(PP), false, np(NP), append(NP, PP, R).
np([D, N]) :- false, det(D), noun(N).
np([D|R]) :- det(D), ap(AP), false, noun(N), append(AP, [N], R).
ap([A]) :- false, adj(A).
ap([A|R]) :- adj(A), ap(R), false.
pp([P|R]) :- prep(P), np(R), false.

?- vp([put, the, red, green, block, on, the, block]).

通过插入目标,false我们得到了一个仍然没有终止的程序的小片段.实际的源是ap/1递归的,但不受实际输入的限制.有关更多示例,请参阅.

没有简单的方法来修复你的程序.最简单的方法是使用语法.

  • @DanielLyons:这就是故障切片的想法:你必须在可见部分改变**.罢工部分无关紧要. (2认同)
  • @DanieLyons:你会因意外找到答案而混淆终止.是的,*有时*你会得到答案.但你无法轻易预测何时.另外在顶部添加"vp(_)."作为事实就可以了...... (2认同)
  • @DanielLyons:**整个**失败切片是程序没有终止的原因.请回想一下,Prolog和DCG都是为了精确解决这个问题而开发的. (2认同)
  • 回去之后我现在看到我误读了OP的问题.我为火焰战争道歉. (2认同)
  • @DanielLyons:没关系!你删除了自己的评论吗?(我没有标记它们;发现它们没问题).但无论如何:我认为你可以从失败的概念中获益很多. (2认同)
  • 我做了,他们是不必要的混乱.我想更多地了解失败片(你如此热衷于它们实际上是一个非常强烈的激励).我一直有意与O'Keefe的书坐下来,挖掘它们以及你所拥有的参考资料. (2认同)
  • http://stackoverflow.com/questions/10139640/prolog-successor-notation-yields-incomplete-result-and-infinite-loop/10141181#10141181也包含一个参考.我不确定你的意思是不必要的混乱.使用故障切片,您可以将程序的大小缩小到非终止源. (2认同)
  • 我的意思是我的评论很杂乱. (2认同)