ここに解決策を投稿することもできますが、これは宿題であるため、非生産的です。代わりに、ここにリードがあります:
あなたがリストしたフィボナッチのバージョンの問題は、それが非効率的であることです。を呼び出すたびにfibo/2
別の2 つの呼び出しが発生しますが、これらの呼び出しの一部は同じフィボナッチ数の値を計算します。たとえば、擬似コードでは次のようになります。
(a) fibo(4) -> fibo(3), fibo(2)
(b) fibo(3) -> fibo(2), fibo(1)
(c) fibo(2) -> fibo(1), fibo(0) % called from (a)
(d) fibo(2) -> fibo(1), fibo(0) % called from (b), redundant
この欠点を克服するために、最後の値だけでなく最後の 2 つの値を返すという観点からフィボナッチを言い換えて、各呼び出しがfib/3
1 回の再帰呼び出しのみを引き起こすようにするように求められました (したがって、フィボナッチ数列を線形時間で計算します)。基本ケースを次のように変更する必要があります。
fib(1,1,0).
fib(2,1,1).
再帰的なケースはあなたに任せます。
せっかちな人向け
ここにも再帰的なケースがあります:
fib(N, Val, Last) :-
N > 2,
N1 is N - 1,
fib(N1, Last, Last1), % single call with two output arguments,
% instead of two calls with one output argument
Val is Last + Last1.