2012-03-30 4 views
2

두 개의 다른 피보나치 함수를 만들었습니다. 첫 번째 함수는 완벽하게 작동했습니다. 그런 다음 직관적 인 방법으로 단순화하려고했습니다. 나는 그것이 작동 할 것이라고 생각했는데 어떤 이유로 그것은 ERROR이라고 말한다 : 내가 테스트 할 때마다 로컬 스택에서 빠져 나온다.프롤로그에서 피보나치 함수를 테스트하려고하는 로컬 스택이 없음

작업 버전 :

fibonacci(0,0). 
fibonacci(1,1). 
fibonacci(N,F) :- N1 is N-1, N2 is N-2, fibonacci(N1,F1), fibonacci(N2,F2), F is F1+F2. 

작동하지 버전 :

fibonacci(0,0). 
fibonacci(1,1). 
fibonacci(N,F) :- fibonacci(N-1,F1), fibonacci(N-2,F2), F is F1+F2. 

누군가가 두 번째로 문제가 무엇인지 설명해 주시겠습니까? 감사.

답변

3

두 번째 문제는 재귀 적으로 값이 N-1 인 정수 대신 N-1이라는 용어로 fibonacci/2를 호출한다는 것입니다.

예를 들어, fibonacci(3, F)을 호출하면 세 번째 절에 입력하고 fibonacci(2, F1) 대신 fibonacci(3-1, F1)을 호출합니다. 그런 다음 세 번째 절에 다시 입력하고 fibonacci(3-1-1, F1) 등으로 호출합니다.

프롤로그는 특수 연산자 is을 사용하여 산술 연산을 수행합니다. 첫 번째 예가 옳습니다.

+0

자네 말이 맞아. 이제 이해가된다. 고마워요! – Rama

1

더 간단하지 않습니까? fibonnaci\3을 정의하면 첫 번째 두 개의 인수는 두 개의 'seed'요소입니다 (일반적으로 1과 1이지만 두 개의 양의 정수가 될 수 있음). 세 번째 인수는 계열의 해당 요소의 계산 된 값입니다.

당신이 fibonnaci 순서를 따라 재귀 적으로 따라서, 슬라이딩 윈도우를 유지하기 만하면됩니다 :

% 
% the public interface predicate 
% 
fibonnaci(A , _ , A) . % 1. return the first element of the series 
fibonnaci(_ , B , B) . % 2. return the second element of the series 
fibonnaci(A , B , C) :- % 3. all subsequent values are the sum of 
    fib_body(A , B , C) . % the preceding two elements in the series. 

% 
% the 'private' worker predicate 
% 
fib_body(A , B , X) :- % 1. first, compute the next element of the series 
    X is A + B .   % as the sum of the preceding two elements. 
fib_body(A , B , X) :- % 2. on backtracking, shift our window 
    C is A + B ,   % and recurse down to get the next element 
    fib_body(B , C , X) . % in the series.