Module NZLog2UpProp
(Import A : NZDecOrdAxiomsSig')
(Import B : NZPow' A)
(Import C : NZLog2 A B)
(Import D : NZMulOrderProp A)
(Import E : NZPowProp A B D)
(Import F : NZLog2Prop A B C D E).
(** * [log2_up] : a binary logarithm that rounds up instead of down *)
(** For once, we define instead of axiomatizing, thanks to log2 *)
Definition log2_up a :=
match compare 1 a with
| Lt => S (log2 (P a))
| _ => 0
end.
Instance log2_up_wd : Proper (eq==>eq) log2_up.
(** [log2_up] is always non-negative *)
(** The spec of [log2_up] indeed determines it *)
(** [log2_up] is exact on powers of 2 *)
(** [log2_up] and successors of powers of 2 *)
(** Basic constants *)
(** Links between log2 and [log2_up] *)
(** [log2_up] n is strictly positive for 1<n *)
(** Said otherwise, [log2_up] is null only below 1 *)
(** [log2_up] is a monotone function (but not a strict one) *)
(** No reverse result for <=, consider for instance log2_up 4 <= log2_up 3 *)
(** When left side is a power of 2, we have an equivalence for < *)
(** When right side is a square, we have an equivalence for <= *)
(** Comparing [log2_up] and identity *)
(** [log2_up] and multiplication. *)
(** Due to rounding error, we don't have the usual [log2_up (a*b) = log2_up a + log2_up b] but we may be off by 1 at most *)
(** And we can't find better approximations in general. - The upper bound is exact for powers of 2. - Concerning the lower bound, for any c>1, take a=b=2^c+1, then [log2_up (a*b) = c+c +1] while [(log2_up a) = (log2_up b) = c+1] *)
(** At least, we get back the usual equation when we multiply by 2 (or 2^k) *)
(** Two numbers with same [log2_up] cannot be far away. *)
(** [log2_up] and successor : - the [log2_up] function climbs by at most 1 at a time - otherwise it stays at the same value - the +1 steps occur after powers of two *)

Lemma log2_up_succ_or : forall a,
log2_up (S a) == S (log2_up a) \/ log2_up (S a) == log2_up a.