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
.
log2:(n:nat)(lt O n)->(log2_spec n),we build two other functions:
ceiling_log2:(n:nat)(lt one n)-> {l:nat|(lt (two_power (pred l)) n) /\ (le n (two_power l))}.
floor_log2:(n:nat)(lt O n)-> {l:nat|(le (two_power l) n) /\ (lt n (two_power (S l)))}.
log2
with
Realizer
and Program_all
:
ceiling_log2
:
Realizer [n:nat]<nat>let (l:nat;b:bool)=(log2 n) inif b then l else (S l).
floor_log2
:
Realizer [n:nat]<nat>let (l:nat;b:bool)=(log2 n) in l .
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.
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