Computing Fibonacci numbers and generating C code. Inspired by Lee Pike's
original implementation, modified for inclusion in the package. It illustrates
symbolic termination issues one can have when working with recursive algorithms
and how to deal with such, eventually generating good C code.

However, it is not suitable for doing proofs or generating code, as it is not
symbolically terminating when it is called with a symbolic value n. When we
recursively call fib0 on n-1 (or n-2), the test against 0 will always
explore both branches since the result will be symbolic, hence will not
terminate. (An integrated theorem prover can establish termination
after a certain number of unrollings, but this would be quite expensive to
implement, and would be impractical.)

Using a recursion depth, and accumulating parameters

One way to deal with symbolic termination is to limit the number of recursive
calls. In this version, we impose a limit on the index to the function, working
correctly upto that limit. If we use a compile-time constant, then SBV's code generator
can produce code as the unrolling will eventually stop.

The function will work correctly, so long as the index we query is at most top, and otherwise
will return the value at top. Note that we also use accumulating parameters here for efficiency,
although this is orthogonal to the termination concern.

A note on modular arithmetic: The 64-bit word we use to represent the values will of course
eventually overflow, beware! Fibonacci is a fast growing function..

We can generate code for fib1 using the genFib1 action. Note that the
generated code will grow larger as we pick larger values of top, but only linearly,
thanks to the accumulating parameter trick used by fib1. The following is an excerpt
from the code generated for the call genFib1 10, where the code will work correctly
for indexes up to 10:

Once we have fib2, we can generate the C code straightforwardly. Below
is an excerpt from the code that SBV generates for the call genFib2 64. Note
that this code is a constant-time look-up table implementation of fibonacci,
with no run-time overhead. The index can be made arbitrarily large,
naturally. (Note that this function returns 0 if the index is larger
than 64, as specified by the call to select with default 0.)