Prolog编译器返回错误
我有一个假设的程序来检查从a点到B点的路径是否存在Prolog编译器返回错误,prolog,logic,prolog-toplevel,transitive-closure,Prolog,Logic,Prolog Toplevel,Transitive Closure,我有一个假设的程序来检查从a点到B点的路径是否存在 /*city rules*/ edge(phx, tuc). edge(tuc, ccg). edge(ccg, sf). connected(C1, C2) :- edge(C1, C2). connected(C1, C2) :- edge(C1, X), connected(X, C2). 问题是它返回true,然后返回false。错误从何而来?让我们看看您从Prolog得到的确切答复!首先,您得到一个true,
/*city rules*/
edge(phx, tuc).
edge(tuc, ccg).
edge(ccg, sf).
connected(C1, C2) :-
edge(C1, C2).
connected(C1, C2) :-
edge(C1, X),
connected(X, C2).
问题是它返回true,然后返回false。错误从何而来?让我们看看您从Prolog得到的确切答复!首先,您得到一个
true
,然后按空格或;你最终得到:
?- connected(phx,sf).
true ;
false.
所以你得到了真的;错误。
作为完整答案。代码>表示“或”。所以Prolog本质上说:您的查询已连接(phx,sf)。
与true相同;错误。
因此,您需要查看整个答案以了解其含义。当然这有点奇怪,如果为真。
就足够了
但首先让我们举另一个例子:
?- connected(phx,X).
X = tuc ;
X = ccg ;
X = sf ;
false.
这里Prolog的完整答案是:connected(phx,X)。
描述了与X=tuc相同的解决方案集;X=ccg;X=fg;false。
如果省略false
,则其长度也会更短
那么为什么Prolog会写出这个false
?Prolog以增量方式计算答案。它首先向您显示X=tuc
,然后等待您将要执行的操作。从某种意义上说,不立即向您展示所有内容有点懒惰。有时,Prolog确实知道不会有进一步的答案,在这种情况下,它直接写一个点:
?- member(X,[1,2]).
X = 1 ;
X = 2.
这里的序言说:迪西!我已经说过了
但有时,情况并非如此确定:
?- member(1,[1,2]).
true ;
false.
在证明1是成员后,它将停止,否则它将不得不进一步探索列表
所以这个;false。
意思是:在最后一个答案/解决方案之后,Prolog还不能确定所有的问题都已经研究过了。这可能是一种低效,也可能是一种可以改进的迹象。但是,永远不要将此作为在程序中插入剪切的借口。另一个答案的切入点是完全错误的。这是很多很多错误的根源。在开始使用cuts之前,你真的应该首先学习Prolog的另一个纯粹的部分
顺便说一句:connected/2
有一个更好的定义,它通过使用避免了无限循环(点击它获得定义)
connected(C0,C) :-
edge(C0,C1)
closure0(edge,C1,C).