我是 Prolog 编程的初学者。我编写了这个程序来用累加器对深度列表的原子进行求和。
deep_sum(Xs, N) :- deep_sum(Xs, 0, N).
deep_sum([], N, N).
deep_sum([X|Y], M, N) :- atomic(X), Q is M + X, deep_sum(Y, Q, N).
deep_sum([X|Y], M, N) :- M is P + Q, deep_sum(X, P, N), deep_sum(Y, Q, N).
为什么我会收到“错误:is/2:参数没有充分实例化”?
它在没有累加器的情况下工作正常:
deep_sum([], 0).
deep_sum([X|Y], S) :- atomic(X), !, deep_sum(Y, Q), S is Q + X.
deep_sum([X|Y], S) :- deep_sum(X, P), deep_sum(Y, Q), S is P + Q.
最佳答案
问题出在你的最后一个条款上:
deep_sum([X|Y], M, N) :- M is P+Q, deep_sum(X,P,N), deep_sum(Y,Q,N).
错误的直接问题是当
M is P+Q
时P和Q都没有值。被执行。只是将它移到后面并不能解决它,该条款有更多问题。让我们来看看递归调用。
deep_sum(X,P,N)
在文字中的意思是“N 是头部 (X) 的深度总和,给定累加器 P”。这里有两个问题:P 没有值,N 应该是整个列表的总和,而不仅仅是头部。在第二次递归调用中也存在同样的问题。累加器 Q 还没有值,而 N 再次用作结果。所以现在 N 有 3 种含义:头部的深度和,尾部的深度和,以及整个列表的深度和!显然有些地方不对劲。
让我们试着用语言表达递归规则应该如何表现。结果 N 应等于 a) 当前累加器、b) 头部的深度和和 c) 尾部的深度和的总和。 a 和 b 可以轻松组合:只需将当前累加器作为递归调用的累加器传入:
deep_sum(X, M, N1)
.这里我使用另一个变量 N1 来保存这个结果。现在我们只需要将其与尾部的深和相加即可。同样,我们可以简单地将 N1 作为递归调用的累加器传递,一切都将按预期进行累加。将所有内容放在一起,您的递归规则应如下所示:
deep_sum([X|Y], M, N) :-
deep_sum(X, M, N1),
deep_sum(Y, N1, N).
为了完整起见,我的 deep_sum/3 实现看起来像这样:
deep_sum(X, M, N) :-
number(X),
N is M + X.
deep_sum([], N, N).
deep_sum([X|Y], M, N) :-
deep_sum(X, M, N1),
deep_sum(Y, N1, N).
主要区别是:
number/1
而不是 atomic/1
,因此您不要尝试添加字符串等。 关于prolog - 在序言中对深层列表中的原子元素求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34284698/