pretposlednji([1]).
poslednji([1]).

dodati( [], L, L ):- !.
dodati( [G|R], L, [G|R1] ):-dodati( R, L, R1 ).

okreni( [], [] ) :- !.
okreni( [G|R], N ) :- okreni( R, R1 ), dodati( R1, [G], N ).

prenos( [], [1] ):-!.
prenos( [G1|R1], [G|R1] ) :- G1 < 9, G is G1+1.
prenos( [G1|R1], [G|R] ) :- G is 0, prenos( R1, R ).

saberi( [], A, A ):- !.
saberi( A, [], A ):- !.
saberi( [G1|R1], [G2|R2], [G|R] ) :- G1+G2 < 10, G is G1+G2, saberi( R1, R2, R ).
saberi( [G1|R1], [G2|R2], [G|R] ) :- G1+G2 >= 10, G is ((G1+G2) mod 10), saberi( R1, R2, R3 ), prenos(R3, R).


zbir( A, B, C ) :- okreni( A, A1 ), okreni( B, B1),
  saberi( A1, B1, C1 ), okreni( C1, C ). 

fibonaci( 2 ) :- poslednji(X), write( X ),
  retractall( poslednji( _ ) ), assert( poslednji([1]) ), 
  retractall( pretposlednji( _ ) ), assert( pretposlednji([1]) ), !. 
fibonaci( N ):- poslednji(X), pretposlednji(Y), zbir( X, Y, Z ), 
  retractall( poslednji( _ ) ), assert( poslednji(Z) ), 
  retractall( pretposlednji( _ ) ), assert( pretposlednji(X) ),
  N1 is N-1, fibonaci( N1 ), !.

fibonaci( 2,[X] ) :- poslednji(X),
  retractall( poslednji( _ ) ), assert( poslednji([1]) ), 
  retractall( pretposlednji( _ ) ), assert( pretposlednji([1]) ), !. 
fibonaci( N,[L|L1] ):- poslednji(X), pretposlednji(Y), zbir( X, Y, Z ), 
  retractall( poslednji( _ ) ), assert( poslednji(Z) ), 
  retractall( pretposlednji( _ ) ), assert( pretposlednji(X) ),
  N1 is N-1, fibonaci( N1,L1 ), !.
  
izdvoj_zadnji([X],X):-!.
izdvoj_zadnji([_|L],X):-izdvoj_zadnji(L,X).  

jestefib(L):-skup(2,35,S),pripada(N,S),fibonaci(N,L1),izdvoj_zadnji(L1,L).

skup(I,G,[I|Rep]):-I =< G, M is I + 1, skup(M,G,Rep), !.
skup(_,_,[]).
pripada(X,[X|_]).
pripada(X,[_|Y]):-pripada(X,Y).

 
 