n个自然数之和的Prolog递归

n个自然数之和的Prolog递归,prolog,Prolog,我很难理解Z的值是如何不断变化的。具体步骤已在堆栈跟踪输出中指示 这是我用来求N个自然数之和的代码- sum1(1,1). sum1(N, Sum) :- Next is N-1, sum1(Next, Z), Sum is Z + N. 这是堆栈跟踪- ?- sum1(3,_). Call: (8) sum1(3, _2668) ? creep Call: (9) _2860 is 3+ -1 ? creep Exit: (9) 2 is 3+ -1 ?

我很难理解Z的值是如何不断变化的。具体步骤已在堆栈跟踪输出中指示

这是我用来求N个自然数之和的代码-

sum1(1,1).
sum1(N, Sum) :-
   Next is N-1,
   sum1(Next, Z),
   Sum is Z + N.
这是堆栈跟踪-

?- sum1(3,_).
   Call: (8) sum1(3, _2668) ? creep
   Call: (9) _2860 is 3+ -1 ? creep
   Exit: (9) 2 is 3+ -1 ? creep
   Call: (9) sum1(2, _2862) ? creep
   Call: (10) _2866 is 2+ -1 ? creep
   Exit: (10) 1 is 2+ -1 ? creep
   Call: (10) sum1(1, _2868) ? creep
   Exit: (10) sum1(1, 1) ? creep
   Call: (10) _2872 is 1+2 ? creep
   Exit: (10) 3 is 1+2 ? creep
   Exit: (9) sum1(2, 3) ? creep **%How is Z assigned value 3 ?**
   Call: (9) _2668 is 3+3 ? creep
    Exit: (9) 6 is 3+3 ? EOF: exit
提前谢谢

它不是“改变”;
sum1
的每个证明都有自己版本的
N
Sum
Next
Z
。这就是为什么在堆栈跟踪中,每一个都会得到一个不同的生成名称(即
\u2860
),因此Prolog可以将它们区分开来


至于你的具体问题,在你所问的那一行上方两行,那一特定的
总和
2872
;因此证明
\u2872是1+2
需要
\u2872
是3。这个
Sum
与前面的调用
Sum(1,_2868)
匹配,其中
\u 2868
sum1
Z
(从上面的两行可以看到)。

因此,3被分配到
sum1(2,_2862)
,因为prolog与前面的调用匹配。3被分配到到
\u 2862
。基本上,变量的作用域是它们所在的调用。调用之间的任何变量都会被分配新的匿名变量,直到它们与传递给它们的内容统一。这意味着,如果在多个位置使用Z,则Z是未实例化的,并且说
Z=A
,将创建一个新的匿名变量
_1234
,并将其分配给A和使用Z的所有位置。