Recursion Prolog查询失败

Recursion Prolog查询失败,recursion,prolog,sum,Recursion,Prolog,Sum,这应该是计算两个列表的总和。列表可以有不同的大小 sum([],[],[]). sum(A,[],A). sum([],B,B). sum([A|Int1],[B|Int2],[C|Int3]) :- ( C =:= A + B ; ((C =:= A), B = []) ; ((C =:= B), A = []) ), sum(Int1,Int2,Int3). 它似乎工作正常,除非试图找到两个列表的总和。然后给出以下错误: ERROR: =:=/2

这应该是计算两个列表的总和。列表可以有不同的大小

sum([],[],[]).
sum(A,[],A).
sum([],B,B).
sum([A|Int1],[B|Int2],[C|Int3]) :-
  (
    C =:= A + B
  ;
    ((C =:= A), B = [])
  ;
    ((C =:= B), A = [])
  ),
  sum(Int1,Int2,Int3).
它似乎工作正常,除非试图找到两个列表的总和。然后给出以下错误:

ERROR: =:=/2: Arguments are not sufficiently instantiated

我不明白为什么。有一个递归步骤和一个基本步骤,到底什么还没有实例化,我如何修复它?

[1]虽然最后一个子句中的析取在某种程度上在概念上是正确的,但Prolog会按顺序考虑这些析取。因此它首先考虑
C=:=A+B
。但是
A
B
都可以是空列表!这就是您报告的错误的原因,因为在数值操作中不允许出现空列表

[2] 您需要使用
C是A+b
(赋值)i.o.
C=:=A+b
(数字等效)

[3] 如果你说
[A | Int1]
然后说
A=[]
,那么这意味着
[A | Int1]
不仅是一个整数列表(正如你所说的那样),而且是一个列表列表!您可能想检查第一个列表或第二个列表是否为空,而不是其中是否包含空列表

与您的原始计划保持一致,我建议按以下方式重新排序和更改:

sumOf([], [], []):- !.
sumOf([], [B|Bs], [C|Cs]):- !,
  C is B,
  sumOf([], Bs, Cs).
sumOf([A|As], [], [C|Cs]):- !,
  C is A,
  sumOf(As, [], Cs).
sumOf([A|As], [B|Bs], [C|Cs]):-
  C is A + B,
  sumOf(As, Bs, Cs).
例如:

?- sumOf([1,2,3], [1,-90], X).
X = [2, -88, 3]

请注意我在上面使用的切口(符号
)。这可以确保同一个答案不会被多次给出,或者更严格地说,不会保留任何选择点(这被称为决定论)。

你应该阅读一本教程或一本书。无论如何,这就是如何将两件事添加到彼此中:

Result is A + B
以下是添加一个列表中所有元素的方法:

sum([], 0). % because the sum of nothing is zero
sum([X|Xs], Sum) :-
    sum(Xs, Sum0),
    Sum is X + Sum0.
这就是如何添加列表的总和:

sums([], 0).
sums([L|Ls], Sums) :-
    sums(Ls, Sums0),
    sum(L, S),
    Sums is Sums0 + S.

我喜欢你的解决方案,但任务是只使用一个谓词和。@user3614293实际上,对于不涉及数值操作的数值赋值,你可以使用统一。第一条确实是不需要的,因为第二条(和第三条)涵盖了第一条。我的代码示例本来打算与您的原始程序非常接近,但您在注释中给出的版本确实包含较少的冗余。不过,我想在第一个条款中增加一个删节,作为决定论。