我正在学习 swi Prolog,我想创建为每个元素添加 +2 的谓词。
所以我写了这样的东西:
addUp([],_).
addUp([H|T],R):-addUp(T,R),is_list(R)->append([H+2],R,R);R=[H+2|[]].
addUp([1,2],X).
但它总是返回 false。为什么?
首先是一个建议:学习使用maplist /3:你将使用它来编写
addUp(Xs, Ys) :- maplist(addUp2, Xs, Ys).
addUp2(X, Y) :- Y is X + 2.
或者更好,一个更可重用的片段......
addUp(Xs, Ys) :- maplist(addUp(2), Xs, Ys).
addUp(N, X, Y) :- Y is X + N.
无论如何,Prolog 中的算术必须“明确地”评估,并且您的代码必须简化很多才能工作
addUp([], []).
addUp([H|T], [H1|T1]) :- H1 is H+2, addUp(T, T1).
但它总是返回 false。为什么?
您的定义并不总是失败:
?- addUp([1],X)。 X = [1+2]。
所以有时它会成功。看来这种情况或多或少是您想要的。它还能在哪里成功?在其他编程语言中,您将不得不猜测,或者,天堂禁止,阅读程序。在 Prolog 中,不需要这样做。只需找到一个好的查询。一个好的候选者是最一般的查询:
?- addUp(Xs,Ys)。 Xs = [] ...
所以你的定义成功了Xs
equal to[]
和Ys
equal to ... 好吧,equal to anything。因此,这个答案太笼统了。
另一个目标引起了我的注意:is_list(R)->append([H+2],R,R)
. 让我们想象一下,这将是真的。不为R = []
,也不为R = [_]
。事实上,没有长度,这将是真实的。
现在,我们可以开始修复您的程序了。请参阅 chac/CapelliC 的建议。