2016-09-14 2 views
0

프롤로그에서 피보나치 시퀀스의 재귀 버전을 구현하려고합니다. 다음은 코드입니다.프롤로그 재귀 함수가 예상대로 작동하지 않습니다.

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. 

논리적으로 예상대로 작동하지 않는 것이 문제입니다. (10) "_G2578 1인가?"라고 :

무엇 내 관심을 잡는다 것은 마지막 호출입니다
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 

, 전화 : 나는 (3,2)을 FIB를 호출하는 trace를 사용할 때, 나는 다음과 같은 라인을 얻을 fib (1, _G2579)를 호출하더라도. 내 기대는 그것이 변경 될 _G2579이지만, 그럴 것 같지 않습니다. 왜 이것이 fib (3,2)가 true 대신 false를 반환하는지 의심이 많이 드는 이유를 알아야합니다. 내가 잘못 아니에요 경우

답변

0

문제는, F (값없이 새롭게 도입 된 용어) R 동일한 경우 확인

F == R 

입니다.

당신이

F = R 

그렇게 (중복 다음 F is R에) RF을 unifing에서 변경할 경우 fib/2 작동합니다.

하지만 나는 당신에게 몇 가지 준결승을 제안합니다.

(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를 반환합니다. –

관련 문제