Prolog谓词定义为2个目标的布尔OR?

时间:2011-04-26 01:19:22

标签: prolog

我想知道如何在Prolog中创建一个谓词,如果其中一个目标是可证明的,则评估为“true”。

我有这个程序:

adjacent(place1, place2).
distance(X, Y, 1) :-
    adjacent(X, Y) ; adjacent(Y, X).

在咨询Prolog后,如果我输入:

> distance(place1, place2, 1)

我收到了这个输出:

true;
false.

我想知道是否有办法制作一个距离谓词,如果相邻(X,Y)或相邻(Y,X)中的任何一个是可证明的,则只返回单个“真”的答案。

请原谅我,如果这篇文章中的任何内容令人困惑,我对Prolog没有最好的理解,但希望这个问题是可以理解的。感谢。

3 个答案:

答案 0 :(得分:4)

您可以使用once/1谓词来确保没有回溯。

析取运算符;引入了回溯的可能性,这就是为什么Prolog会等你告诉它探索可能存在的任何进一步解决方案的原因。

once是根据“剪切”(!)来定义的,它会抛弃任何先前可能存在的回溯“选择点”。它可能值得一读。

答案 1 :(得分:1)

顺便说一句,谓词评估为真。下一个答案是因为你问prolog的替代答案(获得结果的不同方法等)和prolog ofc说错误,没有别的办法。

基本上你不必担心它,除非你特别想要一个答案(界面)。

在这种情况下,你应该使用cut / once。

答案 2 :(得分:0)

解释once/1为什么可以检查是否有任何真实目标的原因。扩展尼克的答案。

从下面可以看出,once发现一个事实,无论它在哪里,其结果都为true,并立即停止。

% undesired behaviour
?- false;true;true.
true ;
true.
% desired behaviour
?- once(false;true;true).
true.

让我们看看Prolog对once的实现

once(Goal) :-
    call(Goal),
    !.

哇,那很简单。 !是做什么的?

丢弃自输入切入出现的谓词以来创建的所有选择点。换句话说,提交出现剪切的子句,并丢弃当前子句中剪切左边由目标创建的选择点。 According to SWI-Prolog documentation

简单来说,!可以防止成功后退。当Prolog看到第一个错误时,它会回溯检查是否可以找到true;当找到第一个错误时,它就会满足并且由于!而停止。