Section Log_pos. (* Log of positive integers *)
(** First we build [log_inf] and [log_sup] *)
Fixpoint log_inf (p:positive) : Z :=
match p with
| xH => 0 (* 1 *)
| xO q => Z.succ (log_inf q)       (* 2n *)
| xI q => Z.succ (log_inf q)       (* 2n+1 *)
end.
Fixpoint log_sup (p:positive) : Z :=
match p with
| xH => 0	(* 1 *)
| xO n => Z.succ (log_sup n) (* 2n *)
| xI n => Z.succ (Z.succ (log_inf n))	(* 2n+1 *)
end.
Hint Unfold log_inf log_sup : core.
(** Then we give the specifications of [log_inf] and [log_sup] and prove their validity *)
Hint Resolve Z.le_trans: zarith.
Definition log_inf_correct1 (p:positive) := proj1 (log_inf_correct p).
Definition log_inf_correct2 (p:positive) := proj2 (log_inf_correct p).
Opaque log_inf_correct1 log_inf_correct2.
Hint Resolve log_inf_correct1 log_inf_correct2: zarith.
(** For every [p], either [p] is a power of two and [(log_inf p)=(log_sup p)] either [(log_sup p)=(log_inf p)+1] *)
(** Now it's possible to specify and build the [Log] rounded to the nearest *)
Fixpoint log_near (x:positive) : Z :=
match x with
| xH => 0
| xO xH => 1
| xI xH => 2
| xO y => Z.succ (log_near y)
| xI y => Z.succ (log_near y)
end.

Theorem log_near_correct2 :
forall p:positive, log_near p = log_inf p \/ log_near p = log_sup p.