用Leibniz公式递归计算prolog中的pi

时间:2017-11-29 21:38:52

标签: recursion prolog

我想学习一些序言,并发现练习以递归方式计算给定谓词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,我不知道该怎么做。如果有人能帮帮忙,我会很高兴的。不,这不是家庭作业或任何东西。 :)

1 个答案:

答案 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并不是强大的。