cubbi.com: fibonacci numbers in prolog languages: [english] [русский]
Prolog
Date: 1971 (Standardized in ISO/IEC 13211-1:1995)
Type: Logic programming language
Usage: artificial intellect, fuzzy logic, natural language processing, etc

ALGORITHM 1A: BINARY RECURSION
:- module(f1a,[main/0]).
% Predicate f(N,F) is true if N'th Fibonacci number is F.
% It uses ALGORITHM 1A: BINARY RECURSION
f(0,1).
f(1,1).
f(N,F) :-
   N > 1, N1 is N-1, N2 is N-2, f(N1,F1), f(N2,F2), F is F1+F2.
% Predicate f_print(N) prints the n'th Fibonacci number and stops the program.
f_print(N) :-
   write(N), write('th Fibonacci number is '), f(N,X), write(X), nl, halt.
% main/0 is the entry point in Ciao Prolog
main :-
   f_print(30).
main.

ALGORITHM 2A-3: DATA STRUCTURE - SIMPLE LIST
:- module(f2a,[main/0]).
:- use_module(library(lists), [length/2]).
:- use_module(library(lists), [nth/3]).
% Predicate fl(list1, N, list2) recursively calculates the first N 
% Fibonacci numbers, storing them in list2.
fl(_,N,[1,1]) :- N<2.
fl(L1,N,[T|L1]) :-
   length(L1,FLL), N =:= FLL, N1 is FLL-N+1, nth(N1,L1,T1),
   N2 is FLL-N+2, nth(N2,L1,T2), T is T1+T2.
fl(L1,N,L2) :-
   length(L1,FLL), N>FLL, N3 is N-1, fl(L1,N3,L3), fl(L3,N,L2).
% Predicate f(N,F) is true if N'th Fibonacci number is F
% It uses ALGORITHM 2A-3: DATA STRUCTURE - SIMPLE LIST
f(N,F) :-
   fl([1,1],N,FL), length(FL,FLL), N1 is FLL-N, nth(N1,FL,F).
% Predicate f_print(N) prints the n'th Fibonacci number and stops the program.
f_print(N) :-   
   write(N), write('th Fibonacci number is '), f(N,X), write(X), nl.
% main/0 is the entry point in Ciao Prolog
main :-
   f_print(1000).

ALGORITHM 2B: SIMPLE RECURSION
:- module(f2b,[main/0]).
% Predicate f(N,F) is true if N'th Fibonacci number is F.
% It uses ALGORITHM 2B: SIMPLE RECURSION
f(N,F) :- l(1,1,N,F).
% Predicate l(F1,F2,N,F) recursively calculates N'th Fiboacci number
l(F1,F2,N,F):-
   N > 1, F3 is F1+F2, N2 is N-1, l(F3,F1,N2,F);
   N < 2, F is F1.
% Predicate f_print(N) prints the n'th Fibonacci number and stops the program.
f_print(N) :-   
   write(N), write('th Fibonacci number is '), f(N,X), write(X), nl.
% main/0 is the entry point in Ciao Prolog
main :-
   f_print(1000).

ALGORITHM 2C: NON-RECURSIVE LOOP
Prolog does not support non-recursive loops.
Rewriting this algorithm using recursion gives ALGORITHM 2B.

ALGORITHM 3A: MATRIX EQUATION
:- module(f3a,[main/0]).
:- use_module(library(lists), [nth/3]).
% Predicate f(N,F) is true if N'th Fibonacci number is F.
% It uses ALGORITHM 3A: MATRIX EQUATION
f(N,F) :-
 mp(N,[1,1,1,0],R), nth(1,R,F).
% Predicate mp(N,M,R) is true if R is M raised to the Nth power
mp(N,M,R) :-
 N < 2, R = M;
 N > 1, T2 is N mod 2, T is N//2, mp(T,M,C),
   ( T2 =:= 0, mm(C,C,R);
     T2 =:= 1, mm(C,C,C2), mm(C2,M,R) ).
% Predicate mm(A,B,C) is true if C is matrix product of A and B
% (only for 2x2 matrices represented as 4 element lists)
mm([A11,A12,A21,A22],[B11,B12,B21,B22],[C11,C12,C21,C22]) :-
  C11 is A11*B11+A12*B21, C12 is A11*B12+A12*B22,
  C21 is A21*B11+A22*B21, C22 is A21*B12+A22*B22.
% Predicate f_print(N) prints the n'th Fibonacci number and stops the program.
f_print(N) :-   
   write(N), write('th Fibonacci number is '), f(N,X), write(X), nl.
% main/0 is the entry point in Ciao Prolog
main :-
   f_print(1000000).

ALGORITHM 3B: FAST RECURSION
:- module(f3b,[main/0]).
% Predicate f(N,F) is true if N'th Fibonacci number is F.
% It uses ALGORITHM 3B: FAST RECURSION
f(N,F) :- l(N,[F|_]). 
l(N,[F1|F2]) :-
    N < 2, F1 is 1, F2 is 1;
    N =:= 2, F1 is 2, F2 is 1;
    Z1 is N mod 2, Z1 =:= 1, A1 is (N-1)/2, l(A1,[K1|K2]),
        F1 is K1*(K1+K2)+K1*K2, F2 is K1*K1+K2*K2;
    Z1 is N mod 2, Z1 =:= 0, A2 is (N/2)-1, l(A2,[L1|L2]), 
        F1 is (L1+L2)*(L1+L2)+L1*L1, F2 is (L1+L2)*L1+L1*L2.
% Predicate f_print(N) prints the n'th Fibonacci number and stops the program.
f_print(N) :-   
    write(N), write('th Fibonacci number is '), f(N,X), write(X), nl.
% main/0 is the entry point in Ciao Prolog
main :-
    f_print(1000000).

ALGORITHM 3C: BINET'S FORMULA
:- module(f3c,[main/0]).
:- use_module(library(format), [format/2]).
% Predicate f(N,F) is true if N'th Fibonacci number is F.
% It uses ALGORITHM 3C: BINET'S FORMULA
f(N,F) :- 
 PHI is (1+ 5**0.5)/2, 
 F is (PHI**(N+1) - (1-PHI)**(N+1) ) / (5**0.5).

% Predicate f_print(N) prints the n'th Fibonacci number and stops the program.
f_print(N) :-   
    f(N,X), format("~dth Fibonacci number is ~d",[N,X]), nl.
% main/0 is the entry point Ciao Prolog
main :-
    f_print(70).