여기서 문제는 두 개의 절인 fib(X, Y, 0, V) :-
과 fib(X, Y, R, V) :-
을 쓰는 것입니다. Prolog는 역 추적을 사용합니다. : 하나의 절이 시도 된 경우 성공 또는 실패 여부와 상관없이 나중에 다음 절을 다시 시도합니다 (이를 변경할 수있는 once/1
과 같은 일부 메타 조건어가 있음).
따라서 R
이 0
이하인 경우에도 Prolog는 두 번째 절을 시도합니다.
이 문제를 해결하는 빠른 방법이 두 번째 조항에 대한 경비를 사용하는 것입니다 :
은 또한 코드가 당신이 반대의 방법으로 관계를 사용할 수없는 점에서 매우 우아하지
fib(_, Y, 0, V) :-
Y == V.
fib(X, Y, R, V) :-
R > 0,
Z is X + Y,
C is R - 1,
fib(Y, Z, C, V).
도 X 번째 요소를 쿼리 할 수 있습니다.
당신이
Y == V
를 사용하는 예를 들어
하지만,이 블록의 통일 : 우리가 X 번째 피보나치 수를 알고 싶다면, 우리는 다시 그 결과를 전파 할 수있는 방법을 원한다.
fib(_, V, 0, V).
fib(X, Y, R, V) :-
R > 0,
Z is X + Y,
C is R - 1,
fib(Y, Z, C, V).
을하지만 지금 우리는 여전히 양방향 관계가없는 : 그래서 우리는 대신에 통일을 사용할 수 있습니다 우리가 주어진 값 V의 X를 얻을 수 없습니다. 이것은 더 복잡합니다. 이제
:- use_module(library(clpfd)).
fib(_, V, 0, V).
fib(X, Y, R, V) :-
R #> 0,
V #>= Y,
Z is X + Y,
C#= R - 1,
fib(Y, Z, C, V).
우리는 할 수 있습니다 : 가장 쉬운 방법은 아마 이것에 대한 clpfd
을 사용
열거 모든 인덱스와 해당 피보나치 번호 :
?- fib(A,B).
A = 0,
B = 1 ;
A = B, B = 2 ;
A = B, B = 3 ;
A = 4,
B = 5 ;
A = 5,
B = 8 ;
A = 6,
B = 13 ;
A = 7,
B = 21
...
는 내가 받기 피보나치 번호 :
,363,210 ?- fib(2,B).
B = 2 ;
false.
?- fib(10,B).
B = 89 ;
false.
대응 피보나치 수는 일정 값 인 대한 I 얻었다 :
?- fib(A,1).
A = 0 ;
A = 1 ;
false.
?- fib(A,2).
A = 2 ;
false.
?- fib(A,3).
A = 3 ;
false.
?- fib(A,4).
false.
?- fib(A,5).
A = 4 ;
false.
체크를 만약 피보나치 수 번째 주어진 값이다
?- fib(4,5).
true ;
false.
?- fib(4,6).
false.
?- fib(4,10).
false.
?- fib(5,8).
true ;
false.
은
'추적'을 시도하여 현재 상황을 확인 했습니까? 'R <0 '이면 어떻게 될까? 두 번째'fib/4' 절이 여전히 실행될 것입니다. – lurker
추적을 어떻게 실행합니까? –
'trace를 입력하십시오.'그런 다음 쿼리를 실행하십시오. Prolog 문서에서 설명합니다. 더 이상 추적하고 싶지 않다면 notrace를 입력하십시오. – lurker