Recursion Prolog递归的简单解释

Recursion Prolog递归的简单解释,recursion,prolog,Recursion,Prolog,我有以下递归规则返回一个数字的和,但我不知道它如何返回和: sum(1,1). sum(A,Result) :- A > 0, Ax is A - 1, sum(Ax,Bx), Result is A + Bx. 现在,当您在Prolog中执行以下命令时: sum(3,X). 答案是5,但当我研究这些规则时,我看不出这些规则如何返回值并求和。Bx的值是如何计算的?sum3,X。实际上给出了X=6的结果。该谓词sumN,X计算从1到N的整数之和,给出X:

我有以下递归规则返回一个数字的和,但我不知道它如何返回和:

sum(1,1).
sum(A,Result) :-
    A > 0,
    Ax is A - 1,
    sum(Ax,Bx),
    Result is A + Bx.
现在,当您在Prolog中执行以下命令时:

sum(3,X).
答案是5,但当我研究这些规则时,我看不出这些规则如何返回值并求和。Bx的值是如何计算的?

sum3,X。实际上给出了X=6的结果。该谓词sumN,X计算从1到N的整数之和,给出X:

所以它是从1到N的整数之和

sum1,1表示1的和本身就是1。这是真的

第二个子句应该计算A>1的和,但实际上它并没有完全正确地编写。它表示A>0,忽略了第一个子句已经处理了1的情况这一事实。我会用大于1的字母来写。它将按原样工作,但效率稍低

sum(A,Result) :-
    A > 0,
    Ax is A - 1, 
    sum(Ax, Bx),       % Recursively find the sum of integers 1 to A-1
                       % Instantiate Bx with that sum
    Result is A + Bx.  % Result is A plus sum (in Bx) from 1 to A-1
该子句递归地表示从1到A的整数之和是结果。结果是A和从1到A-1的整数之和,这是Ax的统一值。Bx是整数1到axa-1的中间和。当它计算sumAx,Bx时,Ax的值比A小1。它将继续递归调用第二个子句,直到第一个参数降到1,此时第一个子句将提供求和的值,递归将从此处展开,求和1,2,3

编辑:有关递归的更多详细信息

让我们以sum3,X为例

sum3,X与sum1,1不匹配。所以跳过该子句,Prolog查看sumA,Result。Prolog通过将A实例化为3,结果实例化为X,并逐步执行构成子句的语句来实现这一点:

% SEQUENCE 1
% sum(A, Result) query issued with A = 3

3 > 1,         % true
Ax is 3 - 1,   % Ax is instantiated as the value 2
sum(2, Bx),    % recursive call to `sum`, `Ax` has the value of 2
Result is 3 + Bx.  % this statement is awaiting the result of `sum` above
此时,Prolog暂停计算结果为A+Bx,以便进行递归调用。对于递归调用,Prolog无法将sumAx、Bx与sum1、1匹配,因为Ax被实例化为2。接下来是下一个子句,sumA,Result,如果它将A实例化为2,将Result实例化为Bx,则可以匹配记住,这是对这个子句的新调用,因此A和Result的这些值与我们上面挂起的值是不同的副本。现在Prolog再次使用sumA、Result语句,这次使用新值:

% SEQUENCE 2
% sum(A, Result) query issued with A = 2

2 > 0,         % true
Ax is 2 - 1,   % Ax is instantiated to the value 1
sum(1, Bx),    % recursive call to `sum`, `Ax` has the value of 1
Result is 2 + Bx.  % this statement is awaiting the result of `sum` above
现在Prolog有了sum1,bxax用1实例化。这将匹配sum1,1,并在最后一个查询中将Bx实例化为1,以在上面的序列2中求和。这意味着Prolog将完成以下序列:

Result is 2 + 1.   % `A` is 2 and `Bx` is 1, so `Result` is 3
现在,这个结果已经完成,在序列1的先前执行中要求和的递归查询将以类似的方式完成。在本例中,它被实例化为Bx,带有3:

最后,原始查询sum3,X完成,其中X被实例化,结果为6,得到:

X = 6.

这并不是对递归工作原理的完美解释,而且有一些文本提供了图形表示的帮助。但是我希望这能提供一些关于它是如何运行的见解。

我仍然不知道Bx是如何计算的,你的意思是每次执行sumAx,Bx时,它都会将Ax的值存储到Bx中,但是sumAx,Bx被认为只对一个事实是sum1,1是真的。因为sum1,1是真的,所有其他的sumAx,Bx都是真的。这是对的还是我在这里做旁道?@user733659每次调用sumA,Result时,Ax和Bx都会实例化新的值。Ax设置为A-1,然后Bx由对sumAx、Bx的递归调用确定。sumAx的定义是,Bx是从1到Ax的整数之和。此计算以递归方式进行,直到它从sum1中的1降到底部,然后在每个递归级别实例化每个递归调用中Bx的值,添加到A,并实例化结果。@user733659我更新了我的答案,提供了有关递归的更多详细信息。请参阅是否有帮助。在C中,这将是suma{if A>0{A+suma-1;}。Prolog使求值顺序更清晰、更明确、更不神秘。
Result is 3 + 3.  % `A` is 3 and `Bx` is 3 (from the SEQUENCE 2 query)
                  % so `Result` is 6
X = 6.