Module Type ZBitsProp
(Import A : ZAxiomsSig')
(Import B : ZMulOrderProp A)
(Import C : ZParityProp A B)
(Import D : ZSgnAbsProp A B)
(Import E : ZPowProp A B C D)
(Import F : ZDivProp A B D)
(Import G : NZLog2Prop A A A B E).
Include BoolEqualityFacts A.
Ltac order_nz := try apply pow_nonzero; order'.
Ltac order_pos' := try apply abs_nonneg; order_pos.
Hint Rewrite div_0_l mod_0_l div_1_r mod_1_r : nz.
(** Some properties of power and division *)
(** An injection from bits [true] and [false] to numbers 1 and 0. We declare it as a (local) coercion for shorter statements. *)
Definition b2z (b:bool) := if b then 1 else 0.
Local Coercion b2z : bool >-> t.
Instance b2z_wd : Proper (Logic.eq ==> eq) b2z := _.
(** We can compact [testbit_odd_0] [testbit_even_0] [testbit_even_succ] [testbit_odd_succ] in only two lemmas. *)
(** Alternative characterisations of [testbit] *)
(** This concise equation could have been taken as specification for testbit in the interface, but it would have been hard to implement with little initial knowledge about div and mod *)
(** This characterisation that uses only basic operations and power was initially taken as specification for testbit. We describe [a] as having a low part and a high part, with the corresponding bit in the middle. This characterisation is moderatly complex to implement, but also moderately usable... *)
(** Results about the injection [b2z] *)
(** The specification of testbit by low and high parts is complete *)

Lemma testbit_unique : forall a n (a0:bool) l h,
0<=l<2^n -> a == l + (a0 + 2*h)*2^n -> a.[n] = a0.