Prolog代码对列表中的元素求和时出现问题

Prolog代码对列表中的元素求和时出现问题,prolog,Prolog,祝你身体健康。我对prolog相当陌生,我对我正在编写的代码有一个问题。代码的目的很简单。它将列表中的每个元素添加到最后一个元素。我可以在Java中执行以下操作: 静态空添加(双[]数组){ 双x=0.0; 对于(int i=0;i

祝你身体健康。我对prolog相当陌生,我对我正在编写的代码有一个问题。代码的目的很简单。它将列表中的每个元素添加到最后一个元素。我可以在Java中执行以下操作:

静态空添加(双[]数组){
双x=0.0;
对于(int i=0;i
然而,我一直在琢磨如何在prolog中实现它。 我有以下代码

add_list([], X):- write(X).
add_list([Head|Tail],X) :- 
    Y is Head,
    X is 0 + Y, %initialize X and add Y every time it runs.
    add_list(Tail, X).
我得到的错误是,当代码第二次运行时,变量X已经有界了,这是有意义的,但我真的不知道如何解决这个问题

任何帮助都将不胜感激


谢谢。

序言程序是关系。使用以
add\开头的名称听起来更像是命令式程序。如果您想学习Prolog,请尽量避免使用此类名称。在这种情况下,您希望在列表与其元素之和之间建立关系
list\u sum/2
听起来是个更好的名字

:- use_module(library(clpfd)).
:- op(150, fx, #).

list_sum([], 0).
list_sum([E|Es], S) :-
   #S #= #E + #Si,
   list_sum(Es, Si).
现在,根据这个定义,试试看

?- list_sum([1,2,3], N).
N = 6.

?- list_sum([1,2,3], 7).
false.

?- list_sum([1,2,E], 7).
E = 4.

?- list_sum([1,E,E], 7).
E = 3.

我想出了一个办法来得到我需要的结果。按照@false的建议,我将我的规则从添加列表重命名为列表。我提出了下面的代码,它可以工作,但需要在调用时提供一个数字(理想情况下为0。任何其他数字都会将结果增加该数字)

list_sum([], X):- write(X). 
list_sum([Head|Tail], X)  :- 
    K is X,
    W is K + Head, 
    list_sum(Tail, W).

现在代码的问题是,如果输入1而不是上面提到的0作为初始变量,则会将结果增加1。老实说,我对结果并不完全满意。

这使用了和
#=
操作符,而不是“右侧的函数求值,左侧的函数求值如
LHS是RHS
,但是为什么要声明一个
中缀运算符作为
S
\S
的前缀呢?否则
N=1+0,list\u sum([1],N.)
成功,而
list\u sum([1],N),N=1+0.
失败。因此,我明白了。但是对于第一个目标,我们可能有理由看到它成功了,而
list\u sum([1],N),N=1+0。
永远不会成功,因为程序员把一个整数和一个术语搞砸了。事实上,编译器可能会成功地告诉程序员,
list\u sum([1],N),N=1+0。
无论如何都会产生false。因此,排除N=1+0,list_sum([1],N])的成功是合理的吗?
编译器几乎不可能捕获所有此类情况。另外,如果
N=0+0
[]
不起作用,那该怎么办?当然,要捕获所有内容是不可能的。但并不需要完美,例如,Idris编译器会在怀疑循环不会终止时告诉您,这可能很有用。无论如何,
N=0+0
确实不起作用,除非您先减少
0+0
。我猜这是针对另一种语言(统一与平等,不是吗?)的
X
出现在第二个子句中的三个地方-您使用它与使用赋值改变其状态的语言中的变量相同。请注意,在此设置中,这意味着Prolog将确保或确定相同的值出现在这三个位置
X
最好作为对共享内存位置的引用。显然,
add_list([Head | Tail],X)
在其第二个参数位置上不能具有与
add_list(Tail,X)
相同的
X
。我理解。谢谢。提示:不要把计算和输出混为一谈。如果要打印成功的目标绑定,可以随时调用例如
g(X),write(X)