如何检查一个列表是否具有prolog中另一个列表的值的三倍?

时间:2013-04-23 03:48:29

标签: prolog

我刚刚在考试中遇到了这个Prolog问题,我很确定我没有把它弄好。

我必须定义三重(List1,List2),例如三重([1,2,3],[3,6,9])和三重([2,4],[6,12])是真的

我的尝试是这样的,但我怀疑它不起作用......

triple([],[]).
triple([H1|T1],[H2|T2]) :-
    triple(T1,T2),
    H1 = H2 * 3.

任何人都知道正确的解决方案吗? (注意,这不是作业,只是对考试问题感到好奇。)

2 个答案:

答案 0 :(得分:1)

如果要检查表达式是否评估为与另一个表达式相同的值(和类型),请使用is/2,而不是统一=/2

所以而不是

H1 = H2 * 3

应该是:

H2 is H1 * 3

你似乎在哪一方面稍微混淆乘以3。

请注意,is/2被声明为-Number is +Expr,因此表达式H1 * 3必须位于右侧。

请注意,is/2还会检查number的具体类型,可以是integerfloat。因此,即使值相等,当一方为float而另一方为integer时,统一将失败。

quad([],[]).
quad([H1|T1],[H2|T2]) :-
    triple(T1,T2),
    H2 is H1 * 4.

quad([0.25], [1])将返回false

如果您想比较number,无论是integer还是float,请使用=:=/2运算符。< / p>

H2 =:= H1 * 3

H1 * 3 =:= H2

由于=:=/2被声明为+Expr1 =:= +Expr2,它在运算符的两边提供了更多的自由度(双方可以是表达式,而不是is/2中的一侧)。但是,它还要求在评估双方时对其进行实例化。

简而言之,is版本可让您评估A中的triple([1,2,3],A).。另一方面,=:=版本将返回true triple([1],[3.0]).(值比较),但限制您仅检查。

答案 1 :(得分:0)

如果我们可以限制为整数列表,我们可以使用库(clpfd):

?- [library(clpfd)].
?- [user].
|: triple(X, Y) :- maplist(tri, X, Y).
|: tri(X, Y) :- X * 3 #= Y.
|: % user://1 compiled 0,13 sec, 5 clauses
true.

?- triple([2,X,Y],[Z,9,12]).
X = 3,
Y = 4,
Z = 6.

要处理浮点表达式,有库(clpr):

?- [library(clpr)].
?- [user].
|: triplef(X, Y) :- maplist(mult(3), X, Y).
|: mult(F,X,Y) :- {X * F = Y}.
|: % user://3 compiled 0,27 sec, 79 clauses
true.

?- triplef([2,X,Y],[Z,9,12]).
X = 3.0,
Y = 4.0,
Z = 6.0 .

我通过可重复使用的 mult / 3编码了triplef / 3比triple / 3好一点。