2010-11-24 55 views
4

这听起来很傻,但可以说我的谓词最大/ 2返回的最大元素的列表...输出应该是这样的:如何在Prolog中返回变量结果和真/假?

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

我实现最大的,它的工作原理类似上面除了它doesn输出“false”。我如何做到这一点,所以它也输出这个“错误”。值?这是一个令人讨厌的任务,我必须完成。 :(

回答

8

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

在大多数的交互式Prolog的解释,你检查,看看是否有通过按分号(;)键的另一解决方案。

1

听起来像不可能的,因为如果谓词失败,没有自由变量的结合情况发生,见

?- A=5. 
A = 5. 

?- A=5,false. 
false. 

然而

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

要做到这一点,你应该让你的谓语“最大的”非确定性。但对我来说这似乎很愚蠢。

+0

S(X) :如果我将问题提交给T,这个有点奇怪的答案是** it **。它也有很好的时机! – repeat 2016-03-25 14:57:54

1

如果这是一个赋值的一部分,这可能意味着你的谓词在回溯后不应该产生第二个(可能不同的)结果。如果用户想要下一个解决方案,通常通过按;。解释者经常表示,如果知道还有路径未得到充分评估,则可能有另一种解决方案。

假设你有一个谓语foo/1如下:

foo(1). 

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

如果你问foo(Bar),解释将与Bar = 1回应。反复按;,口译员会回来的时候有Bar = 2,Bar = 3等等。

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

这是由你来解释这个任务意味着你必须允许回溯但是失败,否则根本就没有回溯。

+0

s(X):甚至短规格导致基本相反的结论也很有趣。 – repeat 2016-03-26 09:11:33

0

There is@aschepler@Xonix@SQB以前的答案。

在这个答案中,我们使用来表示声明式整数运算。

:- use_module(library(clpfd)). 

我们使用内置的谓词member/2定义largest/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.