gpt4 book ai didi

prolog - 对序言中的深层列表中的原子元素求和

转载 作者:行者123 更新时间:2023-12-01 00:59:29 24 4
gpt4 key购买 nike

我是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).


为什么会出现“ ERROR: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是给定累加器P的扬程(X)的深和”。这里有两个问题: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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com