2

我有这个假设的程序来检查从 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).

问题是它返回真,然后是假。虚假从何而来?

4

1 回答 1

2

让我们看看您从 Prolog 得到的确切回复!首先你得到一个单曲trueSPACE或者;你最终得到:

?- 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).
于 2014-12-02T18:20:48.253 回答