まず、元のコードを次のように書き直します
fib(N, NthFib) :- fib(1, N, 1, 0, NthFib).
fib(K, N, Ans, Tmp, NthFib) :-
K > N -> Ans = NthFib; % use = instead of is here
K =< N -> fib((K+1), N, (Ans+Tmp), Ans, NthFib).
今、
?- fib(7,X).
X = 1+0+1+ (1+0)+ (1+0+1)+ (1+0+1+ (1+0))+ (1+0+1+ (1+0)+ (1+0+1))+
(1+0+1+ (1+0)+ (1+0+1)+ (1+0+1+ (1+0)))
Yes
?- fib(7,X), Z is X.
X = 1+0+1+ (1+0)+ (1+0+1)+ (1+0+1+ (1+0))+ (1+0+1+ (1+0)+ (1+0+1))+
(1+0+1+ (1+0)+ (1+0+1)+ (1+0+1+ (1+0)))
Z = 21
を参照してください。プロローグでは、データはシンボリックであり、を使用するとis
、算術式が算術値に強制されます(意味のある算術式であると仮定して式を評価します)。
20が7番目のフィボナッチ数であるかどうかを確認するには、引数を評価する算術比較演算子を使用できます。
?- fib(7,X), X =:= 20.
No
つまり、コードを次のように書き直す必要があります。
fib(N, NthFib) :- fib(1, N, 1, 0, NthFib).
fib(K, N, Ans, Tmp, NthFib) :-
K > N -> NthFib is Ans ; % exchange the order of operands
K =< N -> fib((K+1), N, (Ans+Tmp), Ans, NthFib).
これで、意図したとおりに機能します。
?- fib(7,21).
Yes
?- fib(7,20).
No
ただし、これらの長い式をすべてシンボリックデータとして持ち運ぶため、効率的に機能しません。本当に必要なのは数字だけなので、他の回答で示されているように、それis
を達成するために使用されます。持っているすべてのシンボリック部分式は、それを囲む式から取り出し、のis
代わりに使用して名前を付け=
ます。
ところで、21は実際にはシーケンスの8番目のメンバーです。コードを修正してください。