我刚刚在考试中遇到了这个 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.
有人知道正确的解决方案吗?(注意,这不是作业,只是对考试问题感到好奇。)
我刚刚在考试中遇到了这个 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.
有人知道正确的解决方案吗?(注意,这不是作业,只是对考试问题感到好奇。)
如果我们可以限制为整数列表,我们可以使用库(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 好一点。
当您想检查一个表达式的计算结果是否与另一个表达式的值(和类型)相同时,请使用is/2
,而不是 unification =/2
。
所以而不是
H1 = H2 * 3
它应该是:
H2 is H1 * 3
您似乎也对在哪一边乘以 3 感到有些困惑。
请注意,它is/2
被声明为-Number is +Expr
,因此表达式H1 * 3
必须在右侧。
请注意,is/2
还将检查 的特定类型number
,可以是integer
或float
。因此,即使值相等,当一侧为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
版本将允许您A
在triple([1,2,3],A).
. 另一方面,=:=
版本将返回true
(triple([1],[3.0]).
值比较),但仅限于检查。