Integer logarithm of base 2 (specification)

Specification

In the module generation we have to implement a piece of code of the form:
if p is the q-th power of 2 then ... else ...

To do that, we need a function which, not only gives the logarithm of a given positive integer, but tells also whether this logarithm is exact or not.

We propose the specification:

Definition log2_spec:=[n0:nat]
                      {l:nat & {n0=(two_power l)}+
                               {(lt (two_power l) n0) /\
                                (lt n0 (two_power (S l)))}}.
(The function two_power(exponential of base 2) is defined and studied in the module two_power).

An implementation of the integer logarithm is a proof of a statement of the form:

(n0:nat)(lt O n0)->(log2_spec n0).
Normally, the proof of this statement should begin with a
Realizer T.
where T is some Fw term of type nat->nat*bool

The first component of the result is the integer logarithm of the argument, and the second is a boolean which is true if the logarithm is exact, else false. See the module log2_implementation , for an "imperative" implementation of log2_spec.

Applications

We give two applications of our definitions: Given a function
log2:(n:nat)(lt O n)->(log2_spec n),
we build two other functions: Please notice that both functions are build from log2 with Realizer and Program_all:

For the beginner ...

In the first versions of this development, we had a single module log2, which contained both specification and implementation; the separation in two modules: this one and log2_implementation, increases the modularity of all the proof, and makes recompilation faster (some modules depend only on the specification, see for instance generation and dicho_strat).

See the source for more details.

A Demo in Caml-Light

This module give us two functionals: floor_log2 and ceiling_log2, which take as parameter a correct implementation of log2_spec. If we use the implementation log2_impl given by the module log2_implementation, we have the following results.
#load "Demo.ml";;
##open "Demo";;

(* logarithm by default *)

#floor_log2 log2_impl 1025;;
- : int = 10

#floor_log2 log2_impl 1024;;
- : int = 10

(* logarithm by excess *)

#ceiling_log2 log2_impl 1025;;
- : int = 11

#ceiling_log2 log2_impl 1024;;
- : int = 10