Я мог бы опубликовать здесь решение, но так как это домашнее задание, оно будет контрпродуктивным.Вместо этого вот пример:
Проблема с версией Фибоначчи, которую вы перечислили, заключается в том, что она неэффективна.Каждый вызов fibo/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
Чтобы преодолеть этот недостаток, вас попросили перефразировать Фибоначчи с точки зрения возврата не только последнего значения, но и двух последних значений, чтобы каждое из них вызывало fib/3
вызовет только один рекурсивный вызов (следовательно, рассчитайте ряд Фибоначчи за линейное время).Вам нужно изменить базовые случаи на:
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.