我想学习一些序言,并发现练习以递归方式计算给定谓词pi(10,结果)。我不希望它是尾递归的,因为我发现尾递归更容易。我现在已经尝试了几个小时,但似乎我无法找到解决方案,这就是我已经走了多远:
(我使用Leibniz&#pi; pi公式作为参考)
pi(0, 0).
pi(Next, Result) :-
Num is -1**(Next + 1),
Part is Num / (2 * Next - 1),
N1 is Next -1,
pi(N1, R),
Result is Part + R.
现在,我意识到最后的添加是错误的。此外,我需要将最终结果乘以4,我不知道该怎么做。如果有人能帮帮忙,我会很高兴的。不,这不是家庭作业或任何东西。 :)
答案 0 :(得分:0)
这是一种稍微不同的扭曲,它基于达到给定的精度而终止。它也是尾递归的。因为Leibniz收敛非常缓慢,所以当使用简单递归完成时,公式是堆栈生成。它不是一种非常适合任何语言的递归解决方案的算法。但是,一个聪明的Prolog解释器可以利用尾递归并避免这种情况。仅作为示例,它仅允许在特定范围内的精度。
pi(Precision, Pi) :-
Precision > 0.0000001,
Precision < 0.1,
pi_over_4(1, 1, Precision/4, 1, Pi_over_4), % Compensate for *4 later
Pi is Pi_over_4 * 4.
pi_over_4(AbsDenominator, Numerator, Precision, Sum, Result) :-
NewAbsDenominator is AbsDenominator + 2,
NewNumerator is -Numerator,
NewSum is Sum + NewNumerator/NewAbsDenominator,
( abs(NewSum - Sum) < Precision
-> Result = NewSum
; pi_over_4(NewAbsDenominator, NewNumerator, Precision, NewSum, Result)
).
2 ?- pi(0.0001, P).
P = 3.1416426510898874.
3 ?- pi(0.00001, P).
P = 3.141597653564762.
4 ?- pi(0.000005, P).
P = 3.141595153583494.
这绝对是Prolog的必要用途,而Prolog并不是强大的。