如何在Prolog中返回变量结果和true / false?

时间:2010-11-24 14:22:47

标签: prolog swi-prolog prolog-toplevel

这听起来很愚蠢,但是让我说我​​的谓词最大/ 2返回列表中最大的元素...输出应该如下所示:

?- largest([1,2,3,4,5], X).
X = 5.
false.

我实现了最大,它的工作方式与上面类似,但不输出“false”。我怎么做它所以它也输出这个“假”。值?这是一个烦人的任务,我必须完成。 :(

4 个答案:

答案 0 :(得分:8)

额外的false.No只是意味着运行程序的人要求获得X的所有可能解决方案,而不仅仅是第一个可能的解决方案。

在大多数交互式Prolog解释器上,通过按分号(;)键检查是否有其他解决方案。

答案 1 :(得分:1)

听起来像是不可能的,就好像谓词失败一样,没有自由变量的绑定发生,参见

 ?- A=5.
A = 5.

 ?- A=5,false.
false.

然而

 ?- A=5;false.
A = 5 ;
false.

要实现这一目标,您应该使您的谓词“最大”不确定。但对我来说这看起来很傻。

答案 2 :(得分:1)

如果这是一个赋值的一部分,它可能意味着你的谓词在回溯后不应该产生第二个(可能是不同的)结果。如果用户想要下一个解决方案,通常按; ,就会发生回溯。解释器经常指出,当它知道仍有未完全评估的路径时,可能有另一种解决方案。

假设您有一个谓词foo/1,如下所示:

foo(1).

foo(Bar) :-
   foo(Baz),
   Bar is Baz + 1.

如果您问foo(Bar),口译员会回复Bar = 1。在反复按; 后,口译员将返回Bar = 2Bar = 3等等。

在您的示例中,查找列表中最大的列表应该是确定性的。回溯不应该产生不同的答案。

由您来解释这项任务意味着您必须允许回溯但让它失败,或者根本不让它完全回溯就可以了。

答案 3 :(得分:0)

@aschepler@Xonix@SQB之前的答案。

在这个答案中,我们使用来表达声明性整数算术。

:- use_module(library(clpfd)).

我们使用内置谓词member/2,库 maplist/2以及有限域约束(#>=)/2来定义largest/2

largest(Zs, X) :-
   member(X, Zs),            % X is a member of the list Zs
   maplist(#>=(X), Zs).      % all Z in Zs fulfill X #>= Z

示例查询:

?- largest([1,2,3,4,5], X).
X = 5.

?- largest([1,2,3,4,5,4], X).
X = 5 ;
false.

?- largest([1,2,3,4,5,5], X).
X = 5 ;
X = 5.

?- largest([1,2,3,4,5,5,4], X).
X = 5 ;
X = 5 ;
false.

?- largest([A,B,C,D], X).
A = X, X#>=D, X#>=C, X#>=B ;
B = X, X#>=A, X#>=D, X#>=C ;
C = X, X#>=A, X#>=D, X#>=B ;
D = X, X#>=A, X#>=C, X#>=B.