2016-09-14 30 views
0

我試圖在Prolog中實現斐波那契序列的遞歸版本。下面是代碼:序言遞歸函數不像預期的那樣行爲

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),它說 「?_G2578爲1」,即使我打電話給fib(1,_G2579)。我的期望是_G2579將會改變,但似乎並非如此。我需要找出原因,因爲我高度懷疑這就是爲什麼fib(3,2)返回false而不是true的原因。

回答

0

的問題,如果我沒看錯,是

F == R 

是檢查是否F(新引入無值項)等於R

如果你改變它在

F = R 

所以unifing FR(一個冗餘以下F is R),您fib/2應該工作。

但我建議你一些semplification。

(1)terminale情況fib(0,F) :- F is 0.是好的,但可以將其寫爲

fib(0,0). 

(2)的另一端的情況下相同semplification:可以寫爲

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). 
+0

感謝您的建議更改!在我自己的程序中實現你在(3)中寫的代碼之後,我最初期望的行爲現在已經實現。在所有情況下,F都是第N個斐波納契數,並且僅在這些情況下才會返回true。 –