0

我刚刚在考试中遇到了这个 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.

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

4

2 回答 2

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 好一点。

于 2013-04-23T07:03:52.540 回答
0

当您想检查一个表达式的计算结果是否与另一个表达式的值(和类型)相同时,请使用is/2,而不是 unification =/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运算符。

H2 =:= H1 * 3

或者

H1 * 3 =:= H2

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

简而言之,该is版本将允许您Atriple([1,2,3],A).. 另一方面,=:=版本将返回truetriple([1],[3.0]).值比较),但仅限于检查。

于 2013-04-23T04:26:23.853 回答