我刚刚在考试中遇到了这个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.
任何人都知道正确的解决方案吗? (注意,这不是作业,只是对考试问题感到好奇。)
答案 0 :(得分:1)
如果要检查表达式是否评估为与另一个表达式相同的值(和类型),请使用is/2
,而不是统一=/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
运算符。< / 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好一点。