我对Prolog很陌生,这种思维方式让我的想法变得混乱。我目前正在使用SWI-Prolog来运行和调试我的代码。我已经实现了一个尾递归算法来解决第N个fibonnaci数。我已经尝试了一步一步的调试,我无法解释为什么我的实现正在跳过基本情况。我在哪里想错了?
fib(0, A,_, A). %Base case, when we reach N = 0, return.
%Tail recursion. Use N as counter, iterate until base value (N=0) is reached.
fib(N, A, B, F) :-
Nnew is N - 1,
Sum is (A + B),
fib(Nnew, B, Sum, F).
fib(N, F) :-
fib(N, 0, 1, F). %set start values for when fib(N,F). is called
如果我想计算第n个fib数,我的实现工作得很好(而且很快)。例如,如果我运行?- fib(5,F).
,我会回到F = 5。大。如果我想查看?- fib(5,5).
,我会回复True
,这是正确的。大。
但是,如果我输入一个false语句,例如:?- fib(5,4).
那么程序就会永远循环。会发生什么是N传递0,忽略基本情况(?),并继续递减。为什么跳过基本案例?在我看来,fib(0,A,_,A).
感到满意。我哪里错了?
答案 0 :(得分:1)
您应该将条件N>0
添加到谓词fib/3
的第二个子句中,否则如果基本案例失败,谓词fib/3
将继续尝试使用负数。让我们在咨询?- fib(0,1)
:
此案例将统一第二个子句fib(0,0,1,1)
,其中Nnew
将实例化为值-1
。从这里Nnew
将无限递减,基本情况永远不会统一。
任何其他false
案例,如?- fib(5,4)
将尝试递减N
,直到基本案例统一为止,除非在5次迭代后,否则不会发生斐波那契的总和数字等于4.因此,尝试更多尝试没有意义。