我有以下递归规则,它返回一个数字的总和,但我不知道它是如何返回总和的:
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的值?
答案 0 :(得分:3)
sum(3,X).
实际上会得到X = 6
的结果。此谓词(sum(N, X)
)计算1
到N
的{{1}}整数之和:
X
所以它是从1到N的整数之和。
X = 1 + 2 + 3 + ... + N.
表示sum(1,1)
本身的总和只是1
。这是真的。 :)
第二个子句应计算1
>的总和。 1,但它实际上并没有完全正确地写。它说A
忽略了第一个子句已经处理A > 0
的情况的事实。我会用1
写的。它会按原样运作,但效率会低一些。
A > 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
。 Result
是Result
与A
到1
之间的整数之和(值A-1
统一到)的总和。 Ax
是整数Bx
到1
(Ax
)的中间和。在计算A-1
时,sum(Ax, Bx)
的值比Ax
小1。它将继续递归调用第二个子句,直到第一个参数变为A
,此时第一个子句将提供总和的值,递归将从那里解开,总结1,2,3, ...
编辑:有关递归的更多详细信息
让我们以1
为例。
sum(3,X)
与sum(3,X)
不匹配,因此跳过该子句,Prolog查看sum(1,1).
。 Prolog通过将sum(A, Result)
A
和3
实例化为Result
来对此进行匹配,并逐步完成构成该子句的语句:
X
此时,Prolog暂停计算% 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无法将Result is A + Bx
与sum(Ax, Bx)
匹配,因为sum(1,1)
被实例化为Ax
。所以它继续下一个子句2
,如果它将sum(A, Result)
实例化为A
而2
实例化为Result
,则可以匹配(请记住,这是一个新的调用此子句,因此Bx
和A
的这些值与我们上面“暂停”的值不同。现在Prolog再次通过Result
语句,这次使用新值:
sum(A, Result)
现在Prolog已% 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
(sum(1, Bx)
已实例化Ax
)。这将与1
匹配,并在上一个查询中将sum(1,1)
与Bx
实例化为1
,这将意味着Prolog将完成序列:
sum
现在这个结果已经完成,在SEQUENCE 1中先前执行中对Result is 2 + 1. % `A` is 2 and `Bx` is 1, so `Result` is 3
的递归查询将以类似的方式完成。在这种情况下,会使用sum
实例化Bx
:
3
最后,原始查询Result is 3 + 3. % `A` is 3 and `Bx` is 3 (from the SEQUENCE 2 query)
% so `Result` is 6
完成,其中sum(3, X)
被实例化,结果为X
,您得到:
6
这不是递归如何工作的完美解释,并且有一些文本周围有图形表示有帮助。但我希望这可以提供一些有关它如何运作的见解。