【发布时间】:2023-12-31 02:15:01
【问题描述】:
我想学习一些序言,并找到了针对给定谓词 pi(10, Result) 递归计算 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,但我不知道该怎么做。如果有人能帮忙,我会很高兴。不,这不是家庭作业或任何东西。 :)
【问题讨论】:
-
我没有检查您的代码以获得正确的公式(我假设您可以这样做)。但是,您需要在递归子句中进行测试,使其排除基本情况。像
Next > 0和/或Result > 0之类的东西,或者这种情况的任何要求。此外,由于您正在处理浮点数,因此您无法在基本情况下精确地寻找0。您将需要使用0.0周围的间隔(epsilon)来检查。否则,您可能永远无法匹配它。 -
如果要递归执行一个操作,那么最后乘以4,使用单独的谓词。您的
pi变为pi_over_4。然后创建pi(P) :- pi_over_4(..., R), P is R * 4.。 -
仅供参考,
Resultant==>Result. -
仅供参考,Prolog 确实允许您使用更复杂的表达式,例如
Part is Num / (2*Next - 1),因此您不需要Sub或Denom。 -
我明白了。基本情况的第一个参数匹配,因为它是一个整数,而第二个不匹配但实例化了一个变量,所以是的,这有效。
Num is -1**Exponent可能只是为了获得该术语的标志而过分杀伤力。您可以只检查该位并执行-> ;(if-else),或者在每次迭代中包含一个交替的 -1/1 乘数参数。