Числа Фибоначчи в Prolog
Простая рекурсивная реализация слишком неэффективна с точки зрения памяти, чтобы успешно выполняться в Poplog, поэтому этот пример демонстрирует более сложную технику — рекурсию с запоминанием. Дополнительный предикат memo(Goal)
определяется так, что в первый раз, когда оценивается Goal
, результат оценки добавляется в базу фактов, и при следующем запросе не переоценивается, а используется как известный факт.
После этого предикат fib(N,F)
определяется рекурсивно, но каждый вызов fib
“обернут” в предикат memo
, поэтому для каждого значения N fib(N,F)
оценивается только один раз. При таком подходе печать вычисленных чисел может производиться сразу после их вычисления, без дополнительного цикла.
% fibonacci.pl
:- dynamic(stored/1).
memo(Goal) :-
stored(Goal) -> true;
Goal, assertz(stored(Goal)).
fib(1,1) :- !, write('1, ').
fib(2,1) :- !, write('1, ').
fib(N,F) :-
N1 is N-1, memo(fib(N1,F1)),
N2 is N-2, memo(fib(N2,F2)),
F is F1 + F2,
write(F), write(', ').
% interactive
[-fibonacci].
fib(16,X), write('...'), nl.
Комментарии
]]>blog comments powered by Disqus
]]>