Prolog递归函数的行为不符合预期

时间:2016-09-14 16:48:12

标签: recursion prolog fibonacci trace

我正在尝试在Prolog中实现Fibonacci序列的递归版本。以下是代码:

fib(0,F) :- F is 0.
fib(1,F) :- F is 1.
fib(N,F) :- N > 1,
AA is (N - 1),
BB is (N - 2),
fib(AA,CC),
fib(BB,DD),
RR is (CC + DD),
F == RR,
F is RR.

问题在于它的行为并不像我在逻辑上所期望的那样。当我使用trace来调用fib(3,2)时,我得到以下几行:

   Call: (7) fib(3, 2) ? creep
   Call: (8) 3>1 ? creep
   Exit: (8) 3>1 ? creep
   Call: (8) _G2569 is 3+ -1 ? creep
   Exit: (8) 2 is 3+ -1 ? creep
   Call: (8) _G2572 is 3+ -2 ? creep
   Exit: (8) 1 is 3+ -2 ? creep
   Call: (8) fib(2, _G2573) ? creep
   Call: (9) 2>1 ? creep
   Exit: (9) 2>1 ? creep
   Call: (9) _G2575 is 2+ -1 ? creep
   Exit: (9) 1 is 2+ -1 ? creep
   Call: (9) _G2578 is 2+ -2 ? creep
   Exit: (9) 0 is 2+ -2 ? creep
   Call: (9) fib(1, _G2579) ? creep
   Call: (10) _G2578 is 1 ? creep
   Exit: (10) 1 is 1 ? creep

引起我注意的是最后一个电话,呼叫:(10),即“我G4478是1?”,即使我正在调用fib(1,_G2579)。我的期望是_G2579会被改变,但事实并非如此。我需要找出原因,因为我非常怀疑这就是为什么fib(3,2)返回false而不是true。

1 个答案:

答案 0 :(得分:0)

问题,如果我没有错,就在

F == R

检查F(新引入的没有值的术语)是否等于R

如果你在

中更改它
F = R

如此统一FR(冗余跟随F is R),您的fib/2应该有效。

但我建议你做一些简化。

(1)终止案例fib(0,F) :- F is 0.很好但你可以把它写成

fib(0,0).

(2)对于另一个终端案例的同样简化:你可以把它写成

fib(1,1).

(3)在一般条款中,您不需要具有相同(统一)值的两个不同变量FRR;您只能以下列方式使用F

fib(N,F) :-
  N > 1,
  AA is (N - 1),
  BB is (N - 2),
  fib(AA,CC),
  fib(BB,DD),
  F is (CC + DD).