Notation pow2 := (Nat.pow 2).Fixpoint Npow2 (n : nat) : N :=
  match n with
    | O => 1
    | S n' => 2 * Npow2 n'
  end%N.

(* Specifications: *)
Theorem untimes2 : forall n, n + (n + 0) = 2 * n.
Lemma strong' : forall n m, m <= n -> P m.
Theorem strong : forall n, P n.
Theorem div2_odd : forall n, mod2 n = true -> n = S (2 * div2 n).
Theorem div2_even : forall n, mod2 n = false -> n = 2 * div2 n.
Theorem drop_mod2 : forall n k, 2 * k <= n -> mod2 (n - 2 * k) = mod2 n.
Theorem div2_minus_2 : forall n k, 2 * k <= n -> div2 (n - 2 * k) = div2 n - k.
Theorem div2_bound : forall k n, 2 * k <= n -> k <= div2 n.
Lemma two_times_div2_bound: forall n, 2 * Nat.div2 n <= n.
Lemma div2_compat_lt_l: forall a b, b < 2 * a -> Nat.div2 b < a.
Lemma pow2_add_mul: forall a b, pow2 (a + b) = (pow2 a) * (pow2 b).
Lemma mult_pow2_bound: forall a b x y, x < pow2 a -> y < pow2 b -> x * y < pow2 (a + b).
Lemma mult_pow2_bound_ex: forall a c x y, x < pow2 a -> y < pow2 (c - a) -> c >= a -> x * y < pow2 c.
Lemma lt_mul_mono' : forall c a b, a < b -> a < b * (S c).
Lemma lt_mul_mono : forall a b c, c <> 0 -> a < b -> a < b * c.
Lemma zero_lt_pow2 : forall sz, 0 < pow2 sz.
Lemma one_lt_pow2: forall n, 1 < pow2 (S n).
Lemma one_le_pow2 : forall sz, 1 <= pow2 sz.
Lemma pow2_ne_zero: forall n, pow2 n <> 0.
Lemma mul2_add : forall n, n * 2 = n + n.
Lemma pow2_le_S : forall sz, (pow2 sz) + 1 <= pow2 (sz + 1).
Lemma pow2_bound_mono: forall a b x, x < pow2 a -> a <= b -> x < pow2 b.
Lemma pow2_inc : forall n m, 0 < n -> n < m -> pow2 n < pow2 m.
Lemma pow2_S: forall x, pow2 (S x) = 2 * pow2 x.
Lemma mod2_S_S : forall n, mod2 (S (S n)) = mod2 n.
Lemma mod2_S_not : forall n, mod2 (S n) = if (mod2 n) then false else true.
Lemma mod2_S_eq : forall n k, mod2 n = mod2 k -> mod2 (S n) = mod2 (S k).
Theorem drop_mod2_add : forall n k, mod2 (n + 2 * k) = mod2 n.
Lemma mod2sub: forall a b, b <= a -> mod2 (a - b) = xorb (mod2 a) (mod2 b).
Theorem mod2_pow2_twice: forall n, mod2 (pow2 n + (pow2 n + 0)) = false.
Theorem div2_plus_2 : forall n k, div2 (n + 2 * k) = div2 n + k.
Lemma pred_add: forall n, n <> 0 -> pred n + 1 = n.
Lemma pow2_zero: forall sz, (pow2 sz > 0)%nat.
Theorem Npow2_nat : forall n, nat_of_N (Npow2 n) = pow2 n.
Theorem pow2_N : forall n, Npow2 n = N.of_nat (pow2 n).
Lemma Z_of_N_Npow2: forall n, Z.of_N (Npow2 n) = (2 ^ Z.of_nat n)%Z.
Lemma pow2_S_z: forall n, Z.of_nat (pow2 (S n)) = (2 * Z.of_nat (pow2 n))%Z.
Lemma pow2_le: forall n m, (n <= m)%nat -> (pow2 n <= pow2 m)%nat.
Lemma Zabs_of_nat: forall n, Z.abs (Z.of_nat n) = Z.of_nat n.
Lemma Npow2_not_zero: forall n, Npow2 n <> 0%N.
Lemma Npow2_S: forall n, Npow2 (S n) = (Npow2 n + Npow2 n)%N.
Lemma Npow2_pos: forall a, (0 < Npow2 a)%N.
Lemma minus_minus: forall a b c, c <= b <= a -> a - (b - c) = a - b + c.
Lemma even_odd_destruct: forall n, (exists a, n = 2 * a) \/ (exists a, n = 2 * a + 1).
Lemma mul_div_undo: forall i c, c <> 0 -> c * i / c = i.
Lemma mod_add_r: forall a b, b <> 0 -> (a + b) mod b = a mod b.
Lemma mod2_cases: forall (n: nat), n mod 2 = 0 \/ n mod 2 = 1.
Lemma div_mul_undo: forall a b, b <> 0 -> a mod b = 0 -> a / b * b = a.
Lemma Smod2_1: forall k, S k mod 2 = 1 -> k mod 2 = 0.
Lemma mod_0_r: forall (m: nat), m mod 0 = 0.
Lemma sub_mod_0: forall (a b m: nat), a mod m = 0 -> b mod m = 0 -> (a - b) mod m = 0.
Lemma mul_div_exact: forall (a b: nat), b <> 0 -> a mod b = 0 -> b * (a / b) = a.