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

为什么我会收到“错误: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/

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