这听起来很愚蠢,但是让我说我的谓词最大/ 2返回列表中最大的元素...输出应该如下所示:
?- largest([1,2,3,4,5], X).
X = 5.
false.
我实现了最大,它的工作方式与上面类似,但不输出“false”。我怎么做它所以它也输出这个“假”。值?这是一个烦人的任务,我必须完成。 :(
答案 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 = 2
,Bar = 3
等等。
在您的示例中,查找列表中最大的列表应该是确定性的。回溯不应该产生不同的答案。
由您来解释这项任务意味着您必须允许回溯但让它失败,或者根本不让它完全回溯就可以了。
答案 3 :(得分:0)
与@aschepler,@Xonix和@SQB之前的答案。
在这个答案中,我们使用clpfd来表达声明性整数算术。
:- use_module(library(clpfd)).
我们使用内置谓词member/2
,库meta-predicate 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.