我有这个假设的程序来检查从 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).
问题是它返回真,然后是假。虚假从何而来?
我有这个假设的程序来检查从 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).
问题是它返回真,然后是假。虚假从何而来?
让我们看看您从 Prolog 得到的确切回复!首先你得到一个单曲true
,SPACE或者;你最终得到:
?- connected(phx,sf).
true ;
false.
所以你得到true ; false.
了完整的答案。意思是“;
或”。所以Prolog本质上说:你的查询connected(phx,sf).
是一样的true ; false.
所以你需要查看整个答案来理解它的含义。当然这有点奇怪,什么时候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.
Prolog 在这里说:dixi!我已经说过。
但有时,不确定:
?- member(1,[1,2]).
true ;
false.
在证明 1 是成员后,它会停止,否则它必须进一步探索列表。
所以这; false.
意味着:在最后一个答案/解决方案之后,Prolog 还不确定一切都已经探索过了。这可能是一种低效率,它可能表明某些事情可以改进。但是,永远不要以此为借口在您的程序中插入剪辑。另一个答案的删减完全是恶意的。它是许多许多错误的根源。在开始使用削减之前,你真的应该首先学习 Prolog 的另一个纯部分。
顺便说一句:这是一个更好的定义,connected/2
它通过使用来避免无限循环closure/3
(单击它以获取定义)。
connected(C0,C) :-
edge(C0,C1)
closure0(edge,C1,C).