The following Prolog program defines a predicate fib/2 for computing the Fibonacci number of an integer in successor arithmetics:
fib(0, 0).
fib(s(0), s(0)).
fib(s(s(N)), F) :-
fib(N, F1),
fib(s(N), F2),
sum(F1, F2, F).
sum(0, N, N).
sum(s(N1), N2, s(S)) :-
sum(N1, N2, S).
It works with queries in this argument mode:
?- fib(s(0), s(0)).
true
; false.
It also works with queries in this argument mode:
?- fib(s(0), F).
F = s(0)
; false.
It also works with queries in this argument mode:
?- fib(N, F).
N = F, F = 0
; N = F, F = s(0)
; N = s(s(0)), F = s(0)
; N = s(s(s(0))), F = s(s(0))
; N = s(s(s(s(0)))), F = s(s(s(0)))
; …
But it exhausts resources with queries in this argument mode:
?- fib(N, s(0)).
N = s(0)
; N = s(s(0))
;
Time limit exceeded
How to implement the Fibonacci sequence in successor arithmetics for all argument modes?
The naive recursive implementation of
fib/2provided in my other answer has a time complexity of O(φ^N) where φ is the golden ratio i.e. exponential time. Here is a tail recursive implementation offib/2which has a time complexity of O(N) i.e. linear time:Sample queries
The most general query (all arguments are free):
Queries with a first argument that is free:
Queries with a second argument that is free: