我想知道如何在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没有最好的理解,但希望这个问题是可以理解的。感谢。
答案 0 :(得分:4)
您可以使用once/1
谓词来确保没有回溯。
析取运算符;
引入了回溯的可能性,这就是为什么Prolog会等你告诉它探索可能存在的任何进一步解决方案的原因。
once
是根据“剪切”(!
)来定义的,它会抛弃任何先前可能存在的回溯“选择点”。它可能值得一读。
答案 1 :(得分:1)
基本上你不必担心它,除非你特别想要一个答案(界面)。
在这种情况下,你应该使用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;当找到第一个错误时,它就会满足并且由于!
而停止。