(** ** Bitwise operations *)

Definition double_S : forall n, double (S n) = S (S (double n))
                    := fun n => add_succ_r (S n) n.Definition double_add : forall n m, double (n + m) = double n + double m
                      := fun n m => add_shuffle1 n m n m.

(* Specifications: *)
Lemma double_twice : forall n, double n = 2*n.
Lemma div2_double n : div2 (2*n) = n.
Lemma div2_succ_double n : div2 (S (2*n)) = n.
Lemma le_div2 n : div2 (S n) <= n.
Lemma lt_div2 n : 0 < n -> div2 n < n.
Lemma div2_decr a n : a <= S n -> div2 a <= n.
Lemma testbit_0_l : forall n, testbit 0 n = false.
Lemma testbit_odd_0 a : testbit (2*a+1) 0 = true.
Lemma testbit_even_0 a : testbit (2*a) 0 = false.
Lemma testbit_odd_succ' a n : testbit (2*a+1) (S n) = testbit a n.
Lemma testbit_even_succ' a n : testbit (2*a) (S n) = testbit a n.
Lemma shiftr_specif : forall a n m, testbit (shiftr a n) m = testbit a (m+n).
Lemma shiftl_specif_high : forall a n m, n<=m -> testbit (shiftl a n) m = testbit a (m-n).
Lemma shiftl_spec_low : forall a n m, m<n -> testbit (shiftl a n) m = false.
Lemma div2_bitwise : forall op n a b, div2 (bitwise op (S n) a b) = bitwise op n (div2 a) (div2 b).
Lemma odd_bitwise : forall op n a b, odd (bitwise op (S n) a b) = op (odd a) (odd b).
Lemma testbit_bitwise_1 : forall op, (forall b, op false b = false) -> forall n m a b, a<=n -> testbit (bitwise op n a b) m = op (testbit a m) (testbit b m).
Lemma testbit_bitwise_2 : forall op, op false false = false -> forall n m a b, a<=n -> b<=n -> testbit (bitwise op n a b) m = op (testbit a m) (testbit b m).
Lemma land_spec a b n : testbit (land a b) n = testbit a n && testbit b n.
Lemma ldiff_spec a b n : testbit (ldiff a b) n = testbit a n && negb (testbit b n).
Lemma lor_spec a b n : testbit (lor a b) n = testbit a n || testbit b n.
Lemma lxor_spec a b n : testbit (lxor a b) n = xorb (testbit a n) (testbit b n).
Lemma div2_spec a : div2 a = shiftr a 1.