(**************************************************************)
(*   Copyright Dominique Larchey-Wendling [*]                 *)
(*                                                            *)
(*                             [*] Affiliation LORIA -- CNRS  *)
(**************************************************************)
(*      This file is distributed under the terms of the       *)
(*         CeCILL v2 FREE SOFTWARE LICENSE AGREEMENT          *)
(**************************************************************)
(** ** Bitwise operations on nat *)
Set Implicit Arguments.
Local Notation power := (mscal mult 1).
Local Notation "∑" := (msum plus 0).
Local Reserved Notation "x ≲ y" (at level 70, no associativity).
(* if n and m are written in binary, LSB first: n = n0 n1 n2 ... m = m0 m1 m2 ... then n ≲ m means forall any i, n[i] <= m[i] *)
Inductive binary_le : nat -> nat -> Prop :=
| in_ble_0 : forall n, 0 ≲ n
| in_ble_1 : forall n m, rem n 2 <= rem m 2 -> div n 2 ≲ div m 2 -> n ≲ m
where "x ≲ y" := (binary_le x y).
Local Infix "≲" := binary_le (at level 70, no associativity).
Fact binary_le_inv n m : n ≲ m -> n = 0 \/ div n 2 ≲ div m 2 /\ rem n 2 <= rem m 2.
Fact binary_le_le x y : x ≲ y -> x <= y.
Fact binary_le_zero_inv n : n ≲ 0 -> n = 0.
Fact div_2_bool2nat b n : div (bool2nat b+2*n) 2 = n.
Definition nat2bool x :=
match x with
| 0 => ⟘
| _ => ⟙
end.
Fact bool2nat2bool : forall x, x < 2 -> bool2nat (nat2bool x) = x.
Fact lb_mask_binary_le l m : l ⪯ m -> ⟦l⟧ ≲ ⟦m⟧.
Section nat_lb_def.
Inductive g_nlb : nat -> lb -> Prop :=
| in_gnlb_0 : g_nlb 0 nil
| in_gnlb_1 : forall n l, n <> 0 -> rem n 2 = 0 -> g_nlb (div n 2) l -> g_nlb n (⟘::l)
| in_gnlb_2 : forall n l, n <> 0 -> rem n 2 = 1 -> g_nlb (div n 2) l -> g_nlb n (⟙::l).
Fact g_nlb_fun n l1 l2 : g_nlb n l1 -> g_nlb n l2 -> l1 = l2.
Let nat_lb_full n : { l | g_nlb n l }.
Definition nat_lb n := proj1_sig (nat_lb_full n).
Fact nat_lb_spec n : g_nlb n (nat_lb n).
Fact nat_lb_fix_2 n : ⟬1+2*n⟭ = ⟙::⟬ n⟭ .
Fact nat_lb_1 : ⟬ 1⟭ = ⟙::nil.
Fact lb_nat_lb n : ⟦⟬ n ⟭⟧ = n.
Fact nat_lb_length x n : x < power n 2 -> length ⟬ x ⟭ <= n.
Fact binary_le_lb_mask x y : x ≲ y -> ⟬ x ⟭ ⪯ ⟬ y ⟭ .
Hint Resolve lb_mask_binary_le binary_le_lb_mask.
Section lb_mask_nat.
Let lb_mask_nat_1 l : ⟬ ⟦l⟧⟭  ⪯  l.
Let lb_mask_nat_2 l : l ⪯  ⟬ ⟦l⟧⟭  .
Fact lb_mask_nat l : ⟬ ⟦l⟧⟭ ≂ l.

(* Specifications: *)
Lemma binary_le_eq_lb_mask x y : x ≲ y <-> ⟬ x⟭  ⪯ ⟬ y⟭ .
Hint Resolve lb_mask_eq_binary_le binary_le_eq_lb_mask.