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