Skip to content

Instantly share code, notes, and snippets.

@WillNess
Forked from mndrix/example.txt
Created January 27, 2013 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WillNess/4647688 to your computer and use it in GitHub Desktop.
Save WillNess/4647688 to your computer and use it in GitHub Desktop.
Lazy Fibonacci in Prolog
?- fibs(F), take(F, 20, _).
F = [0, 1, 1, 2, 3, 5, 8, 13, 21|...],
freeze(_G2395, zip_with(plus, [2584, 4181|_G2395], [4181|_G2395], _G2395)).
zip_with(_, [], []).
zip_with(Goal, [A|As], [B|Bs], [C|Cs]) :-
call(Goal, A, B, C),
freeze(Cs, zip_with(Goal, As, Bs, Cs)).
% implementation from SWI pack list_util
take([], N, []) :-
N > 0,
!.
take(_, 0, []) :-
!.
take([H|T], N1, [H|Rest]) :-
N1 > 0,
succ(N0, N1),
take(T, N0, Rest).
% infinite, lazy Fibonacci sequence
fibs([0,1|T]) :-
F = [0,1|T],
F1 = [1|T],
freeze(T, zip_with(plus, F, F1, T)).
@WillNess
Copy link
Author

Thank you very much! Here's my take on it:

fib(X):- X=[0,1|Z], fibnext(Z,X).
fibnext(Z,X):- X=[A|Y], Y=[B|_], N is A+B, freeze(Z, (Z=[N|W],fibnext(W,Y)) ).

Seems to work too:

13 ?- fib(X), length(A,15),append(A,B,X), writeln(A).
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]

This a translation of

fib = 0:1:next fib where next (a: y@(b:_)) = (a+b):next y

@WillNess
Copy link
Author

WillNess commented May 9, 2013

Haskell:

fib = 0:1:ffib fib where ffib (a: y@(b:_)) = (a+b):ffib y

Prolog, exactly like that: -- -- -- -- -- this all started from http://stackoverflow.com/a/14514298 Jan 25 at 2:16 by mndrix

fib(X):- X=[0,1|Z], ffib(X,Z).
ffib([A|Y],Z):- Y=[B|_], N is A+B, freeze(Z, (Z=[N|W],ffib(Y,W)) ).

Test:

30 ?- fib(X), length(R,7),append(R,_,X).
X = [0, 1, 1, 2, 3, 5, 8|_G1495],
R = [0, 1, 1, 2, 3, 5, 8],
freeze(_G1495, (_G1495=[13|_G1540], ffib([8|_G1495], _G1540))).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment