首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >prolog中深层列表中的原子元素之和

prolog中深层列表中的原子元素之和
EN

Stack Overflow用户
提问于 2015-12-15 08:52:45
回答 1查看 578关注 0票数 4

我是Prolog编程的初学者。我编写这个程序是为了用累加器对深层列表的原子进行求和。

代码语言:javascript
复制
    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:参数没有被充分实例化”?

没有累加器,它工作得很好:

代码语言:javascript
复制
    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.
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-15 09:13:11

问题在于你的最后一条:

代码语言:javascript
复制
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有三个意思:头的深和,尾的深和,整个列表的深和!很明显有什么不对劲的。

让我们试着把递归规则的行为用语言表达出来。结果N应等于a)电流累加器的和,b)头的深和,c)尾的深和。可以很容易地组合A和b:只需将当前累加器作为递归调用的累加器:deep_sum(X, M, N1)。在这里,我使用另一个变量N1来保存这个结果。现在我们只需要用尾部的深和来和这个。同样,我们可以简单地将N1作为递归调用的累加器传递,并且一切都将按预期进行累积。

将所有内容组合在一起,递归规则应该如下所示:

代码语言:javascript
复制
deep_sum([X|Y], M, N) :- 
    deep_sum(X, M, N1), 
    deep_sum(Y, N1, N).

为了完整起见,我的deep_sum/3实现如下所示:

代码语言:javascript
复制
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,所以您不会尝试添加字符串之类的内容。
  • 重新排列条款的顺序,一旦计算完成,就不会留下任何无用的选择点。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34284698

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档