4

听起来很傻,但是可以说我的谓词最大/ 2 返回列表中的最大元素...输出应如下所示:

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

我实现了最大的,它像上面一样工作,只是它不输出“false”。我该怎么做,所以它也输出这个“假”。价值?这是我必须完成的一项烦人的任务。:(

4

4 回答 4

8

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

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

于 2010-11-24T20:13:49.727 回答
1

听起来不可能,好像谓词失败,没有发生自由变量的绑定,请参阅

 ?- A=5.
A = 5.

 ?- A=5,false.
false.

然而

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

为此,您应该使您的谓词“最大”不确定。但对我来说,这似乎很愚蠢。

于 2010-11-24T20:31:34.167 回答
1

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

假设您有foo/1如下谓词:

foo(1).

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

如果你问foo(Bar),口译员会回答Bar = 1。反复按 后;,翻译返回Bar = 2Bar = 3以此类推。

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

您可以将分配解释为您必须允许回溯但让它失败,或者根本不让它回溯也可以。

于 2016-03-25T13:34:24.137 回答
0

@aschepler 、@Xonix@SQB之前的回答有些内容

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

:- use_module(library(clpfd)).

我们largest/2使用内置谓词member/2、库 maplist/2和有限域约束进行定义(#>=)/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.
于 2016-03-25T16:10:40.957 回答