Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(*         *   The Coq Proof Assistant / The Coq Development Team       *)
(*  v      *   INRIA, CNRS and contributors - Copyright 1999-2018       *)
(* <O___,, *       (see CREDITS file for the list of authors)           *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)

Require Import
 Bool ZAxioms ZMulOrder ZPow ZDivFloor ZSgnAbs ZParity NZLog.
Derived properties of bitwise operations
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

forall a b c : t, a ~= 0 -> 0 <= c <= b -> a ^ (b - c) == a ^ b / a ^ c

forall a b c : t, a ~= 0 -> 0 <= c <= b -> a ^ (b - c) == a ^ b / a ^ c
a, b, c:t
Ha:a ~= 0
H:0 <= c
H':c <= b

a ^ (b - c) == a ^ b / a ^ c
a, b, c:t
Ha:a ~= 0
H:0 <= c
H':c <= b

a ^ (b - c) == a ^ (b - c + c) / a ^ c
a, b, c:t
Ha:a ~= 0
H:0 <= c
H':c <= b

a ^ (b - c) == a ^ (b - c) * a ^ c / a ^ c
a, b, c:t
Ha:a ~= 0
H:0 <= c
H':c <= b
0 <= b - c
a, b, c:t
Ha:a ~= 0
H:0 <= c
H':c <= b

a ^ (b - c) == a ^ (b - c)
a, b, c:t
Ha:a ~= 0
H:0 <= c
H':c <= b
a ^ c ~= 0
a, b, c:t
Ha:a ~= 0
H:0 <= c
H':c <= b
0 <= b - c
a, b, c:t
Ha:a ~= 0
H:0 <= c
H':c <= b

a ^ c ~= 0
a, b, c:t
Ha:a ~= 0
H:0 <= c
H':c <= b
0 <= b - c
a, b, c:t
Ha:a ~= 0
H:0 <= c
H':c <= b

0 <= b - c
now apply le_0_sub. Qed.

forall a b c : t, b ~= 0 -> 0 <= c -> a mod b == 0 -> (a / b) ^ c == a ^ c / b ^ c

forall a b c : t, b ~= 0 -> 0 <= c -> a mod b == 0 -> (a / b) ^ c == a ^ c / b ^ c
a, b, c:t
Hb:b ~= 0
Hc:0 <= c
H:a mod b == 0

(a / b) ^ c == a ^ c / b ^ c
a, b, c:t
Hb:b ~= 0
Hc:0 <= c
H:a mod b == 0

(a / b) ^ c == (b * (a / b) + a mod b) ^ c / b ^ c
a, b, c:t
Hb:b ~= 0
Hc:0 <= c
H:a mod b == 0

(a / b) ^ c == (a / b) ^ c
a, b, c:t
Hb:b ~= 0
Hc:0 <= c
H:a mod b == 0
b ^ c ~= 0
a, b, c:t
Hb:b ~= 0
Hc:0 <= c
H:a mod b == 0

b ^ c ~= 0
now apply pow_nonzero. Qed.
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.
Coercion b2z : bool >-> t.

Instance b2z_wd : Proper (Logic.eq ==> eq) b2z := _.

a:t

exists (a' : t) (b : bool), a == 2 * a' + b
a:t

exists (a' : t) (b : bool), a == 2 * a' + b
a, a':t
H:a == 2 * a'

exists (a'0 : t) (b : bool), a == 2 * a'0 + b
a, a':t
H:a == 2 * a' + 1
exists (a'0 : t) (b : bool), a == 2 * a'0 + b
a, a':t
H:a == 2 * a'

exists b : bool, a == 2 * a' + b
a, a':t
H:a == 2 * a' + 1
exists (a'0 : t) (b : bool), a == 2 * a'0 + b
a, a':t
H:a == 2 * a'

a == 2 * a' + false
a, a':t
H:a == 2 * a' + 1
exists (a'0 : t) (b : bool), a == 2 * a'0 + b
a, a':t
H:a == 2 * a' + 1

exists (a'0 : t) (b : bool), a == 2 * a'0 + b
a, a':t
H:a == 2 * a' + 1

exists b : bool, a == 2 * a' + b
a, a':t
H:a == 2 * a' + 1

a == 2 * a' + true
now simpl. Qed.
We can compact testbit_odd_0 testbit_even_0 testbit_even_succ testbit_odd_succ in only two lemmas.
a:t
b:bool

(2 * a + b).[0] = b
a:t
b:bool

(2 * a + b).[0] = b
a:t

(2 * a + 1).[0] = true
a:t
(2 * a).[0] = false
a:t

(2 * a).[0] = false
apply testbit_even_0. Qed.
a:t
b:bool
n:t

0 <= n -> (2 * a + b).[S n] = a.[n]
a:t
b:bool
n:t

0 <= n -> (2 * a + b).[S n] = a.[n]
a, n:t

0 <= n -> (2 * a + 1).[S n] = a.[n]
a, n:t
0 <= n -> (2 * a).[S n] = a.[n]
a, n:t

0 <= n -> (2 * a).[S n] = a.[n]
now apply testbit_even_succ. Qed.
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
a, n:t

0 <= n -> a.[n] == (a / 2 ^ n) mod 2
a, n:t

0 <= n -> a.[n] == (a / 2 ^ n) mod 2
a, n:t
Hn:0 <= n

a.[n] == (a / 2 ^ n) mod 2
n:t
Hn:0 <= n

forall a : t, a.[n] == (a / 2 ^ n) mod 2
n:t
Hn:0 <= n

Proper (eq ==> iff) (fun n0 : t => forall a : t, a.[n0] == (a / 2 ^ n0) mod 2)
n:t
Hn:0 <= n
forall a : t, a.[0] == (a / 2 ^ 0) mod 2
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2
n:t
Hn:0 <= n

forall a : t, a.[0] == (a / 2 ^ 0) mod 2
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2
n:t
Hn:0 <= n
a:t

a.[0] == (a / 2 ^ 0) mod 2
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2
n:t
Hn:0 <= n
a:t

a.[0] == a mod 2
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2
n:t
Hn:0 <= n
a, a':t
b:bool
H:a == 2 * a' + b

a.[0] == a mod 2
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2
n:t
Hn:0 <= n
a, a':t
b:bool
H:a == 2 * a' + b

(2 * a' + b).[0] == a mod 2
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2
n:t
Hn:0 <= n
a, a':t
b:bool
H:a == 2 * a' + b

b == a mod 2
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2
n:t
Hn:0 <= n
a, a':t
b:bool
H:a == 2 * a' + b

0 <= b < 2 \/ 2 < b <= 0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2
n:t
Hn:0 <= n
a, a':t
b:bool
H:a == 2 * a' + b

0 <= b < 2
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2
n:t
Hn:0 <= n

forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2

forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2
n:t
Hn:0 <= n
IH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2
a:t

a.[S n] == (a / 2 ^ S n) mod 2
n:t
Hn:0 <= n
IH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2
a, a':t
b:bool
H:a == 2 * a' + b

a.[S n] == (a / 2 ^ S n) mod 2
n:t
Hn:0 <= n
IH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2
a, a':t
b:bool
H:a == 2 * a' + b

(2 * a' + b).[S n] == (a / 2 ^ S n) mod 2
n:t
Hn:0 <= n
IH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2
a, a':t
b:bool
H:a == 2 * a' + b

(a' / 2 ^ n) mod 2 == (a / 2 ^ S n) mod 2
n:t
Hn:0 <= n
IH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2
a, a':t
b:bool
H:a == 2 * a' + b

a' / 2 ^ n == a / 2 ^ S n
n:t
Hn:0 <= n
IH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2
a, a':t
b:bool
H:a == 2 * a' + b

a' / 2 ^ n == a / 2 / 2 ^ n
n:t
Hn:0 <= n
IH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2
a, a':t
b:bool
H:a == 2 * a' + b

a' == a / 2
n:t
Hn:0 <= n
IH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2
a, a':t
b:bool
H:a == 2 * a' + b

0 <= b < 2 \/ 2 < b <= 0
n:t
Hn:0 <= n
IH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2
a, a':t
b:bool
H:a == 2 * a' + b

0 <= b < 2
destruct b; split; simpl; order'. Qed.
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...
a, n:t

0 <= n -> exists l h : t, 0 <= l < 2 ^ n /\ a == l + (a.[n] + 2 * h) * 2 ^ n
a, n:t

0 <= n -> exists l h : t, 0 <= l < 2 ^ n /\ a == l + (a.[n] + 2 * h) * 2 ^ n
a, n:t
Hn:0 <= n

exists l h : t, 0 <= l < 2 ^ n /\ a == l + (a.[n] + 2 * h) * 2 ^ n
a, n:t
Hn:0 <= n

exists h : t, 0 <= a mod 2 ^ n < 2 ^ n /\ a == a mod 2 ^ n + (a.[n] + 2 * h) * 2 ^ n
a, n:t
Hn:0 <= n

0 <= a mod 2 ^ n < 2 ^ n /\ a == a mod 2 ^ n + (a.[n] + 2 * (a / 2 ^ n / 2)) * 2 ^ n
a, n:t
Hn:0 <= n

0 <= a mod 2 ^ n < 2 ^ n
a, n:t
Hn:0 <= n
a == a mod 2 ^ n + (a.[n] + 2 * (a / 2 ^ n / 2)) * 2 ^ n
a, n:t
Hn:0 <= n

a == a mod 2 ^ n + (a.[n] + 2 * (a / 2 ^ n / 2)) * 2 ^ n
a, n:t
Hn:0 <= n

a == 2 ^ n * (2 * (a / 2 ^ n / 2) + a.[n]) + a mod 2 ^ n
a, n:t
Hn:0 <= n

2 ^ n * (a / 2 ^ n) + a mod 2 ^ n == 2 ^ n * (2 * (a / 2 ^ n / 2) + a.[n]) + a mod 2 ^ n
a, n:t
Hn:0 <= n

a / 2 ^ n == 2 * (a / 2 ^ n / 2) + a.[n]
a, n:t
Hn:0 <= n

a / 2 ^ n == 2 * (a / 2 ^ n / 2) + (a / 2 ^ n) mod 2
a, n:t
Hn:0 <= n

2 ~= 0
order'. Qed.

forall a n : t, 0 <= n -> a.[n] = true <-> (a / 2 ^ n) mod 2 == 1

forall a n : t, 0 <= n -> a.[n] = true <-> (a / 2 ^ n) mod 2 == 1
a, n:t
Hn:0 <= n

a.[n] = true <-> (a / 2 ^ n) mod 2 == 1
a, n:t
Hn:0 <= n

a.[n] = true <-> a.[n] == 1
destruct a.[n]; split; simpl; now try order'. Qed.

forall a n : t, 0 <= n -> a.[n] = false <-> (a / 2 ^ n) mod 2 == 0

forall a n : t, 0 <= n -> a.[n] = false <-> (a / 2 ^ n) mod 2 == 0
a, n:t
Hn:0 <= n

a.[n] = false <-> (a / 2 ^ n) mod 2 == 0
a, n:t
Hn:0 <= n

a.[n] = false <-> a.[n] == 0
destruct a.[n]; split; simpl; now try order'. Qed.

forall a n : t, 0 <= n -> a.[n] = ((a / 2 ^ n) mod 2 =? 1)

forall a n : t, 0 <= n -> a.[n] = ((a / 2 ^ n) mod 2 =? 1)
a, n:t
Hn:0 <= n

a.[n] = ((a / 2 ^ n) mod 2 =? 1)
a, n:t
Hn:0 <= n

a.[n] = true <-> ((a / 2 ^ n) mod 2 =? 1) = true
now rewrite testbit_true, eqb_eq. Qed.
Results about the injection b2z

forall a0 b0 : bool, a0 == b0 -> a0 = b0

forall a0 b0 : bool, a0 == b0 -> a0 = b0
intros [|] [|]; simpl; trivial; order'. Qed.

forall (a0 : bool) (a : t), (a0 + 2 * a) / 2 == a

forall (a0 : bool) (a : t), (a0 + 2 * a) / 2 == a
a0:bool
a:t

(a0 + 2 * a) / 2 == a
a0:bool
a:t

a0 / 2 + a == a
now rewrite div_small, add_0_l by (destruct a0; split; simpl; order'). Qed.

forall (a0 : bool) (a : t), (a0 + 2 * a).[0] = a0

forall (a0 : bool) (a : t), (a0 + 2 * a).[0] = a0
a0:bool
a:t

(a0 + 2 * a).[0] = a0
a0:bool
a:t

(a0 + 2 * a).[0] == a0
a0:bool
a:t

((a0 + 2 * a) / 2 ^ 0) mod 2 == a0
a0:bool
a:t

(a0 + 2 * a) mod 2 == a0
a0:bool
a:t

a0 mod 2 == a0
now rewrite mod_small by (destruct a0; split; simpl; order'). Qed.

forall a0 : bool, a0 / 2 == 0

forall a0 : bool, a0 / 2 == 0
a0:bool

a0 / 2 == 0
a0:bool

a0 / 2 == (a0 + 2 * 0) / 2
now nzsimpl. Qed.

forall a0 : bool, a0.[0] = a0

forall a0 : bool, a0.[0] = a0
a0:bool

a0.[0] = a0
a0:bool

a0.[0] = (a0 + 2 * 0).[0]
now nzsimpl. Qed.
The specification of testbit by low and high parts is complete

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

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

a.[n] = a0
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n

0 <= n
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n
a.[n] = a0
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
Hn:n < 0

0 <= n
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n
a.[n] = a0
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 0
EQ:a == l + (a0 + 2 * h) * 2 ^ n
Hn:n < 0

0 <= n
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n
a.[n] = a0
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n

a.[n] = a0
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n

a.[n] == a0
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n

(a / 2 ^ n) mod 2 == a0
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n

a0 == (a / 2 ^ n) mod 2
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n

0 <= a0 < 2 \/ 2 < a0 <= 0
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n
a / 2 ^ n == 2 * h + a0
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n

a / 2 ^ n == 2 * h + a0
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n

2 * h + a0 == a / 2 ^ n
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n

0 <= l < 2 ^ n \/ 2 ^ n < l <= 0
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n
a == 2 ^ n * (2 * h + a0) + l
a, n:t
a0:bool
l, h:t
Hl:0 <= l < 2 ^ n
EQ:a == l + (a0 + 2 * h) * 2 ^ n
H:0 <= n

a == 2 ^ n * (2 * h + a0) + l
now rewrite add_comm, (add_comm _ a0), mul_comm. Qed.
All bits of number 0 are 0

forall n : t, 0.[n] = false

forall n : t, 0.[n] = false
n:t

0.[n] = false
n:t
H:0 <= n

0.[n] = false
n:t
H:n < 0
0.[n] = false
n:t
H:0 <= n

(0 / 2 ^ n) mod 2 == 0
n:t
H:n < 0
0.[n] = false
n:t
H:n < 0

0.[n] = false
now apply testbit_neg_r. Qed.
For negative numbers, we are actually doing two's complement

forall a n : t, 0 <= n -> (- a).[n] = negb (P a).[n]

forall a n : t, 0 <= n -> (- a).[n] = negb (P a).[n]
a, n:t
Hn:0 <= n

(- a).[n] = negb (P a).[n]
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] = negb (P a).[n]
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] = negb (P a).[n]
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(P a).[n] = negb (- a).[n]
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

0 <= 2 ^ n - l - 1 < 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
P a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

0 <= 2 ^ n - l - 1
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
2 ^ n - l - 1 < 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
P a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

0 < S (2 ^ n - l - 1)
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
2 ^ n - l - 1 < 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
P a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

0 < 2 ^ n - l
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
2 ^ n - l - 1 < 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
P a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

2 ^ n - l - 1 < 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
P a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

S (2 ^ n - l - 1) <= 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
P a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

2 ^ n - l <= 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
P a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

2 ^ n <= 2 ^ n + l
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
P a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

2 ^ n + 0 <= 2 ^ n + l
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n
P a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

P a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

P a == P (2 ^ n - l + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

a == 2 ^ n - l + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

- a == - (2 ^ n - l + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

- a == - 2 ^ n + l + - ((negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

- a == l + (- 2 ^ n + - ((negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n))
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

l + ((- a).[n] + 2 * h) * 2 ^ n == l + (- 2 ^ n + - ((negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n))
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

((- a).[n] + 2 * h) * 2 ^ n == - 2 ^ n + - ((negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

((- a).[n] + 2 * h) * 2 ^ n == - (2 ^ n + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

((- a).[n] + 2 * h) * 2 ^ n == - (1 * 2 ^ n + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

((- a).[n] + 2 * h) * 2 ^ n == - ((1 + (negb (- a).[n] + 2 * (- h - 1))) * 2 ^ n)
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

((- a).[n] + 2 * h) * 2 ^ n == - (1 + (negb (- a).[n] + 2 * (- h - 1))) * 2 ^ n
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] + 2 * h == - (1 + (negb (- a).[n] + 2 * (- h - 1)))
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] + 2 * h == -1 + (- negb (- a).[n] + - (2 * (- h - 1)))
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] + 2 * h == -1 + (- negb (- a).[n] + 2 * - (- h - 1))
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] + 2 * h == -1 + (- negb (- a).[n] + 2 * (h + 1))
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] + 2 * h == -1 + (- negb (- a).[n] + 2 * (1 + h))
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] + 2 * h == -1 + (- negb (- a).[n] + (2 * 1 + 2 * h))
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] + 2 * h == -1 + - negb (- a).[n] + 2 * 1 + 2 * h
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] == -1 + - negb (- a).[n] + 2 * 1
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] == -1 + - negb (- a).[n] + 2
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n

(- a).[n] == 1 - negb (- a).[n]
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + (true + 2 * h) * 2 ^ n

1 == 1 - 0
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + (false + 2 * h) * 2 ^ n
0 == 1 - 1
a, n:t
Hn:0 <= n
l, h:t
Hl:0 <= l < 2 ^ n
EQ:- a == l + (false + 2 * h) * 2 ^ n

0 == 1 - 1
now nzsimpl'. Qed.
All bits of number (-1) are 1

forall n : t, 0 <= n -> (-1).[n] = true

forall n : t, 0 <= n -> (-1).[n] = true
n:t
H:0 <= n

(-1).[n] = true
now rewrite bits_opp, one_succ, pred_succ, bits_0. Qed.
Various ways to refer to the lowest bit of a number

forall a : t, a.[0] = odd a

forall a : t, a.[0] = odd a
a:t

a.[0] = odd a
a:t

odd a = a.[0]
a, a':t
b:bool
EQ:a == 2 * a' + b

odd a = a.[0]
a, a':t
b:bool
EQ:a == 2 * a' + b

odd b = b
destruct b; simpl; apply odd_1 || apply odd_0. Qed.

forall a : t, a.[0] = (a mod 2 =? 1)

forall a : t, a.[0] = (a mod 2 =? 1)
a:t

a.[0] = (a mod 2 =? 1)
a:t

((a / 2 ^ 0) mod 2 =? 1) = (a mod 2 =? 1)
now nzsimpl. Qed.

forall a : t, a.[0] == a mod 2

forall a : t, a.[0] == a mod 2
a:t

a.[0] == a mod 2
a:t

(a / 2 ^ 0) mod 2 == a mod 2
now nzsimpl. Qed.
Hence testing a bit is equivalent to shifting and testing parity

forall a n : t, a.[n] = odd (a >> n)

forall a n : t, a.[n] = odd (a >> n)
a, n:t

a.[n] = odd (a >> n)
now rewrite <- bit0_odd, shiftr_spec, add_0_l. Qed.
log2 gives the highest nonzero bit of positive numbers

forall a : t, 0 < a -> a.[log2 a] = true

forall a : t, 0 < a -> a.[log2 a] = true
a:t
Ha:0 < a

a.[log2 a] = true
a:t
Ha:0 < a
Ha':0 <= log2 a

a.[log2 a] = true
a:t
Ha:0 < a
Ha':0 <= log2 a
r:t
EQ:a == 2 ^ log2 a + r
Hr:0 <= r < 2 ^ log2 a

a.[log2 a] = true
a:t
Ha:0 < a
Ha':0 <= log2 a
r:t
EQ:a == 2 ^ log2 a + r
Hr:0 <= r < 2 ^ log2 a

(2 ^ log2 a + r).[log2 a] = true
a:t
Ha:0 < a
Ha':0 <= log2 a
r:t
EQ:a == 2 ^ log2 a + r
Hr:0 <= r < 2 ^ log2 a

((r + 2 ^ log2 a) / 2 ^ log2 a) mod 2 == 1
a:t
Ha:0 < a
Ha':0 <= log2 a
r:t
EQ:a == 2 ^ log2 a + r
Hr:0 <= r < 2 ^ log2 a

((r + 1 * 2 ^ log2 a) / 2 ^ log2 a) mod 2 == 1
a:t
Ha:0 < a
Ha':0 <= log2 a
r:t
EQ:a == 2 ^ log2 a + r
Hr:0 <= r < 2 ^ log2 a

(r / 2 ^ log2 a + 1) mod 2 == 1
a:t
Ha:0 < a
Ha':0 <= log2 a
r:t
EQ:a == 2 ^ log2 a + r
Hr:0 <= r < 2 ^ log2 a

(0 + 1) mod 2 == 1
a:t
Ha:0 < a
Ha':0 <= log2 a
r:t
EQ:a == 2 ^ log2 a + r
Hr:0 <= r < 2 ^ log2 a

1 mod 2 == 1
a:t
Ha:0 < a
Ha':0 <= log2 a
r:t
EQ:a == 2 ^ log2 a + r
Hr:0 <= r < 2 ^ log2 a

0 <= 1 < 2
split; order'. Qed.

forall a n : t, 0 <= a -> log2 a < n -> a.[n] = false

forall a n : t, 0 <= a -> log2 a < n -> a.[n] = false
a, n:t
Ha:0 <= a
H:log2 a < n

a.[n] = false
a, n:t
Ha:0 <= a
H:log2 a < n

0 <= n
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n
a.[n] = false
a, n:t
Ha:0 <= a
H:log2 a < n

0 <= log2 a
a, n:t
Ha:0 <= a
H:log2 a < n
log2 a <= n
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n
a.[n] = false
a, n:t
Ha:0 <= a
H:log2 a < n

log2 a <= n
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n
a.[n] = false
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

a.[n] = false
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

(a / 2 ^ n) mod 2 == 0
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

0 mod 2 == 0
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n
0 <= a < 2 ^ n
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

0 <= a < 2 ^ n
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

0 <= a
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n
a < 2 ^ n
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

a < 2 ^ n
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

log2 a < log2 (2 ^ n)
now rewrite log2_pow2. Qed.
Hence the number of bits of a is 1+log2 a (see Pos.size_nat and Pos.size).
For negative numbers, things are the other ways around: log2 gives the highest zero bit (for numbers below -1).

forall a : t, a < -1 -> a.[log2 (P (- a))] = false

forall a : t, a < -1 -> a.[log2 (P (- a))] = false
a:t
Ha:a < -1

a.[log2 (P (- a))] = false
a:t
Ha:a < -1

(- - a).[log2 (P (- a))] = false
a:t
Ha:a < -1

negb (P (- a)).[log2 (P (- a))] = false
a:t
Ha:a < -1
0 <= log2 (P (- a))
a:t
Ha:a < -1

(P (- a)).[log2 (P (- a))] = true
a:t
Ha:a < -1
0 <= log2 (P (- a))
a:t
Ha:a < -1

0 < P (- a)
a:t
Ha:a < -1
0 <= log2 (P (- a))
a:t
Ha:- -1 < - a

0 < P (- a)
a:t
Ha:a < -1
0 <= log2 (P (- a))
a:t
Ha:1 < - a

0 < P (- a)
a:t
Ha:a < -1
0 <= log2 (P (- a))
a:t
Ha:1 < - a

S 0 < - a
a:t
Ha:a < -1
0 <= log2 (P (- a))
a:t
Ha:a < -1

0 <= log2 (P (- a))
apply log2_nonneg. Qed.

forall a n : t, a < 0 -> log2 (P (- a)) < n -> a.[n] = true

forall a n : t, a < 0 -> log2 (P (- a)) < n -> a.[n] = true
a, n:t
Ha:a < 0
H:log2 (P (- a)) < n

a.[n] = true
a, n:t
Ha:a < 0
H:log2 (P (- a)) < n

0 <= n
a, n:t
Ha:a < 0
H:log2 (P (- a)) < n
Hn:0 <= n
a.[n] = true
a, n:t
Ha:a < 0
H:log2 (P (- a)) < n

0 <= log2 (P (- a))
a, n:t
Ha:a < 0
H:log2 (P (- a)) < n
log2 (P (- a)) <= n
a, n:t
Ha:a < 0
H:log2 (P (- a)) < n
Hn:0 <= n
a.[n] = true
a, n:t
Ha:a < 0
H:log2 (P (- a)) < n

log2 (P (- a)) <= n
a, n:t
Ha:a < 0
H:log2 (P (- a)) < n
Hn:0 <= n
a.[n] = true
a, n:t
Ha:a < 0
H:log2 (P (- a)) < n
Hn:0 <= n

a.[n] = true
a, n:t
Ha:a < 0
H:log2 (P (- a)) < n
Hn:0 <= n

(P (- a)).[n] = false
a, n:t
Ha:a < 0
H:log2 (P (- a)) < n
Hn:0 <= n

0 <= P (- a)
now rewrite <- opp_succ, opp_nonneg_nonpos, le_succ_l. Qed.
Accessing a high enough bit of a number gives its sign

forall a n : t, log2 (abs a) < n -> 0 <= a <-> a.[n] = false

forall a n : t, log2 (abs a) < n -> 0 <= a <-> a.[n] = false
a, n:t
Hn:log2 (abs a) < n

0 <= a <-> a.[n] = false
a, n:t
Hn:log2 (abs a) < n
H:0 <= a

a.[n] = false
a, n:t
Hn:log2 (abs a) < n
H:a.[n] = false
0 <= a
a, n:t
Hn:log2 a < n
H:0 <= a

a.[n] = false
a, n:t
Hn:log2 (abs a) < n
H:a.[n] = false
0 <= a
a, n:t
Hn:log2 (abs a) < n
H:a.[n] = false

0 <= a
a, n:t
Hn:log2 (abs a) < n
H:a.[n] = false
H0:a < 0

0 <= a
a, n:t
Hn:log2 (- a) < n
H:a.[n] = false
H0:a < 0

0 <= a
a, n:t
Hn:log2 (- a) < n
H:a.[n] = false
H0:a < 0

log2 (P (- a)) < n
a, n:t
Hn:log2 (- a) < n
H:a.[n] = false
H0:a < 0

log2 (P (- a)) <= log2 (- a)
a, n:t
Hn:log2 (- a) < n
H:a.[n] = false
H0:a < 0

P (- a) <= - a
apply le_pred_l. Qed.

forall a : t, 0 <= a <-> a.[S (log2 (abs a))] = false

forall a : t, 0 <= a <-> a.[S (log2 (abs a))] = false
a:t

0 <= a <-> a.[S (log2 (abs a))] = false
a:t

log2 (abs a) < S (log2 (abs a))
apply lt_succ_diag_r. Qed.

forall a : t, 0 <= a <-> (exists k : t, forall m : t, k < m -> a.[m] = false)

forall a : t, 0 <= a <-> (exists k : t, forall m : t, k < m -> a.[m] = false)
a:t

0 <= a <-> (exists k : t, forall m : t, k < m -> a.[m] = false)
a:t

0 <= a -> exists k : t, forall m : t, k < m -> a.[m] = false
a:t
(exists k : t, forall m : t, k < m -> a.[m] = false) -> 0 <= a
a:t
Ha:0 <= a

exists k : t, forall m : t, k < m -> a.[m] = false
a:t
(exists k : t, forall m : t, k < m -> a.[m] = false) -> 0 <= a
a:t
Ha:0 <= a

forall m : t, log2 a < m -> a.[m] = false
a:t
(exists k : t, forall m : t, k < m -> a.[m] = false) -> 0 <= a
a:t
Ha:0 <= a
m:t
Hm:log2 a < m

a.[m] = false
a:t
(exists k : t, forall m : t, k < m -> a.[m] = false) -> 0 <= a
a:t

(exists k : t, forall m : t, k < m -> a.[m] = false) -> 0 <= a
a, k:t
Hk:forall m : t, k < m -> a.[m] = false

0 <= a
a, k:t
Hk:forall m : t, k < m -> a.[m] = false
H:k <= log2 (abs a)

0 <= a
a, k:t
Hk:forall m : t, k < m -> a.[m] = false
H:log2 (abs a) < k
0 <= a
a, k:t
Hk:forall m : t, k < m -> a.[m] = false
H:log2 (abs a) < k

0 <= a
a, k:t
Hk:forall m : t, k < m -> a.[m] = false
H:log2 (abs a) < k

log2 (abs a) < S k
a, k:t
Hk:forall m : t, k < m -> a.[m] = false
H:log2 (abs a) < k
a.[S k] = false
a, k:t
Hk:forall m : t, k < m -> a.[m] = false
H:log2 (abs a) < k

a.[S k] = false
a, k:t
Hk:forall m : t, k < m -> a.[m] = false
H:log2 (abs a) < k

k < S k
apply lt_succ_diag_r. Qed.

forall a n : t, log2 (abs a) < n -> a < 0 <-> a.[n] = true

forall a n : t, log2 (abs a) < n -> a < 0 <-> a.[n] = true
a, n:t
Hn:log2 (abs a) < n

a < 0 <-> a.[n] = true
now rewrite lt_nge, <- not_false_iff_true, (bits_iff_nonneg a n). Qed.

forall a : t, a < 0 <-> a.[S (log2 (abs a))] = true

forall a : t, a < 0 <-> a.[S (log2 (abs a))] = true
a:t

a < 0 <-> a.[S (log2 (abs a))] = true
a:t

log2 (abs a) < S (log2 (abs a))
apply lt_succ_diag_r. Qed.

forall a : t, a < 0 <-> (exists k : t, forall m : t, k < m -> a.[m] = true)

forall a : t, a < 0 <-> (exists k : t, forall m : t, k < m -> a.[m] = true)
a:t

a < 0 <-> (exists k : t, forall m : t, k < m -> a.[m] = true)
a:t

a < 0 -> exists k : t, forall m : t, k < m -> a.[m] = true
a:t
(exists k : t, forall m : t, k < m -> a.[m] = true) -> a < 0
a:t
Ha:a < 0

exists k : t, forall m : t, k < m -> a.[m] = true
a:t
(exists k : t, forall m : t, k < m -> a.[m] = true) -> a < 0
a:t
Ha:a < 0

forall m : t, log2 (P (- a)) < m -> a.[m] = true
a:t
(exists k : t, forall m : t, k < m -> a.[m] = true) -> a < 0
a:t
Ha:a < 0
m:t
Hm:log2 (P (- a)) < m

a.[m] = true
a:t
(exists k : t, forall m : t, k < m -> a.[m] = true) -> a < 0
a:t

(exists k : t, forall m : t, k < m -> a.[m] = true) -> a < 0
a, k:t
Hk:forall m : t, k < m -> a.[m] = true

a < 0
a, k:t
Hk:forall m : t, k < m -> a.[m] = true
H:k <= log2 (abs a)

a < 0
a, k:t
Hk:forall m : t, k < m -> a.[m] = true
H:log2 (abs a) < k
a < 0
a, k:t
Hk:forall m : t, k < m -> a.[m] = true
H:log2 (abs a) < k

a < 0
a, k:t
Hk:forall m : t, k < m -> a.[m] = true
H:log2 (abs a) < k

log2 (abs a) < S k
a, k:t
Hk:forall m : t, k < m -> a.[m] = true
H:log2 (abs a) < k
a.[S k] = true
a, k:t
Hk:forall m : t, k < m -> a.[m] = true
H:log2 (abs a) < k

a.[S k] = true
a, k:t
Hk:forall m : t, k < m -> a.[m] = true
H:log2 (abs a) < k

k < S k
apply lt_succ_diag_r. Qed.
Testing bits after division or multiplication by a power of two

forall a n : t, 0 <= n -> (a / 2).[n] = a.[S n]

forall a n : t, 0 <= n -> (a / 2).[n] = a.[S n]
a, n:t
Hn:0 <= n

(a / 2).[n] = a.[S n]
a, n:t
Hn:0 <= n

(a / 2).[n] = true <-> a.[S n] = true
a, n:t
Hn:0 <= n

(a / 2 / 2 ^ n) mod 2 == 1 <-> (a / 2 ^ S n) mod 2 == 1
a, n:t
Hn:0 <= n

(a / 2 / 2 ^ n) mod 2 == 1 <-> (a / (2 * 2 ^ n)) mod 2 == 1
now rewrite div_div by order_pos. Qed.

forall a n m : t, 0 <= n -> 0 <= m -> (a / 2 ^ n).[m] = a.[m + n]

forall a n m : t, 0 <= n -> 0 <= m -> (a / 2 ^ n).[m] = a.[m + n]
a, n, m:t
Hn:0 <= n

0 <= m -> (a / 2 ^ n).[m] = a.[m + n]
n:t
Hn:0 <= n

forall a m : t, 0 <= m -> (a / 2 ^ n).[m] = a.[m + n]
n:t
Hn:0 <= n

Proper (eq ==> iff) (fun n0 : t => forall a m : t, 0 <= m -> (a / 2 ^ n0).[m] = a.[m + n0])
n:t
Hn:0 <= n
forall a m : t, 0 <= m -> (a / 2 ^ 0).[m] = a.[m + 0]
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a m0 : t, 0 <= m0 -> (a / 2 ^ m).[m0] = a.[m0 + m]) -> forall a m0 : t, 0 <= m0 -> (a / 2 ^ S m).[m0] = a.[m0 + S m]
n:t
Hn:0 <= n

forall a m : t, 0 <= m -> (a / 2 ^ 0).[m] = a.[m + 0]
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a m0 : t, 0 <= m0 -> (a / 2 ^ m).[m0] = a.[m0 + m]) -> forall a m0 : t, 0 <= m0 -> (a / 2 ^ S m).[m0] = a.[m0 + S m]
n:t
Hn:0 <= n
a, m:t
Hm:0 <= m

(a / 2 ^ 0).[m] = a.[m + 0]
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a m0 : t, 0 <= m0 -> (a / 2 ^ m).[m0] = a.[m0 + m]) -> forall a m0 : t, 0 <= m0 -> (a / 2 ^ S m).[m0] = a.[m0 + S m]
n:t
Hn:0 <= n

forall m : t, 0 <= m -> (forall a m0 : t, 0 <= m0 -> (a / 2 ^ m).[m0] = a.[m0 + m]) -> forall a m0 : t, 0 <= m0 -> (a / 2 ^ S m).[m0] = a.[m0 + S m]

forall m : t, 0 <= m -> (forall a m0 : t, 0 <= m0 -> (a / 2 ^ m).[m0] = a.[m0 + m]) -> forall a m0 : t, 0 <= m0 -> (a / 2 ^ S m).[m0] = a.[m0 + S m]
n:t
Hn:0 <= n
IH:forall a0 m0 : t, 0 <= m0 -> (a0 / 2 ^ n).[m0] = a0.[m0 + n]
a, m:t
Hm:0 <= m

(a / 2 ^ S n).[m] = a.[m + S n]
n:t
Hn:0 <= n
IH:forall a0 m0 : t, 0 <= m0 -> (a0 / 2 ^ n).[m0] = a0.[m0 + n]
a, m:t
Hm:0 <= m

(a / (2 * 2 ^ n)).[m] = a.[S (m + n)]
n:t
Hn:0 <= n
IH:forall a0 m0 : t, 0 <= m0 -> (a0 / 2 ^ n).[m0] = a0.[m0 + n]
a, m:t
Hm:0 <= m

(a / 2 / 2 ^ n).[m] = a.[S (m + n)]
now rewrite IH, div2_bits by order_pos. Qed.

forall a n : t, (2 * a).[S n] = a.[n]

forall a n : t, (2 * a).[S n] = a.[n]
a, n:t

(2 * a).[S n] = a.[n]
a, n:t
Hn:0 <= n

(2 * a).[S n] = a.[n]
a, n:t
Hn:n < 0
(2 * a).[S n] = a.[n]
a, n:t
Hn:n < 0

(2 * a).[S n] = a.[n]
a, n:t
Hn:n < 0

(2 * a).[S n] = false
a, n:t
Hn:S n <= 0

(2 * a).[S n] = false
a, n:t
Hn:S n < 0

(2 * a).[S n] = false
a, n:t
Hn:S n == 0
(2 * a).[S n] = false
a, n:t
Hn:S n == 0

(2 * a).[S n] = false
now rewrite Hn, bit0_odd, odd_mul, odd_2. Qed.

forall a n : t, (2 * a).[n] = a.[P n]

forall a n : t, (2 * a).[n] = a.[P n]
a, n:t

(2 * a).[n] = a.[P n]
a, n:t

(2 * a).[S (P n)] = a.[P n]
apply double_bits_succ. Qed.

forall a n m : t, 0 <= n -> (a * 2 ^ n).[n + m] = a.[m]

forall a n m : t, 0 <= n -> (a * 2 ^ n).[n + m] = a.[m]
a, n, m:t
Hn:0 <= n

(a * 2 ^ n).[n + m] = a.[m]
n:t
Hn:0 <= n

forall a m : t, (a * 2 ^ n).[n + m] = a.[m]
n:t
Hn:0 <= n

Proper (eq ==> iff) (fun n0 : t => forall a m : t, (a * 2 ^ n0).[n0 + m] = a.[m])
n:t
Hn:0 <= n
forall a m : t, (a * 2 ^ 0).[0 + m] = a.[m]
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a m0 : t, (a * 2 ^ m).[m + m0] = a.[m0]) -> forall a m0 : t, (a * 2 ^ S m).[S m + m0] = a.[m0]
n:t
Hn:0 <= n

forall a m : t, (a * 2 ^ 0).[0 + m] = a.[m]
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a m0 : t, (a * 2 ^ m).[m + m0] = a.[m0]) -> forall a m0 : t, (a * 2 ^ S m).[S m + m0] = a.[m0]
n:t
Hn:0 <= n
a, m:t

(a * 2 ^ 0).[0 + m] = a.[m]
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a m0 : t, (a * 2 ^ m).[m + m0] = a.[m0]) -> forall a m0 : t, (a * 2 ^ S m).[S m + m0] = a.[m0]
n:t
Hn:0 <= n

forall m : t, 0 <= m -> (forall a m0 : t, (a * 2 ^ m).[m + m0] = a.[m0]) -> forall a m0 : t, (a * 2 ^ S m).[S m + m0] = a.[m0]

forall m : t, 0 <= m -> (forall a m0 : t, (a * 2 ^ m).[m + m0] = a.[m0]) -> forall a m0 : t, (a * 2 ^ S m).[S m + m0] = a.[m0]
n:t
Hn:0 <= n
IH:forall a0 m0 : t, (a0 * 2 ^ n).[n + m0] = a0.[m0]
a, m:t

(a * 2 ^ S n).[S n + m] = a.[m]
n:t
Hn:0 <= n
IH:forall a0 m0 : t, (a0 * 2 ^ n).[n + m0] = a0.[m0]
a, m:t

(a * (2 * 2 ^ n)).[S (n + m)] = a.[m]
n:t
Hn:0 <= n
IH:forall a0 m0 : t, (a0 * 2 ^ n).[n + m0] = a0.[m0]
a, m:t

(2 * (a * 2 ^ n)).[S (n + m)] = a.[m]
now rewrite double_bits_succ. Qed.

forall a n m : t, 0 <= n -> (a * 2 ^ n).[m] = a.[m - n]

forall a n m : t, 0 <= n -> (a * 2 ^ n).[m] = a.[m - n]
a, n, m:t
H:0 <= n

(a * 2 ^ n).[m] = a.[m - n]
a, n, m:t
H:0 <= n

(a * 2 ^ n).[m + n - n] = a.[m - n]
a, n, m:t
H:0 <= n

(a * 2 ^ n).[n + (m - n)] = a.[m - n]
now apply mul_pow2_bits_add. Qed.

forall a n m : t, m < n -> (a * 2 ^ n).[m] = false

forall a n m : t, m < n -> (a * 2 ^ n).[m] = false
a, n, m:t
H:m < n

(a * 2 ^ n).[m] = false
a, n, m:t
H:m < n
H0:0 <= n

(a * 2 ^ n).[m] = false
a, n, m:t
H:m < n
H0:n < 0
(a * 2 ^ n).[m] = false
a, n, m:t
H:m < n
H0:0 <= n

a.[m - n] = false
a, n, m:t
H:m < n
H0:n < 0
(a * 2 ^ n).[m] = false
a, n, m:t
H:m < n
H0:0 <= n

m - n < 0
a, n, m:t
H:m < n
H0:n < 0
(a * 2 ^ n).[m] = false
a, n, m:t
H:m < n
H0:n < 0

(a * 2 ^ n).[m] = false
now rewrite pow_neg_r, mul_0_r, bits_0. Qed.
Selecting the low part of a number can be done by a modulo

forall a n m : t, 0 <= n <= m -> (a mod 2 ^ n).[m] = false

forall a n m : t, 0 <= n <= m -> (a mod 2 ^ n).[m] = false
a, n, m:t
Hn:0 <= n
H:n <= m

(a mod 2 ^ n).[m] = false
a, n, m:t
Hn:0 <= n
H:n <= m

0 < 2 ^ n
a, n, m:t
Hn:0 <= n
H:n <= m
LE:0 <= a mod 2 ^ n
LT:a mod 2 ^ n < 2 ^ n
(a mod 2 ^ n).[m] = false
a, n, m:t
Hn:0 <= n
H:n <= m
LE:0 <= a mod 2 ^ n
LT:a mod 2 ^ n < 2 ^ n

(a mod 2 ^ n).[m] = false
a, n, m:t
Hn:0 <= n
H:n <= m
LE:0 < a mod 2 ^ n
LT:a mod 2 ^ n < 2 ^ n

(a mod 2 ^ n).[m] = false
a, n, m:t
Hn:0 <= n
H:n <= m
LE:0 == a mod 2 ^ n
LT:a mod 2 ^ n < 2 ^ n
(a mod 2 ^ n).[m] = false
a, n, m:t
Hn:0 <= n
H:n <= m
LE:0 < a mod 2 ^ n
LT:a mod 2 ^ n < 2 ^ n

log2 (a mod 2 ^ n) < m
a, n, m:t
Hn:0 <= n
H:n <= m
LE:0 == a mod 2 ^ n
LT:a mod 2 ^ n < 2 ^ n
(a mod 2 ^ n).[m] = false
a, n, m:t
Hn:0 <= n
H:n <= m
LE:0 < a mod 2 ^ n
LT:a mod 2 ^ n < 2 ^ n

log2 (a mod 2 ^ n) < n
a, n, m:t
Hn:0 <= n
H:n <= m
LE:0 == a mod 2 ^ n
LT:a mod 2 ^ n < 2 ^ n
(a mod 2 ^ n).[m] = false
a, n, m:t
Hn:0 <= n
H:n <= m
LE:0 == a mod 2 ^ n
LT:a mod 2 ^ n < 2 ^ n

(a mod 2 ^ n).[m] = false
now rewrite <- LE, bits_0. Qed.

forall a n m : t, m < n -> (a mod 2 ^ n).[m] = a.[m]

forall a n m : t, m < n -> (a mod 2 ^ n).[m] = a.[m]
a, n, m:t
H:m < n

(a mod 2 ^ n).[m] = a.[m]
a, n, m:t
H:m < n
Hm:0 <= m

(a mod 2 ^ n).[m] = a.[m]
a, n, m:t
H:m < n
Hm:0 <= m

((a mod 2 ^ n / 2 ^ m) mod 2 =? 1) = a.[m]
a, n, m:t
H:m < n
Hm:0 <= m

((a mod 2 ^ n / 2 ^ m + 2 ^ P (n - m) * (a / 2 ^ n) * 2) mod 2 =? 1) = a.[m]
a, n, m:t
H:m < n
Hm:0 <= m

(((a mod 2 ^ n + 2 ^ P (n - m) * (a / 2 ^ n) * 2 * 2 ^ m) / 2 ^ m) mod 2 =? 1) = a.[m]
a, n, m:t
H:m < n
Hm:0 <= m

(((a mod 2 ^ n + 2 ^ (n - m) * (a / 2 ^ n) * 2 ^ m) / 2 ^ m) mod 2 =? 1) = a.[m]
a, n, m:t
H:m < n
Hm:0 <= m
0 <= P (n - m)
a, n, m:t
H:m < n
Hm:0 <= m

(((a mod 2 ^ n + 2 ^ n * (a / 2 ^ n)) / 2 ^ m) mod 2 =? 1) = a.[m]
a, n, m:t
H:m < n
Hm:0 <= m
0 <= n - m
a, n, m:t
H:m < n
Hm:0 <= m
0 <= P (n - m)
a, n, m:t
H:m < n
Hm:0 <= m

((a / 2 ^ m) mod 2 =? 1) = a.[m]
a, n, m:t
H:m < n
Hm:0 <= m
0 <= n - m
a, n, m:t
H:m < n
Hm:0 <= m
0 <= P (n - m)
a, n, m:t
H:m < n
Hm:0 <= m

a.[m] = ((a / 2 ^ m) mod 2 =? 1)
a, n, m:t
H:m < n
Hm:0 <= m
0 <= n - m
a, n, m:t
H:m < n
Hm:0 <= m
0 <= P (n - m)
a, n, m:t
H:m < n
Hm:0 <= m

0 <= n - m
a, n, m:t
H:m < n
Hm:0 <= m
0 <= P (n - m)
a, n, m:t
H:m < n
Hm:0 <= m

0 <= P (n - m)
now apply lt_le_pred, lt_0_sub. Qed.
We now prove that having the same bits implies equality. For that we use a notion of equality over functional streams of bits.
Definition eqf (f g:t -> bool) := forall n:t, f n = g n.


Equivalence eqf

Equivalence eqf
split; congruence. Qed. Local Infix "===" := eqf (at level 70, no associativity).

Proper (eq ==> eqf) testbit

Proper (eq ==> eqf) testbit
a, a':t
Ha:a == a'
n:t

a.[n] = a'.[n]
now rewrite Ha. Qed.
Only zero corresponds to the always-false stream.

forall a : t, (forall n : t, a.[n] = false) -> a == 0

forall a : t, (forall n : t, a.[n] = false) -> a == 0
a:t
H:forall n : t, a.[n] = false

a == 0
a:t
H:forall n : t, a.[n] = false
Ha:a < 0

a == 0
a:t
H:forall n : t, a.[n] = false
Ha:0 < a
a == 0
a:t
H:forall n : t, a.[n] = false
Ha:a.[S (log2 (P (- a)))] = true

a == 0
a:t
H:forall n : t, a.[n] = false
Ha:a < 0
log2 (P (- a)) < S (log2 (P (- a)))
a:t
H:forall n : t, a.[n] = false
Ha:0 < a
a == 0
a:t
H:forall n : t, a.[n] = false
Ha:a < 0

log2 (P (- a)) < S (log2 (P (- a)))
a:t
H:forall n : t, a.[n] = false
Ha:0 < a
a == 0
a:t
H:forall n : t, a.[n] = false
Ha:0 < a

a == 0
a:t
H:forall n : t, a.[n] = false
Ha:a.[log2 a] = true

a == 0
now rewrite H in Ha. Qed.
If two numbers produce the same stream of bits, they are equal.

forall a b : t, testbit a === testbit b -> a == b

forall a b : t, testbit a === testbit b -> a == b

forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n

forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n

Proper (eq ==> iff) (fun n0 : t => forall a b : t, 0 <= a < 2 ^ n0 -> testbit a === testbit b -> a == b)
n:t
Hn:0 <= n
forall a b : t, 0 <= a < 2 ^ 0 -> testbit a === testbit b -> a == b
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n

forall a b : t, 0 <= a < 2 ^ 0 -> testbit a === testbit b -> a == b
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
a, b:t
Ha:0 <= a < 2 ^ 0
H:testbit a === testbit b

a == b
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
a, b:t
Ha:0 <= a <= 0
H:testbit a === testbit b

a == b
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
a, b:t
Ha:0 <= a <= 0
H:testbit a === testbit b
Ha':a == 0

a == b
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
a, b:t
Ha:0 <= 0 <= 0
H:testbit 0 === testbit b
Ha':a == 0

0 == b
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
a, b:t
Ha:0 <= 0 <= 0
H:testbit 0 === testbit b
Ha':a == 0

b == 0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
a, b:t
Ha:0 <= 0 <= 0
H:testbit 0 === testbit b
Ha':a == 0

forall n0 : t, b.[n0] = false
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
a, b:t
Ha:0 <= 0 <= 0
H:testbit 0 === testbit b
Ha':a == 0
m:t

b.[m] = false
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n

forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b

forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b

a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b

2 * (a / 2) + a mod 2 == 2 * (b / 2) + b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b

2 * (a / 2) == 2 * (b / 2)
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b

a / 2 == b / 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b

0 <= a / 2 < 2 ^ n
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
testbit (a / 2) === testbit (b / 2)
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b

0 <= a / 2
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
a / 2 < 2 ^ n
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
testbit (a / 2) === testbit (b / 2)
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b

a / 2 < 2 ^ n
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
testbit (a / 2) === testbit (b / 2)
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b

0 < 2
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
a < 2 * 2 ^ n
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
testbit (a / 2) === testbit (b / 2)
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b

a < 2 * 2 ^ n
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
testbit (a / 2) === testbit (b / 2)
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b

testbit (a / 2) === testbit (b / 2)
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
m:t

(a / 2).[m] = (b / 2).[m]
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
m:t
H0:0 <= m

(a / 2).[m] = (b / 2).[m]
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
m:t
H0:m < 0
(a / 2).[m] = (b / 2).[m]
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
m:t
H0:0 <= m

a.[S m] = b.[S m]
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
m:t
H0:m < 0
(a / 2).[m] = (b / 2).[m]
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
H:testbit a === testbit b
m:t
H0:m < 0

(a / 2).[m] = (b / 2).[m]
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b
forall a b : t, testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == b

forall a b : t, testbit a === testbit b -> a == b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b

a == b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:0 <= a

a == b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
a == b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:0 <= a

0 <= a < 2 ^ a
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
a == b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:0 <= a

a < 2 ^ a
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
a == b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0

a == b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0

- S a == - S b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0

0 <= - S a
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a
- S a == - S b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0

- - S a <= - 0
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a
- S a == - S b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a

- S a == - S b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a

0 <= - S a < 2 ^ (- S a)
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a
testbit (- S a) === testbit (- S b)
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a

- S a < 2 ^ (- S a)
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a
testbit (- S a) === testbit (- S b)
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a

testbit (- S a) === testbit (- S b)
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a
m:t

(- S a).[m] = (- S b).[m]
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a
m:t
H1:0 <= m

(- S a).[m] = (- S b).[m]
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a
m:t
H1:m < 0
(- S a).[m] = (- S b).[m]
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0
a, b:t
H:testbit a === testbit b
Ha:a < 0
H0:0 <= - S a
m:t
H1:m < 0

(- S a).[m] = (- S b).[m]
now rewrite 2 testbit_neg_r. Qed.

forall a b : t, testbit a === testbit b <-> a == b

forall a b : t, testbit a === testbit b <-> a == b
a, b:t

testbit a === testbit b -> a == b
a, b:t
a == b -> testbit a === testbit b
a, b:t

a == b -> testbit a === testbit b
intros EQ; now rewrite EQ. Qed.
In fact, checking the bits at positive indexes is enough.

forall a b : t, (forall n : t, 0 <= n -> a.[n] = b.[n]) -> a == b

forall a b : t, (forall n : t, 0 <= n -> a.[n] = b.[n]) -> a == b
a, b:t
H:forall n : t, 0 <= n -> a.[n] = b.[n]

a == b
a, b:t
H:forall n : t, 0 <= n -> a.[n] = b.[n]

testbit a === testbit b
a, b:t
H:forall n0 : t, 0 <= n0 -> a.[n0] = b.[n0]
n:t

a.[n] = b.[n]
a, b:t
H:forall n0 : t, 0 <= n0 -> a.[n0] = b.[n0]
n:t
H0:0 <= n

a.[n] = b.[n]
a, b:t
H:forall n0 : t, 0 <= n0 -> a.[n0] = b.[n0]
n:t
H0:n < 0
a.[n] = b.[n]
a, b:t
H:forall n0 : t, 0 <= n0 -> a.[n0] = b.[n0]
n:t
H0:n < 0

a.[n] = b.[n]
now rewrite 2 testbit_neg_r. Qed.

forall a b : t, (forall n : t, 0 <= n -> a.[n] = b.[n]) <-> a == b

forall a b : t, (forall n : t, 0 <= n -> a.[n] = b.[n]) <-> a == b
a, b:t

(forall n : t, 0 <= n -> a.[n] = b.[n]) -> a == b
a, b:t
a == b -> forall n : t, 0 <= n -> a.[n] = b.[n]
a, b:t

a == b -> forall n : t, 0 <= n -> a.[n] = b.[n]
intros EQ n Hn; now rewrite EQ. Qed. Ltac bitwise := apply bits_inj'; intros ?m ?Hm; autorewrite with bitwise. Hint Rewrite lxor_spec lor_spec land_spec ldiff_spec bits_0 : bitwise.
The streams of bits that correspond to a numbers are exactly the ones which are stationary after some point.

forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (exists n : t, forall m : t, 0 <= m -> f m = n.[m]) <-> (exists k : t, forall m : t, k <= m -> f m = f k)

forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (exists n : t, forall m : t, 0 <= m -> f m = n.[m]) <-> (exists k : t, forall m : t, k <= m -> f m = f k)
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f

(exists n : t, forall m : t, 0 <= m -> f m = n.[m]) <-> (exists k : t, forall m : t, k <= m -> f m = f k)
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f

(exists n : t, forall m : t, 0 <= m -> f m = n.[m]) -> exists k : t, forall m : t, k <= m -> f m = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m : t, 0 <= m -> f m = a.[m]

exists k : t, forall m : t, k <= m -> f m = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m : t, 0 <= m -> f m = a.[m]
H0:0 <= a

exists k : t, forall m : t, k <= m -> f m = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m : t, 0 <= m -> f m = a.[m]
H0:a < 0
exists k : t, forall m : t, k <= m -> f m = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m : t, 0 <= m -> f m = a.[m]
H0:0 <= a

forall m : t, S (log2 a) <= m -> f m = f (S (log2 a))
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m : t, 0 <= m -> f m = a.[m]
H0:a < 0
exists k : t, forall m : t, k <= m -> f m = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]
H0:0 <= a
m:t
Hm:S (log2 a) <= m

f m = f (S (log2 a))
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m : t, 0 <= m -> f m = a.[m]
H0:a < 0
exists k : t, forall m : t, k <= m -> f m = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]
H0:0 <= a
m:t
Hm:log2 a < m

f m = f (S (log2 a))
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m : t, 0 <= m -> f m = a.[m]
H0:a < 0
exists k : t, forall m : t, k <= m -> f m = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]
H0:0 <= a
m:t
Hm:log2 a < m

0 <= S (log2 a)
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]
H0:0 <= a
m:t
Hm:log2 a < m
0 <= m
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m : t, 0 <= m -> f m = a.[m]
H0:a < 0
exists k : t, forall m : t, k <= m -> f m = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]
H0:0 <= a
m:t
Hm:log2 a < m

0 <= m
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m : t, 0 <= m -> f m = a.[m]
H0:a < 0
exists k : t, forall m : t, k <= m -> f m = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m : t, 0 <= m -> f m = a.[m]
H0:a < 0

exists k : t, forall m : t, k <= m -> f m = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m : t, 0 <= m -> f m = a.[m]
H0:a < 0

forall m : t, S (log2 (P (- a))) <= m -> f m = f (S (log2 (P (- a))))
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]
H0:a < 0
m:t
Hm:S (log2 (P (- a))) <= m

f m = f (S (log2 (P (- a))))
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]
H0:a < 0
m:t
Hm:log2 (P (- a)) < m

f m = f (S (log2 (P (- a))))
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]
H0:a < 0
m:t
Hm:log2 (P (- a)) < m

0 <= S (log2 (P (- a)))
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]
H0:a < 0
m:t
Hm:log2 (P (- a)) < m
0 <= m
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
a:t
H:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]
H0:a < 0
m:t
Hm:log2 (P (- a)) < m

0 <= m
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f

(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k

exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LT:k < 0

exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LT:k < 0
H0:f 0 = true

exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LT:k < 0
H0:f 0 = false
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LT:k < 0
H0:f 0 = true

forall m : t, 0 <= m -> f m = (-1).[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LT:k < 0
H0:f 0 = false
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m0 : t, k <= m0 -> f m0 = f k
LT:k < 0
H0:f 0 = true
m:t
Hm:0 <= m

f m = (-1).[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LT:k < 0
H0:f 0 = false
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m0 : t, k <= m0 -> f m0 = f k
LT:k < 0
H0:f 0 = true
m:t
Hm:0 <= m

f k = true
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LT:k < 0
H0:f 0 = false
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m0 : t, k <= m0 -> f m0 = f k
LT:k < 0
H0:f 0 = true
m:t
Hm:0 <= m

f 0 = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LT:k < 0
H0:f 0 = false
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LT:k < 0
H0:f 0 = false

exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LT:k < 0
H0:f 0 = false

forall m : t, 0 <= m -> f m = 0.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m0 : t, k <= m0 -> f m0 = f k
LT:k < 0
H0:f 0 = false
m:t
Hm:0 <= m

f m = 0.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m0 : t, k <= m0 -> f m0 = f k
LT:k < 0
H0:f 0 = false
m:t
Hm:0 <= m

f k = false
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m0 : t, k <= m0 -> f m0 = f k
LT:k < 0
H0:f 0 = false
m:t
Hm:0 <= m

f 0 = f k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
k:t
Hk:forall m : t, k <= m -> f m = f k
LE:0 <= k

exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k

forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k

Proper (eq ==> iff) (fun k0 : t => forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, k0 <= m -> f m = f k0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m])
k:t
LE:0 <= k
forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
(* compat : solve_proper fails here *)
k:t
LE:0 <= k

Symmetric eq
k:t
LE:0 <= k
Proper (eq ==> Basics.impl) (fun k0 : t => forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, k0 <= m -> f m = f k0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m])
k:t
LE:0 <= k
forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k:t
LE:0 <= k

Proper (eq ==> Basics.impl) (fun k0 : t => forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, k0 <= m -> f m = f k0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m])
k:t
LE:0 <= k
forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]

Proper (eq ==> Basics.impl) (fun k : t => forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m])
k:t
LE:0 <= k
forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k, k':t
Hk:k == k'
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H:forall m : t, k' <= m -> f m = f k'

exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k, k':t
Hk:k == k'
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H:forall m : t, k' <= m -> f m = f k'

forall m : t, k <= m -> f m = f k
k:t
LE:0 <= k
forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k:t
LE:0 <= k

forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
(* /compat *)
k:t
LE:0 <= k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H0:forall m : t, 0 <= m -> f m = f 0

exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k:t
LE:0 <= k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H0:forall m : t, 0 <= m -> f m = true

exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H0:forall m : t, 0 <= m -> f m = false
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k:t
LE:0 <= k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H0:forall m : t, 0 <= m -> f m = true

forall m : t, 0 <= m -> f m = (-1).[m]
k:t
LE:0 <= k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H0:forall m : t, 0 <= m -> f m = false
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k:t
LE:0 <= k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H0:forall m0 : t, 0 <= m0 -> f m0 = true
m:t
Hm:0 <= m

f m = (-1).[m]
k:t
LE:0 <= k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H0:forall m : t, 0 <= m -> f m = false
exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k:t
LE:0 <= k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H0:forall m : t, 0 <= m -> f m = false

exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k:t
LE:0 <= k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H0:forall m : t, 0 <= m -> f m = false

forall m : t, 0 <= m -> f m = 0.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k:t
LE:0 <= k
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
H0:forall m0 : t, 0 <= m0 -> f m0 = false
m:t
Hm:0 <= m

f m = 0.[m]
k:t
LE:0 <= k
forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k:t
LE:0 <= k

forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]

forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m : t, S k <= m -> f m = f (S k)

exists n : t, forall m : t, 0 <= m -> f m = n.[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m : t, S k <= m -> f m = f (S k)

Proper (eq ==> Logic.eq) (fun m : t => f (S m))
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m : t, S k <= m -> f m = f (S k)
forall m : t, k <= m -> f (S m) = f (S k)
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m : t, S k <= m -> f m = f (S k)
n:t
Hn:forall m : t, 0 <= m -> f (S m) = n.[m]
exists n0 : t, forall m : t, 0 <= m -> f m = n0.[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m : t, S k <= m -> f m = f (S k)

forall m : t, k <= m -> f (S m) = f (S k)
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m : t, S k <= m -> f m = f (S k)
n:t
Hn:forall m : t, 0 <= m -> f (S m) = n.[m]
exists n0 : t, forall m : t, 0 <= m -> f m = n0.[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n : t, forall m0 : t, 0 <= m0 -> f0 m0 = n.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
m:t
Hm:k <= m

f (S m) = f (S k)
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m : t, S k <= m -> f m = f (S k)
n:t
Hn:forall m : t, 0 <= m -> f (S m) = n.[m]
exists n0 : t, forall m : t, 0 <= m -> f m = n0.[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n : t, forall m0 : t, 0 <= m0 -> f0 m0 = n.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
m:t
Hm:k <= m

S k <= S m
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m : t, S k <= m -> f m = f (S k)
n:t
Hn:forall m : t, 0 <= m -> f (S m) = n.[m]
exists n0 : t, forall m : t, 0 <= m -> f m = n0.[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m : t, S k <= m -> f m = f (S k)
n:t
Hn:forall m : t, 0 <= m -> f (S m) = n.[m]

exists n0 : t, forall m : t, 0 <= m -> f m = n0.[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m : t, S k <= m -> f m = f (S k)
n:t
Hn:forall m : t, 0 <= m -> f (S m) = n.[m]

forall m : t, 0 <= m -> f m = (f 0 + 2 * n).[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 <= m

f m = (f 0 + 2 * n).[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 < m

f m = (f 0 + 2 * n).[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 == m
f m = (f 0 + 2 * n).[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 < m

n.[P m] = ((f 0 + 2 * n) / 2).[P m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 < m
0 <= P m
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 < m
0 <= P m
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 == m
f m = (f 0 + 2 * n).[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 < m

2 ~= 0
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 < m
0 <= P m
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 < m
0 <= P m
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 == m
f m = (f 0 + 2 * n).[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 < m

0 <= P m
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 < m
0 <= P m
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 == m
f m = (f 0 + 2 * n).[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 < m

0 <= P m
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 == m
f m = (f 0 + 2 * n).[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 == m

f m = (f 0 + 2 * n).[m]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 == m

f 0 = (f 0 + 2 * n).[0]
k:t
LE:0 <= k
IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]
f:t -> bool
Hf:Proper (eq ==> Logic.eq) f
Hk:forall m0 : t, S k <= m0 -> f m0 = f (S k)
n:t
Hn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]
m:t
Hm:0 == m

(f 0 + 2 * n).[0] = f 0
apply add_b2z_double_bit0. Qed.

Properties of shifts

First, a unified specification for shiftl : the shiftl_spec below (combined with testbit_neg_r) is equivalent to shiftl_spec_low and shiftl_spec_high.

forall a n m : t, 0 <= m -> (a << n).[m] = a.[m - n]

forall a n m : t, 0 <= m -> (a << n).[m] = a.[m - n]
a, n, m:t
H:0 <= m

(a << n).[m] = a.[m - n]
a, n, m:t
H:0 <= m
H0:n <= m

(a << n).[m] = a.[m - n]
a, n, m:t
H:0 <= m
H0:m < n
(a << n).[m] = a.[m - n]
a, n, m:t
H:0 <= m
H0:m < n

(a << n).[m] = a.[m - n]
a, n, m:t
H:0 <= m
H0:m < n

m - n < 0
now apply lt_sub_0. Qed.
A shiftl by a negative number is a shiftr, and vice-versa

forall a n : t, a >> (- n) == a << n

forall a n : t, a >> (- n) == a << n
a, n:t

a >> (- n) == a << n
a, n, m:t
Hm:0 <= m

(a >> (- n)).[m] = (a << n).[m]
now rewrite shiftr_spec, shiftl_spec, add_opp_r. Qed.

forall a n : t, a << (- n) == a >> n

forall a n : t, a << (- n) == a >> n
a, n:t

a << (- n) == a >> n
a, n, m:t
Hm:0 <= m

(a << (- n)).[m] = (a >> n).[m]
now rewrite shiftr_spec, shiftl_spec, sub_opp_r. Qed.
Shifts correspond to multiplication or division by a power of two

forall a n : t, 0 <= n -> a >> n == a / 2 ^ n

forall a n : t, 0 <= n -> a >> n == a / 2 ^ n
a, n:t
H:0 <= n

a >> n == a / 2 ^ n
a, n:t
H:0 <= n
m:t
Hm:0 <= m

(a >> n).[m] = (a / 2 ^ n).[m]
now rewrite shiftr_spec, div_pow2_bits. Qed.

forall a n : t, n <= 0 -> a >> n == a * 2 ^ (- n)

forall a n : t, n <= 0 -> a >> n == a * 2 ^ (- n)
a, n:t
H:n <= 0

a >> n == a * 2 ^ (- n)
a, n:t
H:n <= 0
m:t
Hm:0 <= m

(a >> n).[m] = (a * 2 ^ (- n)).[m]
a, n:t
H:n <= 0
m:t
Hm:0 <= m

a.[m + n] = a.[m - - n]
a, n:t
H:n <= 0
m:t
Hm:0 <= m
0 <= - n
a, n:t
H:n <= 0
m:t
Hm:0 <= m

0 <= - n
now apply opp_nonneg_nonpos. Qed.

forall a n : t, 0 <= n -> a << n == a * 2 ^ n

forall a n : t, 0 <= n -> a << n == a * 2 ^ n
a, n:t
H:0 <= n

a << n == a * 2 ^ n
a, n:t
H:0 <= n
m:t
Hm:0 <= m

(a << n).[m] = (a * 2 ^ n).[m]
now rewrite shiftl_spec, mul_pow2_bits. Qed.

forall a n : t, n <= 0 -> a << n == a / 2 ^ (- n)

forall a n : t, n <= 0 -> a << n == a / 2 ^ (- n)
a, n:t
H:n <= 0

a << n == a / 2 ^ (- n)
a, n:t
H:n <= 0
m:t
Hm:0 <= m

(a << n).[m] = (a / 2 ^ (- n)).[m]
a, n:t
H:n <= 0
m:t
Hm:0 <= m

a.[m - n] = a.[m + - n]
a, n:t
H:n <= 0
m:t
Hm:0 <= m
0 <= - n
a, n:t
H:n <= 0
m:t
Hm:0 <= m

0 <= - n
now apply opp_nonneg_nonpos. Qed.
Shifts are morphisms

Proper (eq ==> eq ==> eq) shiftr

Proper (eq ==> eq ==> eq) shiftr
a, a':t
Ha:a == a'
n, n':t
Hn:n == n'

a >> n == a' >> n'
a, a':t
Ha:a == a'
n, n':t
Hn:n == n'
H:n <= 0
H':n' <= 0

a >> n == a' >> n'
a, a':t
Ha:a == a'
n, n':t
Hn:n == n'
H:0 <= n
H':0 <= n'
a >> n == a' >> n'
a, a':t
Ha:a == a'
n, n':t
Hn:n == n'
H:0 <= n
H':0 <= n'

a >> n == a' >> n'
now rewrite 2 shiftr_div_pow2, Ha, Hn. Qed.

Proper (eq ==> eq ==> eq) shiftl

Proper (eq ==> eq ==> eq) shiftl
a, a':t
Ha:a == a'
n, n':t
Hn:n == n'

a << n == a' << n'
now rewrite <- 2 shiftr_opp_r, Ha, Hn. Qed.
We could also have specified shiftl with an addition on the left.

forall a n m : t, 0 <= n -> (a << n).[m + n] = a.[m]

forall a n m : t, 0 <= n -> (a << n).[m + n] = a.[m]
a, n, m:t
H:0 <= n

(a << n).[m + n] = a.[m]
now rewrite shiftl_mul_pow2, mul_pow2_bits, add_simpl_r. Qed.
Chaining several shifts. The only case for which there isn't any simple expression is a true shiftr followed by a true shiftl.

forall a n m : t, 0 <= n -> (a << n) << m == a << (n + m)

forall a n m : t, 0 <= n -> (a << n) << m == a << (n + m)
a, n, p:t
Hn:0 <= n

(a << n) << p == a << (n + p)
a, n, p:t
Hn:0 <= n
m:t
Hm:0 <= m

((a << n) << p).[m] = (a << (n + p)).[m]
a, n, p:t
Hn:0 <= n
m:t
Hm:0 <= m

(a << n).[m - p] = a.[m - (n + p)]
a, n, p:t
Hn:0 <= n
m:t
Hm:0 <= m

(a << n).[m - p] = a.[m - p - n]
a, n, p:t
Hn:0 <= n
m:t
Hm:0 <= m
H:0 <= m - p

(a << n).[m - p] = a.[m - p - n]
a, n, p:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m - p < 0
(a << n).[m - p] = a.[m - p - n]
a, n, p:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m - p < 0

(a << n).[m - p] = a.[m - p - n]
a, n, p:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m - p < 0

m - p - n < 0
a, n, p:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m - p < 0

m - p < n
now apply lt_le_trans with 0. Qed.

forall a n m : t, 0 <= n -> (a << n) >> m == a << (n - m)

forall a n m : t, 0 <= n -> (a << n) >> m == a << (n - m)
a, n, m:t
H:0 <= n

(a << n) >> m == a << (n - m)
now rewrite <- shiftl_opp_r, shiftl_shiftl, add_opp_r. Qed.

forall a n m : t, 0 <= n -> (a << n) >> m == a >> (m - n)

forall a n m : t, 0 <= n -> (a << n) >> m == a >> (m - n)
a, n, m:t
H:0 <= n

(a << n) >> m == a >> (m - n)
now rewrite <- 2 shiftl_opp_r, shiftl_shiftl, opp_sub_distr, add_comm. Qed.

forall a n m : t, 0 <= m -> (a >> n) >> m == a >> (n + m)

forall a n m : t, 0 <= m -> (a >> n) >> m == a >> (n + m)
a, n, p:t
Hn:0 <= p

(a >> n) >> p == a >> (n + p)
a, n, p:t
Hn:0 <= p
m:t
Hm:0 <= m

((a >> n) >> p).[m] = (a >> (n + p)).[m]
a, n, p:t
Hn:0 <= p
m:t
Hm:0 <= m

a.[m + p + n] = a.[m + (n + p)]
a, n, p:t
Hn:0 <= p
m:t
Hm:0 <= m
0 <= m + p
a, n, p:t
Hn:0 <= p
m:t
Hm:0 <= m

0 <= m + p
now apply add_nonneg_nonneg. Qed.
shifts and constants

forall n : t, 1 << n == 2 ^ n

forall n : t, 1 << n == 2 ^ n
n:t

1 << n == 2 ^ n
n:t
H:0 <= n

1 << n == 2 ^ n
n:t
H:n < 0
1 << n == 2 ^ n
n:t
H:n < 0

1 << n == 2 ^ n
n:t
H:n < 0

1 < 2 ^ (- n)
n:t
H:n < 0

1 < 2
n:t
H:n < 0
0 < - n
n:t
H:n < 0

0 < - n
now apply opp_pos_neg. Qed.

forall a : t, a << 0 == a

forall a : t, a << 0 == a
a:t

a << 0 == a
a:t

a * 2 ^ 0 == a
now nzsimpl. Qed.

forall a : t, a >> 0 == a

forall a : t, a >> 0 == a
a:t

a >> 0 == a
now rewrite <- shiftl_opp_r, opp_0, shiftl_0_r. Qed.

forall n : t, 0 << n == 0

forall n : t, 0 << n == 0
n:t

0 << n == 0
n:t
H:0 <= n

0 << n == 0
n:t
H:n <= 0
0 << n == 0
n:t
H:0 <= n

0 * 2 ^ n == 0
n:t
H:n <= 0
0 << n == 0
n:t
H:n <= 0

0 << n == 0
n:t
H:n <= 0

0 / 2 ^ (- n) == 0
n:t
H:0 <= - n

0 / 2 ^ (- n) == 0
nzsimpl; order_nz. Qed.

forall n : t, 0 >> n == 0

forall n : t, 0 >> n == 0
n:t

0 >> n == 0
now rewrite <- shiftl_opp_r, shiftl_0_l. Qed.

forall a n : t, 0 <= n -> a << n == 0 <-> a == 0

forall a n : t, 0 <= n -> a << n == 0 <-> a == 0
a, n:t
Hn:0 <= n

a << n == 0 <-> a == 0
a, n:t
Hn:0 <= n

a * 2 ^ n == 0 <-> a == 0
a, n:t
Hn:0 <= n

a == 0 \/ 2 ^ n == 0 <-> a == 0
a, n:t
Hn:0 <= n

a == 0 \/ 2 ^ n == 0 -> a == 0
a, n:t
Hn:0 <= n
a == 0 -> a == 0 \/ 2 ^ n == 0
a, n:t
Hn:0 <= n
H:2 ^ n == 0

a == 0
a, n:t
Hn:0 <= n
a == 0 -> a == 0 \/ 2 ^ n == 0
a, n:t
Hn:0 <= n

a == 0 -> a == 0 \/ 2 ^ n == 0
a, n:t
Hn:0 <= n
H:a == 0

a == 0 \/ 2 ^ n == 0
now left. Qed.

forall a n : t, a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n

forall a n : t, a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t

a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n

a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n

0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:a < 0

0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
EQ:a == 0
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:a < 0

0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 -> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:a < 0
a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:0 <= n
EQ:a == 0
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:a < 0
H:0 <= a

a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:a < 0
H:2 ^ n < a
H':a <= 0
a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:a < 0
a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:0 <= n
EQ:a == 0
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:a < 0
H:2 ^ n < a
H':a <= 0

a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:a < 0
a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:0 <= n
EQ:a == 0
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:a < 0

a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:0 <= n
EQ:a == 0
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
EQ:a == 0

0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
EQ:a == 0

0 <= 0 < 2 ^ n \/ 2 ^ n < 0 <= 0 <-> 0 == 0 \/ 0 < 0 /\ log2 0 < n
a, n:t
Hn:0 <= n
LT:0 < a
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
EQ:a == 0

0 <= 0 < 2 ^ n \/ 2 ^ n < 0 <= 0 -> 0 == 0 \/ 0 < 0 /\ log2 0 < n
a, n:t
Hn:0 <= n
EQ:a == 0
0 == 0 \/ 0 < 0 /\ log2 0 < n -> 0 <= 0 < 2 ^ n \/ 2 ^ n < 0 <= 0
a, n:t
Hn:0 <= n
LT:0 < a
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
EQ:a == 0

0 == 0 \/ 0 < 0 /\ log2 0 < n -> 0 <= 0 < 2 ^ n \/ 2 ^ n < 0 <= 0
a, n:t
Hn:0 <= n
LT:0 < a
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
EQ:a == 0

0 <= 0 < 2 ^ n
a, n:t
Hn:0 <= n
LT:0 < a
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a

0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a

0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 -> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
H:0 <= a
H':a < 2 ^ n

0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
H:2 ^ n < a
H':a <= 0
0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
H:0 <= a
H':a < 2 ^ n

log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
H:2 ^ n < a
H':a <= 0
0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
H:2 ^ n < a
H':a <= 0

0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a

a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT:0 < a
H:a == 0

0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:0 <= n
LT, H:0 < a
H':log2 a < n
0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT, H:0 < a
H':log2 a < n

0 <= a < 2 ^ n \/ 2 ^ n < a <= 0
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT, H:0 < a
H':log2 a < n

0 <= a < 2 ^ n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT, H:0 < a
H':log2 a < n

0 <= a
a, n:t
Hn:0 <= n
LT, H:0 < a
H':log2 a < n
a < 2 ^ n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:0 <= n
LT, H:0 < a
H':log2 a < n

a < 2 ^ n
a, n:t
Hn:n < 0
a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0

a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0

a * 2 ^ (- n) == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0

a == 0 \/ 2 ^ (- n) == 0 <-> a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
H:a == 0

a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
H:2 ^ (- n) == 0
a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
H:a == 0
a == 0 \/ 2 ^ (- n) == 0
a, n:t
Hn:n < 0
H:0 < a /\ log2 a < n
a == 0 \/ 2 ^ (- n) == 0
a, n:t
Hn:n < 0
H:2 ^ (- n) == 0

a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Hn:n < 0
H:a == 0
a == 0 \/ 2 ^ (- n) == 0
a, n:t
Hn:n < 0
H:0 < a /\ log2 a < n
a == 0 \/ 2 ^ (- n) == 0
a, n:t
Hn:n < 0
H:a == 0

a == 0 \/ 2 ^ (- n) == 0
a, n:t
Hn:n < 0
H:0 < a /\ log2 a < n
a == 0 \/ 2 ^ (- n) == 0
a, n:t
Hn:n < 0
H:0 < a /\ log2 a < n

a == 0 \/ 2 ^ (- n) == 0
a, n:t
Hn:n < 0
H:0 < a
H0:log2 a < n

a == 0 \/ 2 ^ (- n) == 0
generalize (log2_nonneg a); order. Qed.

forall a n : t, 0 <= a -> log2 a < n -> a >> n == 0

forall a n : t, 0 <= a -> log2 a < n -> a >> n == 0
a, n:t
Ha:0 <= a
H:log2 a < n

a >> n == 0
a, n:t
Ha:0 <= a
H:log2 a < n

a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Ha:0 < a
H:log2 a < n

a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Ha:0 == a
H:log2 a < n
a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Ha:0 < a
H:log2 a < n

0 < a /\ log2 a < n
a, n:t
Ha:0 == a
H:log2 a < n
a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Ha:0 == a
H:log2 a < n

a == 0 \/ 0 < a /\ log2 a < n
now left. Qed.
Properties of div2.

forall a : t, div2 a == a / 2

forall a : t, div2 a == a / 2
a:t

div2 a == a / 2
a:t

a / 2 ^ 1 == a / 2
a:t
0 <= 1
a:t

0 <= 1
order'. Qed.

Proper (eq ==> eq) div2

Proper (eq ==> eq) div2
a, a':t
Ha:a == a'

div2 a == div2 a'
now rewrite 2 div2_div, Ha. Qed.

forall a : t, a == 2 * div2 a + odd a

forall a : t, a == 2 * div2 a + odd a
a:t

a == 2 * div2 a + odd a
a:t

a == 2 * (a / 2) + a mod 2
a:t

2 ~= 0
order'. Qed.
Properties of lxor and others, directly deduced from properties of xorb and others.

Proper (eq ==> eq ==> eq) lxor

Proper (eq ==> eq ==> eq) lxor
a, a':t
Ha:a == a'
b, b':t
Hb:b == b'

lxor a b == lxor a' b'
a, a':t
Ha:a == a'
b, b':t
Hb:b == b'
m:t
Hm:0 <= m

xorb a.[m] b.[m] = xorb a'.[m] b'.[m]
now rewrite Ha, Hb. Qed.

Proper (eq ==> eq ==> eq) land

Proper (eq ==> eq ==> eq) land
a, a':t
Ha:a == a'
b, b':t
Hb:b == b'

land a b == land a' b'
a, a':t
Ha:a == a'
b, b':t
Hb:b == b'
m:t
Hm:0 <= m

a.[m] && b.[m] = a'.[m] && b'.[m]
now rewrite Ha, Hb. Qed.

Proper (eq ==> eq ==> eq) lor

Proper (eq ==> eq ==> eq) lor
a, a':t
Ha:a == a'
b, b':t
Hb:b == b'

lor a b == lor a' b'
a, a':t
Ha:a == a'
b, b':t
Hb:b == b'
m:t
Hm:0 <= m

a.[m] || b.[m] = a'.[m] || b'.[m]
now rewrite Ha, Hb. Qed.

Proper (eq ==> eq ==> eq) ldiff

Proper (eq ==> eq ==> eq) ldiff
a, a':t
Ha:a == a'
b, b':t
Hb:b == b'

ldiff a b == ldiff a' b'
a, a':t
Ha:a == a'
b, b':t
Hb:b == b'
m:t
Hm:0 <= m

a.[m] && negb b.[m] = a'.[m] && negb b'.[m]
now rewrite Ha, Hb. Qed.

forall a a' : t, lxor a a' == 0 -> a == a'

forall a a' : t, lxor a a' == 0 -> a == a'
a, a':t
H:lxor a a' == 0

a == a'
a, a':t
H:lxor a a' == 0
m:t
Hm:0 <= m

a.[m] = a'.[m]
a, a':t
H:lxor a a' == 0
m:t
Hm:0 <= m

xorb a.[m] a'.[m] = false
now rewrite <- lxor_spec, H, bits_0. Qed.

forall a : t, lxor a a == 0

forall a : t, lxor a a == 0
a:t

lxor a a == 0
a, m:t
Hm:0 <= m

xorb a.[m] a.[m] = false
apply xorb_nilpotent. Qed.

forall a a' : t, lxor a a' == 0 <-> a == a'

forall a a' : t, lxor a a' == 0 <-> a == a'
a, a':t

lxor a a' == 0 -> a == a'
a, a':t
a == a' -> lxor a a' == 0
a, a':t

a == a' -> lxor a a' == 0
intros EQ; rewrite EQ; apply lxor_nilpotent. Qed.

forall a : t, lxor 0 a == a

forall a : t, lxor 0 a == a
a:t

lxor 0 a == a
a, m:t
Hm:0 <= m

xorb false a.[m] = a.[m]
apply xorb_false_l. Qed.

forall a : t, lxor a 0 == a

forall a : t, lxor a 0 == a
a:t

lxor a 0 == a
a, m:t
Hm:0 <= m

xorb a.[m] false = a.[m]
apply xorb_false_r. Qed.

forall a b : t, lxor a b == lxor b a

forall a b : t, lxor a b == lxor b a
a, b:t

lxor a b == lxor b a
a, b, m:t
Hm:0 <= m

xorb a.[m] b.[m] = xorb b.[m] a.[m]
apply xorb_comm. Qed.

forall a b c : t, lxor (lxor a b) c == lxor a (lxor b c)

forall a b c : t, lxor (lxor a b) c == lxor a (lxor b c)
a, b, c:t

lxor (lxor a b) c == lxor a (lxor b c)
a, b, c, m:t
Hm:0 <= m

xorb (xorb a.[m] b.[m]) c.[m] = xorb a.[m] (xorb b.[m] c.[m])
apply xorb_assoc. Qed.

forall a : t, lor 0 a == a

forall a : t, lor 0 a == a
a:t

lor 0 a == a
a, m:t
Hm:0 <= m

false || a.[m] = a.[m]
trivial. Qed.

forall a : t, lor a 0 == a

forall a : t, lor a 0 == a
a:t

lor a 0 == a
a, m:t
Hm:0 <= m

a.[m] || false = a.[m]
apply orb_false_r. Qed.

forall a b : t, lor a b == lor b a

forall a b : t, lor a b == lor b a
a, b:t

lor a b == lor b a
a, b, m:t
Hm:0 <= m

a.[m] || b.[m] = b.[m] || a.[m]
apply orb_comm. Qed.

forall a b c : t, lor a (lor b c) == lor (lor a b) c

forall a b c : t, lor a (lor b c) == lor (lor a b) c
a, b, c:t

lor a (lor b c) == lor (lor a b) c
a, b, c, m:t
Hm:0 <= m

a.[m] || (b.[m] || c.[m]) = a.[m] || b.[m] || c.[m]
apply orb_assoc. Qed.

forall a : t, lor a a == a

forall a : t, lor a a == a
a:t

lor a a == a
a, m:t
Hm:0 <= m

a.[m] || a.[m] = a.[m]
apply orb_diag. Qed.

forall a b : t, lor a b == 0 -> a == 0

forall a b : t, lor a b == 0 -> a == 0
a, b:t
H:lor a b == 0

a == 0
a, b:t
H:lor a b == 0
m:t
Hm:0 <= m

a.[m] = false
a, b:t
H:lor a b == 0
m:t
Hm:0 <= m

a.[m] || b.[m] = false
now rewrite <- lor_spec, H, bits_0. Qed.

forall a b : t, lor a b == 0 <-> a == 0 /\ b == 0

forall a b : t, lor a b == 0 <-> a == 0 /\ b == 0
a, b:t

lor a b == 0 <-> a == 0 /\ b == 0
a, b:t

lor a b == 0 -> a == 0 /\ b == 0
a, b:t
a == 0 /\ b == 0 -> lor a b == 0
a, b:t
H:lor a b == 0

a == 0
a, b:t
H:lor a b == 0
b == 0
a, b:t
a == 0 /\ b == 0 -> lor a b == 0
a, b:t
H:lor a b == 0

b == 0
a, b:t
a == 0 /\ b == 0 -> lor a b == 0
a, b:t
H:lor b a == 0

b == 0
a, b:t
a == 0 /\ b == 0 -> lor a b == 0
a, b:t

a == 0 /\ b == 0 -> lor a b == 0
a, b:t
EQ:a == 0
EQ':b == 0

lor a b == 0
now rewrite EQ, lor_0_l. Qed.

forall a : t, land 0 a == 0

forall a : t, land 0 a == 0
a:t

land 0 a == 0
a, m:t
Hm:0 <= m

false && a.[m] = false
trivial. Qed.

forall a : t, land a 0 == 0

forall a : t, land a 0 == 0
a:t

land a 0 == 0
a, m:t
Hm:0 <= m

a.[m] && false = false
apply andb_false_r. Qed.

forall a b : t, land a b == land b a

forall a b : t, land a b == land b a
a, b:t

land a b == land b a
a, b, m:t
Hm:0 <= m

a.[m] && b.[m] = b.[m] && a.[m]
apply andb_comm. Qed.

forall a b c : t, land a (land b c) == land (land a b) c

forall a b c : t, land a (land b c) == land (land a b) c
a, b, c:t

land a (land b c) == land (land a b) c
a, b, c, m:t
Hm:0 <= m

a.[m] && (b.[m] && c.[m]) = a.[m] && b.[m] && c.[m]
apply andb_assoc. Qed.

forall a : t, land a a == a

forall a : t, land a a == a
a:t

land a a == a
a, m:t
Hm:0 <= m

a.[m] && a.[m] = a.[m]
apply andb_diag. Qed.

forall a : t, ldiff 0 a == 0

forall a : t, ldiff 0 a == 0
a:t

ldiff 0 a == 0
a, m:t
Hm:0 <= m

false && negb a.[m] = false
trivial. Qed.

forall a : t, ldiff a 0 == a

forall a : t, ldiff a 0 == a
a:t

ldiff a 0 == a
a, m:t
Hm:0 <= m

a.[m] && negb false = a.[m]
now rewrite andb_true_r. Qed.

forall a : t, ldiff a a == 0

forall a : t, ldiff a a == 0
a:t

ldiff a a == 0
a, m:t
Hm:0 <= m

a.[m] && negb a.[m] = false
apply andb_negb_r. Qed.

forall a b c : t, lor (land a b) c == land (lor a c) (lor b c)

forall a b c : t, lor (land a b) c == land (lor a c) (lor b c)
a, b, c:t

lor (land a b) c == land (lor a c) (lor b c)
a, b, c, m:t
Hm:0 <= m

a.[m] && b.[m] || c.[m] = (a.[m] || c.[m]) && (b.[m] || c.[m])
apply orb_andb_distrib_l. Qed.

forall a b c : t, lor a (land b c) == land (lor a b) (lor a c)

forall a b c : t, lor a (land b c) == land (lor a b) (lor a c)
a, b, c:t

lor a (land b c) == land (lor a b) (lor a c)
a, b, c, m:t
Hm:0 <= m

a.[m] || b.[m] && c.[m] = (a.[m] || b.[m]) && (a.[m] || c.[m])
apply orb_andb_distrib_r. Qed.

forall a b c : t, land (lor a b) c == lor (land a c) (land b c)

forall a b c : t, land (lor a b) c == lor (land a c) (land b c)
a, b, c:t

land (lor a b) c == lor (land a c) (land b c)
a, b, c, m:t
Hm:0 <= m

(a.[m] || b.[m]) && c.[m] = a.[m] && c.[m] || b.[m] && c.[m]
apply andb_orb_distrib_l. Qed.

forall a b c : t, land a (lor b c) == lor (land a b) (land a c)

forall a b c : t, land a (lor b c) == lor (land a b) (land a c)
a, b, c:t

land a (lor b c) == lor (land a b) (land a c)
a, b, c, m:t
Hm:0 <= m

a.[m] && (b.[m] || c.[m]) = a.[m] && b.[m] || a.[m] && c.[m]
apply andb_orb_distrib_r. Qed.

forall a b c : t, ldiff (ldiff a b) c == ldiff a (lor b c)

forall a b c : t, ldiff (ldiff a b) c == ldiff a (lor b c)
a, b, c:t

ldiff (ldiff a b) c == ldiff a (lor b c)
a, b, c, m:t
Hm:0 <= m

a.[m] && negb b.[m] && negb c.[m] = a.[m] && negb (b.[m] || c.[m])
now rewrite negb_orb, andb_assoc. Qed.

forall a b : t, lor (ldiff a b) (land a b) == a

forall a b : t, lor (ldiff a b) (land a b) == a
a, b:t

lor (ldiff a b) (land a b) == a
a, b, m:t
Hm:0 <= m

a.[m] && negb b.[m] || a.[m] && b.[m] = a.[m]
now rewrite <- andb_orb_distrib_r, orb_comm, orb_negb_r, andb_true_r. Qed.

forall a b : t, land (ldiff a b) b == 0

forall a b : t, land (ldiff a b) b == 0
a, b:t

land (ldiff a b) b == 0
a, b, m:t
Hm:0 <= m

a.[m] && negb b.[m] && b.[m] = false
now rewrite <-andb_assoc, (andb_comm (negb _)), andb_negb_r, andb_false_r. Qed.
Properties of setbit and clearbit
Definition setbit a n := lor a (1 << n).
Definition clearbit a n := ldiff a (1 << n).


forall a n : t, setbit a n == lor a (2 ^ n)

forall a n : t, setbit a n == lor a (2 ^ n)
a, n:t

setbit a n == lor a (2 ^ n)
a, n:t

lor a (1 << n) == lor a (2 ^ n)
now rewrite shiftl_1_l. Qed.

forall a n : t, clearbit a n == ldiff a (2 ^ n)

forall a n : t, clearbit a n == ldiff a (2 ^ n)
a, n:t

clearbit a n == ldiff a (2 ^ n)
a, n:t

ldiff a (1 << n) == ldiff a (2 ^ n)
now rewrite shiftl_1_l. Qed.

Proper (eq ==> eq ==> eq) setbit

Proper (eq ==> eq ==> eq) setbit

Proper (eq ==> eq ==> eq) (fun a n : t => lor a (1 << n))
solve_proper. Qed.

Proper (eq ==> eq ==> eq) clearbit

Proper (eq ==> eq ==> eq) clearbit

Proper (eq ==> eq ==> eq) (fun a n : t => ldiff a (1 << n))
solve_proper. Qed.

forall n : t, 0 <= n -> (2 ^ n).[n] = true

forall n : t, 0 <= n -> (2 ^ n).[n] = true
n:t
H:0 <= n

(2 ^ n).[n] = true
n:t
H:0 <= n

(1 * 2 ^ n).[n] = true
now rewrite mul_pow2_bits, sub_diag, bit0_odd, odd_1. Qed.

forall n m : t, n ~= m -> (2 ^ n).[m] = false

forall n m : t, n ~= m -> (2 ^ n).[m] = false
n, m:t
H:n ~= m

(2 ^ n).[m] = false
n, m:t
H:n ~= m
H0:0 <= n

(2 ^ n).[m] = false
n, m:t
H:n ~= m
H0:0 <= n
H1:n <= m

(2 ^ n).[m] = false
n, m:t
H:n ~= m
H0:0 <= n
H1:m < n
(2 ^ n).[m] = false
n, m:t
H:n ~= m
H0:0 <= n
H1:n <= m

1.[m - n] = false
n, m:t
H:n ~= m
H0:0 <= n
H1:m < n
(2 ^ n).[m] = false
n, m:t
H:n ~= m
H0:0 <= n
H1:n <= m

(1 / 2).[P (m - n)] = false
n, m:t
H:n ~= m
H0:0 <= n
H1:n <= m
0 <= P (m - n)
n, m:t
H:n ~= m
H0:0 <= n
H1:m < n
(2 ^ n).[m] = false
n, m:t
H:n ~= m
H0:0 <= n
H1:n <= m

0 <= P (m - n)
n, m:t
H:n ~= m
H0:0 <= n
H1:m < n
(2 ^ n).[m] = false
n, m:t
H:n ~= m
H0:0 <= n
H1:n <= m

n < m
n, m:t
H:n ~= m
H0:0 <= n
H1:m < n
(2 ^ n).[m] = false
n, m:t
H:n ~= m
H0:0 <= n
H1:m < n

(2 ^ n).[m] = false
rewrite <- (mul_1_l (2^n)), mul_pow2_bits_low; trivial. Qed.

forall n m : t, 0 <= n -> (2 ^ n).[m] = (n =? m)

forall n m : t, 0 <= n -> (2 ^ n).[m] = (n =? m)
n, m:t
Hn:0 <= n

(2 ^ n).[m] = (n =? m)
n, m:t
Hn:0 <= n

(2 ^ n).[m] = true <-> (n =? m) = true
n, m:t
Hn:0 <= n

(2 ^ n).[m] = true <-> n == m
n, m:t
Hn:0 <= n

(2 ^ n).[m] = true -> n == m
n, m:t
Hn:0 <= n
n == m -> (2 ^ n).[m] = true
n, m:t
Hn:0 <= n
H:n == m

(2 ^ n).[m] = true -> n == m
n, m:t
Hn:0 <= n
H:n ~= m
(2 ^ n).[m] = true -> n == m
n, m:t
Hn:0 <= n
n == m -> (2 ^ n).[m] = true
n, m:t
Hn:0 <= n
H:n ~= m

(2 ^ n).[m] = true -> n == m
n, m:t
Hn:0 <= n
n == m -> (2 ^ n).[m] = true
n, m:t
Hn:0 <= n

n == m -> (2 ^ n).[m] = true
n, m:t
Hn:0 <= n
EQ:n == m

(2 ^ n).[m] = true
n, m:t
Hn:0 <= n
EQ:n == m

(2 ^ m).[m] = true
apply pow2_bits_true; order. Qed.

forall a n m : t, 0 <= n -> (setbit a n).[m] = (n =? m) || a.[m]

forall a n m : t, 0 <= n -> (setbit a n).[m] = (n =? m) || a.[m]
a, n, m:t
H:0 <= n

(setbit a n).[m] = (n =? m) || a.[m]
now rewrite setbit_spec', lor_spec, pow2_bits_eqb, orb_comm. Qed.

forall a n m : t, 0 <= n -> (setbit a n).[m] = true <-> n == m \/ a.[m] = true

forall a n m : t, 0 <= n -> (setbit a n).[m] = true <-> n == m \/ a.[m] = true
a, n, m:t
H:0 <= n

(setbit a n).[m] = true <-> n == m \/ a.[m] = true
now rewrite setbit_eqb, orb_true_iff, eqb_eq. Qed.

forall a n : t, 0 <= n -> (setbit a n).[n] = true

forall a n : t, 0 <= n -> (setbit a n).[n] = true
a, n:t
H:0 <= n

(setbit a n).[n] = true
a, n:t
H:0 <= n

n == n \/ a.[n] = true
now left. Qed.

forall a n m : t, 0 <= n -> n ~= m -> (setbit a n).[m] = a.[m]

forall a n m : t, 0 <= n -> n ~= m -> (setbit a n).[m] = a.[m]
a, n, m:t
Hn:0 <= n
H:n ~= m

(setbit a n).[m] = a.[m]
a, n, m:t
Hn:0 <= n
H:n ~= m

(n =? m) || a.[m] = a.[m]
a, n, m:t
Hn:0 <= n
H:(n =? m) <> true

(n =? m) || a.[m] = a.[m]
a, n, m:t
Hn:0 <= n
H:(n =? m) = false

(n =? m) || a.[m] = a.[m]
now rewrite H. Qed.

forall a n m : t, (clearbit a n).[m] = a.[m] && negb (n =? m)

forall a n m : t, (clearbit a n).[m] = a.[m] && negb (n =? m)
a, n, m:t

(clearbit a n).[m] = a.[m] && negb (n =? m)
a, n, m:t
H:0 <= m

(clearbit a n).[m] = a.[m] && negb (n =? m)
a, n, m:t
H:0 <= m

a.[m] && negb (2 ^ n).[m] = a.[m] && negb (n =? m)
a, n, m:t
H:0 <= m

negb (2 ^ n).[m] = negb (n =? m)
a, n, m:t
H:0 <= m

(2 ^ n).[m] = (n =? m)
a, n, m:t
H:0 <= m
Hn:0 <= n

(2 ^ n).[m] = (n =? m)
a, n, m:t
H:0 <= m
Hn:n < 0
(2 ^ n).[m] = (n =? m)
a, n, m:t
H:0 <= m
Hn:n < 0

(2 ^ n).[m] = (n =? m)
a, n, m:t
H:0 <= m
Hn:n < 0

(n =? m) = (2 ^ n).[m]
rewrite pow_neg_r, bits_0, <- not_true_iff_false, eqb_eq; order. Qed.

forall a n m : t, (clearbit a n).[m] = true <-> a.[m] = true /\ n ~= m

forall a n m : t, (clearbit a n).[m] = true <-> a.[m] = true /\ n ~= m
a, n, m:t

(clearbit a n).[m] = true <-> a.[m] = true /\ n ~= m
a, n, m:t

a.[m] = true /\ negb (n =? m) = true <-> a.[m] = true /\ (n =? m) <> true
now rewrite negb_true_iff, not_true_iff_false. Qed.

forall a n : t, (clearbit a n).[n] = false

forall a n : t, (clearbit a n).[n] = false
a, n:t

(clearbit a n).[n] = false
a, n:t

a.[n] && negb true = false
apply andb_false_r. Qed.

forall a n m : t, n ~= m -> (clearbit a n).[m] = a.[m]

forall a n m : t, n ~= m -> (clearbit a n).[m] = a.[m]
a, n, m:t
H:n ~= m

(clearbit a n).[m] = a.[m]
a, n, m:t
H:n ~= m

a.[m] && negb (n =? m) = a.[m]
a, n, m:t
H:(n =? m) <> true

a.[m] && negb (n =? m) = a.[m]
a, n, m:t
H:(n =? m) = false

a.[m] && negb (n =? m) = a.[m]
a, n, m:t
H:(n =? m) = false

a.[m] && negb false = a.[m]
apply andb_true_r. Qed.
Shifts of bitwise operations

forall a b n : t, lxor a b << n == lxor (a << n) (b << n)

forall a b n : t, lxor a b << n == lxor (a << n) (b << n)
a, b, n:t

lxor a b << n == lxor (a << n) (b << n)
a, b, n, m:t
Hm:0 <= m

(lxor a b << n).[m] = xorb (a << n).[m] (b << n).[m]
now rewrite !shiftl_spec, lxor_spec. Qed.

forall a b n : t, lxor a b >> n == lxor (a >> n) (b >> n)

forall a b n : t, lxor a b >> n == lxor (a >> n) (b >> n)
a, b, n:t

lxor a b >> n == lxor (a >> n) (b >> n)
a, b, n, m:t
Hm:0 <= m

(lxor a b >> n).[m] = xorb (a >> n).[m] (b >> n).[m]
now rewrite !shiftr_spec, lxor_spec. Qed.

forall a b n : t, land a b << n == land (a << n) (b << n)

forall a b n : t, land a b << n == land (a << n) (b << n)
a, b, n:t

land a b << n == land (a << n) (b << n)
a, b, n, m:t
Hm:0 <= m

(land a b << n).[m] = (a << n).[m] && (b << n).[m]
now rewrite !shiftl_spec, land_spec. Qed.

forall a b n : t, land a b >> n == land (a >> n) (b >> n)

forall a b n : t, land a b >> n == land (a >> n) (b >> n)
a, b, n:t

land a b >> n == land (a >> n) (b >> n)
a, b, n, m:t
Hm:0 <= m

(land a b >> n).[m] = (a >> n).[m] && (b >> n).[m]
now rewrite !shiftr_spec, land_spec. Qed.

forall a b n : t, lor a b << n == lor (a << n) (b << n)

forall a b n : t, lor a b << n == lor (a << n) (b << n)
a, b, n:t

lor a b << n == lor (a << n) (b << n)
a, b, n, m:t
Hm:0 <= m

(lor a b << n).[m] = (a << n).[m] || (b << n).[m]
now rewrite !shiftl_spec, lor_spec. Qed.

forall a b n : t, lor a b >> n == lor (a >> n) (b >> n)

forall a b n : t, lor a b >> n == lor (a >> n) (b >> n)
a, b, n:t

lor a b >> n == lor (a >> n) (b >> n)
a, b, n, m:t
Hm:0 <= m

(lor a b >> n).[m] = (a >> n).[m] || (b >> n).[m]
now rewrite !shiftr_spec, lor_spec. Qed.

forall a b n : t, ldiff a b << n == ldiff (a << n) (b << n)

forall a b n : t, ldiff a b << n == ldiff (a << n) (b << n)
a, b, n:t

ldiff a b << n == ldiff (a << n) (b << n)
a, b, n, m:t
Hm:0 <= m

(ldiff a b << n).[m] = (a << n).[m] && negb (b << n).[m]
now rewrite !shiftl_spec, ldiff_spec. Qed.

forall a b n : t, ldiff a b >> n == ldiff (a >> n) (b >> n)

forall a b n : t, ldiff a b >> n == ldiff (a >> n) (b >> n)
a, b, n:t

ldiff a b >> n == ldiff (a >> n) (b >> n)
a, b, n, m:t
Hm:0 <= m

(ldiff a b >> n).[m] = (a >> n).[m] && negb (b >> n).[m]
now rewrite !shiftr_spec, ldiff_spec. Qed.
For integers, we do have a binary complement function
Definition lnot a := P (-a).


Proper (eq ==> eq) lnot

Proper (eq ==> eq) lnot

Proper (eq ==> eq) (fun a : t => P (- a))
solve_proper. Qed.

forall a n : t, 0 <= n -> (lnot a).[n] = negb a.[n]

forall a n : t, 0 <= n -> (lnot a).[n] = negb a.[n]
a, n:t
H:0 <= n

(lnot a).[n] = negb a.[n]
a, n:t
H:0 <= n

(P (- a)).[n] = negb a.[n]
a, n:t
H:0 <= n

(P (- a)).[n] = negb (- - a).[n]
rewrite bits_opp, negb_involutive; trivial. Qed.

forall a : t, lnot (lnot a) == a

forall a : t, lnot (lnot a) == a
a:t

lnot (lnot a) == a
a, m:t
Hm:0 <= m

(lnot (lnot a)).[m] = a.[m]
now rewrite 2 lnot_spec, negb_involutive. Qed.

lnot 0 == -1

lnot 0 == -1

P (- 0) == -1
now rewrite opp_0, <- sub_1_r, sub_0_l. Qed.

lnot (-1) == 0

lnot (-1) == 0

P (- -1) == 0
now rewrite opp_involutive, one_succ, pred_succ. Qed.
Complement and other operations

forall a : t, lor a (-1) == -1

forall a : t, lor a (-1) == -1
a:t

lor a (-1) == -1
a, m:t
Hm:0 <= m

a.[m] || (-1).[m] = (-1).[m]
now rewrite bits_m1, orb_true_r. Qed.

forall a : t, lor (-1) a == -1

forall a : t, lor (-1) a == -1
a:t

lor (-1) a == -1
now rewrite lor_comm, lor_m1_r. Qed.

forall a : t, land a (-1) == a

forall a : t, land a (-1) == a
a:t

land a (-1) == a
a, m:t
Hm:0 <= m

a.[m] && (-1).[m] = a.[m]
now rewrite bits_m1, andb_true_r. Qed.

forall a : t, land (-1) a == a

forall a : t, land (-1) a == a
a:t

land (-1) a == a
now rewrite land_comm, land_m1_r. Qed.

forall a : t, ldiff a (-1) == 0

forall a : t, ldiff a (-1) == 0
a:t

ldiff a (-1) == 0
a, m:t
Hm:0 <= m

a.[m] && negb (-1).[m] = false
now rewrite bits_m1, andb_false_r. Qed.

forall a : t, ldiff (-1) a == lnot a

forall a : t, ldiff (-1) a == lnot a
a:t

ldiff (-1) a == lnot a
a, m:t
Hm:0 <= m

(-1).[m] && negb a.[m] = (lnot a).[m]
now rewrite lnot_spec, bits_m1. Qed.

forall a : t, lor a (lnot a) == -1

forall a : t, lor a (lnot a) == -1
a:t

lor a (lnot a) == -1
a, m:t
Hm:0 <= m

a.[m] || (lnot a).[m] = (-1).[m]
a, m:t
Hm:0 <= m

a.[m] || negb a.[m] = true
now destruct a.[m]. Qed.

forall a : t, a + lnot a == -1

forall a : t, a + lnot a == -1
a:t

a + lnot a == -1
a:t

a + P (- a) == -1
now rewrite add_pred_r, add_opp_r, sub_diag, one_succ, opp_succ, opp_0. Qed.

forall a b : t, ldiff a b == land a (lnot b)

forall a b : t, ldiff a b == land a (lnot b)
a, b:t

ldiff a b == land a (lnot b)
a, b, m:t
Hm:0 <= m

a.[m] && negb b.[m] = a.[m] && (lnot b).[m]
now rewrite lnot_spec. Qed.

forall a : t, land a (lnot a) == 0

forall a : t, land a (lnot a) == 0
a:t

land a (lnot a) == 0
now rewrite <- ldiff_land, ldiff_diag. Qed.

forall a b : t, lnot (lor a b) == land (lnot a) (lnot b)

forall a b : t, lnot (lor a b) == land (lnot a) (lnot b)
a, b:t

lnot (lor a b) == land (lnot a) (lnot b)
a, b, m:t
Hm:0 <= m

(lnot (lor a b)).[m] = (lnot a).[m] && (lnot b).[m]
now rewrite !lnot_spec, lor_spec, negb_orb. Qed.

forall a b : t, lnot (land a b) == lor (lnot a) (lnot b)

forall a b : t, lnot (land a b) == lor (lnot a) (lnot b)
a, b:t

lnot (land a b) == lor (lnot a) (lnot b)
a, b, m:t
Hm:0 <= m

(lnot (land a b)).[m] = (lnot a).[m] || (lnot b).[m]
now rewrite !lnot_spec, land_spec, negb_andb. Qed.

forall a b : t, lnot (ldiff a b) == lor (lnot a) b

forall a b : t, lnot (ldiff a b) == lor (lnot a) b
a, b:t

lnot (ldiff a b) == lor (lnot a) b
a, b, m:t
Hm:0 <= m

(lnot (ldiff a b)).[m] = (lnot a).[m] || b.[m]
now rewrite !lnot_spec, ldiff_spec, negb_andb, negb_involutive. Qed.

forall a b : t, lxor (lnot a) (lnot b) == lxor a b

forall a b : t, lxor (lnot a) (lnot b) == lxor a b
a, b:t

lxor (lnot a) (lnot b) == lxor a b
a, b, m:t
Hm:0 <= m

xorb (lnot a).[m] (lnot b).[m] = xorb a.[m] b.[m]
now rewrite !lnot_spec, xorb_negb_negb. Qed.

forall a b : t, lnot (lxor a b) == lxor (lnot a) b

forall a b : t, lnot (lxor a b) == lxor (lnot a) b
a, b:t

lnot (lxor a b) == lxor (lnot a) b
a, b, m:t
Hm:0 <= m

(lnot (lxor a b)).[m] = xorb (lnot a).[m] b.[m]
now rewrite !lnot_spec, !lxor_spec, negb_xorb_l. Qed.

forall a b : t, lnot (lxor a b) == lxor a (lnot b)

forall a b : t, lnot (lxor a b) == lxor a (lnot b)
a, b:t

lnot (lxor a b) == lxor a (lnot b)
a, b, m:t
Hm:0 <= m

(lnot (lxor a b)).[m] = xorb a.[m] (lnot b).[m]
now rewrite !lnot_spec, !lxor_spec, negb_xorb_r. Qed.

forall a : t, lxor a (-1) == lnot a

forall a : t, lxor a (-1) == lnot a
a:t

lxor a (-1) == lnot a
now rewrite <- (lxor_0_r (lnot a)), <- lnot_m1, lxor_lnot_lnot. Qed.

forall a : t, lxor (-1) a == lnot a

forall a : t, lxor (-1) a == lnot a
a:t

lxor (-1) a == lnot a
now rewrite lxor_comm, lxor_m1_r. Qed.

forall a b : t, land a b == 0 -> lxor a b == lor a b

forall a b : t, land a b == 0 -> lxor a b == lor a b
a, b:t
H:land a b == 0

lxor a b == lor a b
a, b:t
H:land a b == 0
m:t
Hm:0 <= m

xorb a.[m] b.[m] = a.[m] || b.[m]
a, b:t
H:land a b == 0
m:t
Hm:0 <= m
H0:a.[m] && b.[m] = false

xorb a.[m] b.[m] = a.[m] || b.[m]
now destruct a.[m], b.[m]. Qed.

forall a n : t, 0 <= n -> lnot (a >> n) == lnot a >> n

forall a n : t, 0 <= n -> lnot (a >> n) == lnot a >> n
a, n:t
Hn:0 <= n

lnot (a >> n) == lnot a >> n
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m

(lnot (a >> n)).[m] = (lnot a >> n).[m]
now rewrite lnot_spec, 2 shiftr_spec, lnot_spec by order_pos. Qed.
(ones n) is 2^n-1, the number with n digits 1
Definition ones n := P (1<<n).


Proper (eq ==> eq) ones

Proper (eq ==> eq) ones

Proper (eq ==> eq) (fun n : t => P (1 << n))
solve_proper. Qed.

forall n : t, ones n == P (2 ^ n)

forall n : t, ones n == P (2 ^ n)
n:t

ones n == P (2 ^ n)
n:t

P (1 << n) == P (2 ^ n)
n:t
H:0 <= n

P (1 << n) == P (2 ^ n)
n:t
H:n < 0
P (1 << n) == P (2 ^ n)
n:t
H:n < 0

P (1 << n) == P (2 ^ n)
n:t
H:n < 0

1 << n == 2 ^ n
n:t
H:n < 0

1 << n == 0
n:t
H:n < 0

1 >> (- n) == 0
n:t
H:n < 0

1 == 0 \/ 0 < 1 /\ log2 1 < - n
n:t
H:n < 0

0 < 1
n:t
H:n < 0
log2 1 < - n
n:t
H:n < 0

log2 1 < - n
n:t
H:n < 0

0 < - n
now apply opp_pos_neg. Qed.

forall n m : t, 0 <= n -> 0 <= m -> ones (m + n) == 2 ^ m * ones n + ones m

forall n m : t, 0 <= n -> 0 <= m -> ones (m + n) == 2 ^ m * ones n + ones m
n, m:t
Hn:0 <= n
Hm:0 <= m

ones (m + n) == 2 ^ m * ones n + ones m
n, m:t
Hn:0 <= n
Hm:0 <= m

P (2 ^ (m + n)) == 2 ^ m * P (2 ^ n) + P (2 ^ m)
n, m:t
Hn:0 <= n
Hm:0 <= m

2 ^ (m + n) - 1 == 2 ^ (m + n) - 2 ^ m + (2 ^ m - 1)
n, m:t
Hn:0 <= n
Hm:0 <= m

2 ^ (m + n) - 1 == 2 ^ (m + n) - 1
reflexivity. Qed.

forall n m : t, 0 <= m <= n -> ones n / 2 ^ m == ones (n - m)

forall n m : t, 0 <= m <= n -> ones n / 2 ^ m == ones (n - m)
n, m:t
Hm:0 <= m
H:m <= n

ones n / 2 ^ m == ones (n - m)
n, m:t
Hm:0 <= m
H:m <= n

ones (n - m) == ones n / 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n

0 <= ones m < 2 ^ m \/ 2 ^ m < ones m <= 0
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

0 <= ones m < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

0 <= P (2 ^ m) < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

0 <= P (2 ^ m)
n, m:t
Hm:0 <= m
H:m <= n
P (2 ^ m) < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

0 < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
P (2 ^ m) < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

P (2 ^ m) < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

ones (n - m + m) == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

ones (m + (n - m)) == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

0 <= n - m
now apply le_0_sub. Qed.

forall n m : t, 0 <= m <= n -> ones n mod 2 ^ m == ones m

forall n m : t, 0 <= m <= n -> ones n mod 2 ^ m == ones m
n, m:t
Hm:0 <= m
H:m <= n

ones n mod 2 ^ m == ones m
n, m:t
Hm:0 <= m
H:m <= n

ones m == ones n mod 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n

0 <= ones m < 2 ^ m \/ 2 ^ m < ones m <= 0
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

0 <= ones m < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

0 <= P (2 ^ m) < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

0 <= P (2 ^ m)
n, m:t
Hm:0 <= m
H:m <= n
P (2 ^ m) < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

0 < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
P (2 ^ m) < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

P (2 ^ m) < 2 ^ m
n, m:t
Hm:0 <= m
H:m <= n
ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

ones n == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

ones (n - m + m) == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

ones (m + (n - m)) == 2 ^ m * ones (n - m) + ones m
n, m:t
Hm:0 <= m
H:m <= n

0 <= n - m
now apply le_0_sub. Qed.

forall n m : t, 0 <= m < n -> (ones n).[m] = true

forall n m : t, 0 <= m < n -> (ones n).[m] = true
n, m:t
Hm:0 <= m
H:m < n

(ones n).[m] = true
n, m:t
Hm:0 <= m
H:m < n

(ones n / 2 ^ m) mod 2 == 1
n, m:t
Hm:0 <= m
H:m < n

ones (n - m) mod 2 == 1
n, m:t
Hm:0 <= m
H:m < n

ones (n - m) mod 2 ^ 1 == 1
n, m:t
Hm:0 <= m
H:m < n

ones 1 == 1
n, m:t
Hm:0 <= m
H:m < n
0 <= 1 <= n - m
n, m:t
Hm:0 <= m
H:m < n

P (2 ^ 1) == 1
n, m:t
Hm:0 <= m
H:m < n
0 <= 1 <= n - m
n, m:t
Hm:0 <= m
H:m < n

0 <= 1 <= n - m
n, m:t
Hm:0 <= m
H:m < n

0 <= 1
n, m:t
Hm:0 <= m
H:m < n
1 <= n - m
n, m:t
Hm:0 <= m
H:m < n

1 <= n - m
n, m:t
Hm:0 <= m
H:m < n

1 + m <= n
n, m:t
Hm:0 <= m
H:m < n

S m <= n
now apply le_succ_l. Qed.

forall n m : t, 0 <= n <= m -> (ones n).[m] = false

forall n m : t, 0 <= n <= m -> (ones n).[m] = false
n, m:t
Hn:0 <= n
H:n <= m

(ones n).[m] = false
n, m:t
Hn:0 < n
H:n <= m

(ones n).[m] = false
n, m:t
Hn:0 == n
H:n <= m
(ones n).[m] = false
n, m:t
Hn:0 < n
H:n <= m

0 <= P (2 ^ n)
n, m:t
Hn:0 < n
H:n <= m
log2 (P (2 ^ n)) < m
n, m:t
Hn:0 == n
H:n <= m
(ones n).[m] = false
n, m:t
Hn:0 < n
H:n <= m

log2 (P (2 ^ n)) < m
n, m:t
Hn:0 == n
H:n <= m
(ones n).[m] = false
n, m:t
Hn:0 < n
H:n <= m

P n < m
n, m:t
Hn:0 == n
H:n <= m
(ones n).[m] = false
n, m:t
Hn:0 == n
H:n <= m

(ones n).[m] = false
n, m:t
Hn:0 == n
H:n <= m

(P (2 ^ n)).[m] = false
now rewrite <- Hn, pow_0_r, one_succ, pred_succ, bits_0. Qed.

forall n m : t, 0 <= n -> (ones n).[m] = true <-> 0 <= m < n

forall n m : t, 0 <= n -> (ones n).[m] = true <-> 0 <= m < n
n, m:t
Hn:0 <= n

(ones n).[m] = true <-> 0 <= m < n
n, m:t
Hn:0 <= n

(ones n).[m] = true -> 0 <= m < n
n, m:t
Hn:0 <= n
0 <= m < n -> (ones n).[m] = true
n, m:t
Hn:0 <= n
H:(ones n).[m] = true

0 <= m < n
n, m:t
Hn:0 <= n
0 <= m < n -> (ones n).[m] = true
n, m:t
Hn:0 <= n
H:(ones n).[m] = true
Hm:m < 0

0 <= m < n
n, m:t
Hn:0 <= n
H:(ones n).[m] = true
Hm:0 <= m
0 <= m < n
n, m:t
Hn:0 <= n
0 <= m < n -> (ones n).[m] = true
n, m:t
Hn:0 <= n
H:(ones n).[m] = true
Hm:0 <= m

0 <= m < n
n, m:t
Hn:0 <= n
0 <= m < n -> (ones n).[m] = true
n, m:t
Hn:0 <= n
H:(ones n).[m] = true
Hm:0 <= m

m < n
n, m:t
Hn:0 <= n
0 <= m < n -> (ones n).[m] = true
n, m:t
Hn:0 <= n
H:(ones n).[m] = true
Hm:0 <= m

~ n <= m
n, m:t
Hn:0 <= n
0 <= m < n -> (ones n).[m] = true
n, m:t
Hn:0 <= n
H:(ones n).[m] = true
Hm:0 <= m
H':n <= m

False
n, m:t
Hn:0 <= n
0 <= m < n -> (ones n).[m] = true
n, m:t
Hn:0 <= n
H:false = true
Hm:0 <= m
H':n <= m

False
n, m:t
Hn:0 <= n
H:(ones n).[m] = true
Hm:0 <= m
H':n <= m
0 <= n <= m
n, m:t
Hn:0 <= n
0 <= m < n -> (ones n).[m] = true
n, m:t
Hn:0 <= n
H:(ones n).[m] = true
Hm:0 <= m
H':n <= m

0 <= n <= m
n, m:t
Hn:0 <= n
0 <= m < n -> (ones n).[m] = true
n, m:t
Hn:0 <= n

0 <= m < n -> (ones n).[m] = true
apply ones_spec_low. Qed.

forall a n : t, 0 <= a -> log2 a < n -> lor a (ones n) == ones n

forall a n : t, 0 <= a -> log2 a < n -> lor a (ones n) == ones n
a, n:t
Ha:0 <= a
H:log2 a < n

lor a (ones n) == ones n
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m

a.[m] || (ones n).[m] = (ones n).[m]
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m

a.[m] || (ones n).[m] = (ones n).[m]
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n
a.[m] || (ones n).[m] = (ones n).[m]
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m

log2 a < m
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m
0 <= n
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n
a.[m] || (ones n).[m] = (ones n).[m]
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m

0 <= n
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n
a.[m] || (ones n).[m] = (ones n).[m]
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n

a.[m] || (ones n).[m] = (ones n).[m]
rewrite ones_spec_low, orb_true_r; try split; trivial. Qed.

forall a n : t, 0 <= n -> land a (ones n) == a mod 2 ^ n

forall a n : t, 0 <= n -> land a (ones n) == a mod 2 ^ n
a, n:t
Hn:0 <= n

land a (ones n) == a mod 2 ^ n
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m

a.[m] && (ones n).[m] = (a mod 2 ^ n).[m]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:n <= m

a.[m] && (ones n).[m] = (a mod 2 ^ n).[m]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m < n
a.[m] && (ones n).[m] = (a mod 2 ^ n).[m]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m < n

a.[m] && (ones n).[m] = (a mod 2 ^ n).[m]
rewrite ones_spec_low, mod_pow2_bits_low, andb_true_r; try split; trivial. Qed.

forall a n : t, 0 <= a -> log2 a < n -> land a (ones n) == a

forall a n : t, 0 <= a -> log2 a < n -> land a (ones n) == a
a, n:t
Ha:0 <= a
H:log2 a < n

land a (ones n) == a
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

land a (ones n) == a
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

a mod 2 ^ n == a
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

0 <= a < 2 ^ n
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

a < 2 ^ n
a, n:t
Ha:0 <= a
H:log2 a < n
Hn:0 <= n

log2 a < log2 (2 ^ n)
now rewrite log2_pow2. Qed.

forall a n : t, 0 <= n -> ldiff a (ones n) == (a >> n) << n

forall a n : t, 0 <= n -> ldiff a (ones n) == (a >> n) << n
a, n:t
Hn:0 <= n

ldiff a (ones n) == (a >> n) << n
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m

a.[m] && negb (ones n).[m] = ((a >> n) << n).[m]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:n <= m

a.[m] && negb (ones n).[m] = ((a >> n) << n).[m]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m < n
a.[m] && negb (ones n).[m] = ((a >> n) << n).[m]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:n <= m

a.[m] && negb false = a.[m - n + n]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:n <= m
0 <= m - n
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:n <= m
0 <= n <= m
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m < n
a.[m] && negb (ones n).[m] = ((a >> n) << n).[m]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:n <= m

a.[m] && negb false = a.[m]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:n <= m
0 <= m - n
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:n <= m
0 <= n <= m
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m < n
a.[m] && negb (ones n).[m] = ((a >> n) << n).[m]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:n <= m

0 <= m - n
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:n <= m
0 <= n <= m
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m < n
a.[m] && negb (ones n).[m] = ((a >> n) << n).[m]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:n <= m

0 <= n <= m
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m < n
a.[m] && negb (ones n).[m] = ((a >> n) << n).[m]
a, n:t
Hn:0 <= n
m:t
Hm:0 <= m
H:m < n

a.[m] && negb (ones n).[m] = ((a >> n) << n).[m]
rewrite ones_spec_low, shiftl_spec_low, andb_false_r; try split; trivial. Qed.

forall a n : t, 0 <= a -> log2 a < n -> ldiff a (ones n) == 0

forall a n : t, 0 <= a -> log2 a < n -> ldiff a (ones n) == 0
a, n:t
Ha:0 <= a
H:log2 a < n

ldiff a (ones n) == 0
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m

a.[m] && negb (ones n).[m] = false
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m

a.[m] && negb (ones n).[m] = false
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n
a.[m] && negb (ones n).[m] = false
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m

log2 a < m
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m
0 <= n <= m
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n
a.[m] && negb (ones n).[m] = false
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m

0 <= n <= m
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n
a.[m] && negb (ones n).[m] = false
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m

0 <= n
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n
a.[m] && negb (ones n).[m] = false
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n

a.[m] && negb (ones n).[m] = false
rewrite ones_spec_low, andb_false_r; try split; trivial. Qed.

forall a n : t, 0 <= a -> log2 a < n -> ldiff (ones n) a == lxor a (ones n)

forall a n : t, 0 <= a -> log2 a < n -> ldiff (ones n) a == lxor a (ones n)
a, n:t
Ha:0 <= a
H:log2 a < n

ldiff (ones n) a == lxor a (ones n)
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m

(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m

(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n
(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m

log2 a < m
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m
0 <= n <= m
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n
(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m

0 <= n <= m
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n
(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:n <= m

0 <= n
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n
(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]
a, n:t
Ha:0 <= a
H:log2 a < n
m:t
Hm:0 <= m
H0:m < n

(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]
rewrite ones_spec_low, xorb_true_r; try split; trivial. Qed.
Bitwise operations and sign

forall a n : t, 0 <= a << n <-> 0 <= a

forall a n : t, 0 <= a << n <-> 0 <= a
a, n:t

0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n

0 <= a << n <-> 0 <= a
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
(* 0<=n *)
a, n:t
Hn:0 <= n

(exists k : t, forall m : t, k < m -> (a << n).[m] = false) <-> (exists k : t, forall m : t, k < m -> a.[m] = false)
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m : t, k < m -> (a << n).[m] = false

exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:0 <= n
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a << n).[m] = false
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m : t, k < m -> (a << n).[m] = false

forall m : t, k - n < m -> a.[m] = false
a, n:t
Hn:0 <= n
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a << n).[m] = false
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m0 : t, k < m0 -> (a << n).[m0] = false
m:t
Hm:k - n < m

a.[m] = false
a, n:t
Hn:0 <= n
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a << n).[m] = false
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m0 : t, k < m0 -> (a << n).[m0] = false
m:t
Hm:k - n < m
H:0 <= m

a.[m] = false
a, n:t
Hn:0 <= n
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a << n).[m] = false
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m0 : t, k < m0 -> (a << n).[m0] = false
m:t
Hm:k - n < m
H:0 <= m

(a << n).[m + n] = false
a, n:t
Hn:0 <= n
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a << n).[m] = false
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m0 : t, k < m0 -> (a << n).[m0] = false
m:t
Hm:k - n < m
H:0 <= m

k < m + n
a, n:t
Hn:0 <= n
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a << n).[m] = false
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m : t, k < m -> a.[m] = false

exists k0 : t, forall m : t, k0 < m -> (a << n).[m] = false
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m : t, k < m -> a.[m] = false

forall m : t, k + n < m -> (a << n).[m] = false
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m0 : t, k < m0 -> a.[m0] = false
m:t
Hm:k + n < m

(a << n).[m] = false
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m0 : t, k < m0 -> a.[m0] = false
m:t
Hm:k + n < m
H:0 <= m

(a << n).[m] = false
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m0 : t, k < m0 -> a.[m0] = false
m:t
Hm:k + n < m
H:0 <= m

a.[m - n] = false
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:0 <= n
k:t
Hk:forall m0 : t, k < m0 -> a.[m0] = false
m:t
Hm:k + n < m
H:0 <= m

k < m - n
a, n:t
Hn:n <= 0
0 <= a << n <-> 0 <= a
a, n:t
Hn:n <= 0

0 <= a << n <-> 0 <= a
(* n<=0*)
a, n:t
Hn:n <= 0

(exists k : t, forall m : t, k < m -> (a >> (- n)).[m] = false) <-> (exists k : t, forall m : t, k < m -> a.[m] = false)
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false

exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:0 <= k

exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:0 <= k

forall m : t, k - n < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = false
H:0 <= k
m:t
Hm:k - n < m

a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = false
H:0 <= k
m:t
Hm:k < m + n

a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = false
H:0 <= k
m:t
Hm:k < m + n

(a >> (- n)).[m + n] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = false
H:0 <= k
m:t
Hm:k < m + n
0 <= m + n
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = false
H:0 <= k
m:t
Hm:k < m + n

0 <= m + n
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0

exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0

a >> (- n) == 0
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
EQ:a >> (- n) == 0
exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0

forall n0 : t, 0 <= n0 -> (a >> (- n)).[n0] = 0.[n0]
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
EQ:a >> (- n) == 0
exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = false
H:k < 0
m:t
Hm:0 <= m

(a >> (- n)).[m] = 0.[m]
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
EQ:a >> (- n) == 0
exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = false
H:k < 0
m:t
Hm:0 <= m

(a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
EQ:a >> (- n) == 0
exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
EQ:a >> (- n) == 0

exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
EQ:a == 0 \/ 0 < a /\ log2 a < - n

exists k0 : t, forall m : t, k0 < m -> a.[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> (a >> (- n)).[m] = false
H:k < 0
EQ:a == 0 \/ 0 < a /\ log2 a < - n

0 <= a
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false
exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false

exists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m : t, k < m -> a.[m] = false

forall m : t, k + n < m -> (a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> a.[m0] = false
m:t
Hm:k + n < m

(a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> a.[m0] = false
m:t
Hm:k + n < m
H:0 <= m

(a >> (- n)).[m] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> a.[m0] = false
m:t
Hm:k + n < m
H:0 <= m

a.[m + - n] = false
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> a.[m0] = false
m:t
Hm:k + n < m
H:0 <= m

k < m + - n
a, n:t
Hn:n <= 0
k:t
Hk:forall m0 : t, k < m0 -> a.[m0] = false
m:t
Hm:k + n < m
H:0 <= m

k < m - n
now apply lt_add_lt_sub_r. Qed.

forall a n : t, a << n < 0 <-> a < 0

forall a n : t, a << n < 0 <-> a < 0
a, n:t

a << n < 0 <-> a < 0
now rewrite 2 lt_nge, shiftl_nonneg. Qed.

forall a n : t, 0 <= a >> n <-> 0 <= a

forall a n : t, 0 <= a >> n <-> 0 <= a
a, n:t

0 <= a >> n <-> 0 <= a
a, n:t

0 <= a << (- n) <-> 0 <= a
apply shiftl_nonneg. Qed.

forall a n : t, a >> n < 0 <-> a < 0

forall a n : t, a >> n < 0 <-> a < 0
a, n:t

a >> n < 0 <-> a < 0
now rewrite 2 lt_nge, shiftr_nonneg. Qed.

forall a : t, 0 <= div2 a <-> 0 <= a

forall a : t, 0 <= div2 a <-> 0 <= a
a:t

0 <= div2 a <-> 0 <= a
a:t

0 <= a >> 1 <-> 0 <= a
apply shiftr_nonneg. Qed.

forall a : t, div2 a < 0 <-> a < 0

forall a : t, div2 a < 0 <-> a < 0
a:t

div2 a < 0 <-> a < 0
now rewrite 2 lt_nge, div2_nonneg. Qed.

forall a b : t, 0 <= lor a b <-> 0 <= a /\ 0 <= b

forall a b : t, 0 <= lor a b <-> 0 <= a /\ 0 <= b
a, b:t

0 <= lor a b <-> 0 <= a /\ 0 <= b
a, b:t

(exists k : t, forall m : t, k < m -> (lor a b).[m] = false) <-> (exists k : t, forall m : t, k < m -> a.[m] = false) /\ (exists k : t, forall m : t, k < m -> b.[m] = false)
a, b:t

(exists k : t, forall m : t, k < m -> (lor a b).[m] = false) -> (exists k : t, forall m : t, k < m -> a.[m] = false) /\ (exists k : t, forall m : t, k < m -> b.[m] = false)
a, b:t
(exists k : t, forall m : t, k < m -> a.[m] = false) /\ (exists k : t, forall m : t, k < m -> b.[m] = false) -> exists k : t, forall m : t, k < m -> (lor a b).[m] = false
a, b, k:t
Hk:forall m : t, k < m -> (lor a b).[m] = false

(exists k0 : t, forall m : t, k0 < m -> a.[m] = false) /\ (exists k0 : t, forall m : t, k0 < m -> b.[m] = false)
a, b:t
(exists k : t, forall m : t, k < m -> a.[m] = false) /\ (exists k : t, forall m : t, k < m -> b.[m] = false) -> exists k : t, forall m : t, k < m -> (lor a b).[m] = false
a, b:t

(exists k : t, forall m : t, k < m -> a.[m] = false) /\ (exists k : t, forall m : t, k < m -> b.[m] = false) -> exists k : t, forall m : t, k < m -> (lor a b).[m] = false
a, b, k:t
Hk:forall m : t, k < m -> a.[m] = false
k':t
Hk':forall m : t, k' < m -> b.[m] = false

exists k0 : t, forall m : t, k0 < m -> (lor a b).[m] = false
destruct (le_ge_cases k k'); [ exists k' | exists k ]; intros m Hm; rewrite lor_spec, Hk, Hk'; trivial; order. Qed.

forall a b : t, lor a b < 0 <-> a < 0 \/ b < 0

forall a b : t, lor a b < 0 <-> a < 0 \/ b < 0
a, b:t

lor a b < 0 <-> a < 0 \/ b < 0
a, b:t

~ (0 <= a /\ 0 <= b) <-> ~ 0 <= a \/ ~ 0 <= b
a, b:t

~ (0 <= a /\ 0 <= b) -> ~ 0 <= a \/ ~ 0 <= b
a, b:t
~ 0 <= a \/ ~ 0 <= b -> ~ (0 <= a /\ 0 <= b)
a, b:t

decidable (0 <= a)
a, b:t
~ 0 <= a \/ ~ 0 <= b -> ~ (0 <= a /\ 0 <= b)
a, b:t

~ 0 <= a \/ ~ 0 <= b -> ~ (0 <= a /\ 0 <= b)
now intros [H|H] (H',H''). Qed.

forall a : t, 0 <= lnot a <-> a < 0

forall a : t, 0 <= lnot a <-> a < 0
a:t

0 <= P (- a) <-> a < 0
now rewrite <- opp_succ, opp_nonneg_nonpos, le_succ_l. Qed.

forall a : t, lnot a < 0 <-> 0 <= a

forall a : t, lnot a < 0 <-> 0 <= a
a:t

lnot a < 0 <-> 0 <= a
now rewrite le_ngt, lt_nge, lnot_nonneg. Qed.

forall a b : t, 0 <= land a b <-> 0 <= a \/ 0 <= b

forall a b : t, 0 <= land a b <-> 0 <= a \/ 0 <= b
a, b:t

0 <= land a b <-> 0 <= a \/ 0 <= b
now rewrite <- (lnot_involutive (land a b)), lnot_land, lnot_nonneg, lor_neg, !lnot_neg. Qed.

forall a b : t, land a b < 0 <-> a < 0 /\ b < 0

forall a b : t, land a b < 0 <-> a < 0 /\ b < 0
a, b:t

land a b < 0 <-> a < 0 /\ b < 0
now rewrite <- (lnot_involutive (land a b)), lnot_land, lnot_neg, lor_nonneg, !lnot_nonneg. Qed.

forall a b : t, 0 <= ldiff a b <-> 0 <= a \/ b < 0

forall a b : t, 0 <= ldiff a b <-> 0 <= a \/ b < 0
a, b:t

0 <= ldiff a b <-> 0 <= a \/ b < 0
now rewrite ldiff_land, land_nonneg, lnot_nonneg. Qed.

forall a b : t, ldiff a b < 0 <-> a < 0 <= b

forall a b : t, ldiff a b < 0 <-> a < 0 <= b
a, b:t

ldiff a b < 0 <-> a < 0 <= b
now rewrite ldiff_land, land_neg, lnot_neg. Qed.

forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)

forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)

forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b
H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b
forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)
a, b:t

0 <= a -> 0 <= b -> 0 <= lxor a b
H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b
forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)
a, b:t

(exists k : t, forall m : t, k < m -> a.[m] = false) -> (exists k : t, forall m : t, k < m -> b.[m] = false) -> exists k : t, forall m : t, k < m -> (lxor a b).[m] = false
H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b
forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)
a, b, k:t
Hk:forall m : t, k < m -> a.[m] = false
k':t
Hk':forall m : t, k' < m -> b.[m] = false

exists k0 : t, forall m : t, k0 < m -> (lxor a b).[m] = false
H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b
forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)
H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b

forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)
H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b

forall a b : t, 0 <= a -> b < 0 -> lxor a b < 0
H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b
H':forall a b : t, 0 <= a -> b < 0 -> lxor a b < 0
forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
a, b:t

0 <= a -> b < 0 -> lxor a b < 0
H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b
H':forall a b : t, 0 <= a -> b < 0 -> lxor a b < 0
forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
a, b:t

(exists k : t, forall m : t, k < m -> a.[m] = false) -> (exists k : t, forall m : t, k < m -> b.[m] = true) -> exists k : t, forall m : t, k < m -> (lxor a b).[m] = true
H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b
H':forall a b : t, 0 <= a -> b < 0 -> lxor a b < 0
forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
a, b, k:t
Hk:forall m : t, k < m -> a.[m] = false
k':t
Hk':forall m : t, k' < m -> b.[m] = true

exists k0 : t, forall m : t, k0 < m -> (lxor a b).[m] = true
H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b
H':forall a b : t, 0 <= a -> b < 0 -> lxor a b < 0
forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)
H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a b
H':forall a b : t, 0 <= a -> b < 0 -> lxor a b < 0

forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t

0 <= lxor a b <-> (0 <= a <-> 0 <= b)
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t

0 <= lxor a b -> 0 <= a <-> 0 <= b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b

0 <= a <-> 0 <= b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b

0 <= a -> 0 <= b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b
0 <= b -> 0 <= a
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b
Ha:0 <= a

0 <= b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b
0 <= b -> 0 <= a
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b
Ha:0 <= a
Hb:b < 0

0 <= b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b
0 <= b -> 0 <= a
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b
Ha:0 <= a
Hb:b < 0

lxor a b < 0 -> 0 <= b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b
0 <= b -> 0 <= a
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b

0 <= b -> 0 <= a
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b
Hb:0 <= b

0 <= a
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b
Hb:0 <= b
Ha:a < 0

0 <= a
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b
Hb:0 <= b
Ha:a < 0

lxor b a < 0 -> 0 <= a
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
Hab:0 <= lxor a b
Hb:0 <= b
Ha:a < 0

lxor a b < 0 -> 0 <= a
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t

0 <= a <-> 0 <= b -> 0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b

0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b
Ha:0 <= a

0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b
Ha:a < 0
0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b
Ha:0 <= a

0 <= b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b
Ha:a < 0
0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b
Ha:a < 0

0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b
Ha:a < 0
Hb:0 <= b

0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b
Ha:a < 0
Hb:b < 0
0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b
Ha:a < 0
Hb:0 <= b

0 <= a
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b
Ha:a < 0
Hb:b < 0
0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b
Ha:a < 0
Hb:b < 0

0 <= lxor a b
H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0
H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0
a, b:t
E:0 <= a <-> 0 <= b
Ha:a < 0
Hb:b < 0

0 <= lxor (lnot a) (lnot b)
apply H; now apply lnot_nonneg. Qed.
Bitwise operations and log2

forall a n : t, a.[n] = true -> (forall m : t, n < m -> a.[m] = false) -> log2 a == n

forall a n : t, a.[n] = true -> (forall m : t, n < m -> a.[m] = false) -> log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false

log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0

log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a == 0
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
log2 a == n
(* a < 0 *)
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0
k:t
Hk:forall m : t, k < m -> a.[m] = true

log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a == 0
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0
k:t
Hk:forall m : t, k < m -> a.[m] = true
H0:n <= k

log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0
k:t
Hk:forall m : t, k < m -> a.[m] = true
H0:k < n
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a == 0
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0
k:t
Hk:a.[S k] = true
H0:n <= k

log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0
k:t
Hk:forall m : t, k < m -> a.[m] = true
H0:k < n
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a == 0
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0
k:t
Hk:false = true
H0:n <= k

log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0
k:t
Hk:a.[S k] = true
H0:n <= k
n < S k
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0
k:t
Hk:forall m : t, k < m -> a.[m] = true
H0:k < n
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a == 0
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0
k:t
Hk:a.[S k] = true
H0:n <= k

n < S k
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0
k:t
Hk:forall m : t, k < m -> a.[m] = true
H0:k < n
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a == 0
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a < 0
k:t
Hk:forall m : t, k < m -> a.[m] = true
H0:k < n

log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a == 0
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
log2 a == n
a, n:t
H:a.[n] = true
H':a.[S n] = false
Ha:a < 0
k:t
Hk:forall m : t, k < m -> a.[m] = true
H0:k < n

log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a == 0
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
log2 a == n
a, n:t
H:a.[n] = true
H':true = false
Ha:a < 0
k:t
Hk:forall m : t, k < m -> a.[m] = true
H0:k < n

log2 a == n
a, n:t
H:a.[n] = true
H':a.[S n] = false
Ha:a < 0
k:t
Hk:forall m : t, k < m -> a.[m] = true
H0:k < n
k < S n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a == 0
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
log2 a == n
a, n:t
H:a.[n] = true
H':a.[S n] = false
Ha:a < 0
k:t
Hk:forall m : t, k < m -> a.[m] = true
H0:k < n

k < S n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a == 0
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:a == 0

log2 a == n
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
log2 a == n
(* a = 0 *)
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a

log2 a == n
(* 0 < a *)
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
LT:n < log2 a

False
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
LT:log2 a < n
False
a, n:t
H:a.[n] = true
H':a.[log2 a] = false
Ha:0 < a
LT:n < log2 a

False
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
LT:log2 a < n
False
a, n:t
H:a.[n] = true
H':forall m : t, n < m -> a.[m] = false
Ha:0 < a
LT:log2 a < n

False
now rewrite bits_above_log2 in H by order. Qed.

forall a n : t, 0 < a -> log2 (a >> n) == max 0 (log2 a - n)

forall a n : t, 0 < a -> log2 (a >> n) == max 0 (log2 a - n)
a, n:t
Ha:0 < a

log2 (a >> n) == max 0 (log2 a - n)
a, n:t
Ha:0 < a
H:0 <= log2 a - n

log2 (a >> n) == log2 a - n
a, n:t
Ha:0 < a
H:log2 a - n < 0
log2 (a >> n) == 0
a, n:t
Ha:0 < a
H:0 <= log2 a - n

(a >> n).[log2 a - n] = true
a, n:t
Ha:0 < a
H:0 <= log2 a - n
forall m : t, log2 a - n < m -> (a >> n).[m] = false
a, n:t
Ha:0 < a
H:log2 a - n < 0
log2 (a >> n) == 0
a, n:t
Ha:0 < a
H:0 <= log2 a - n

forall m : t, log2 a - n < m -> (a >> n).[m] = false
a, n:t
Ha:0 < a
H:log2 a - n < 0
log2 (a >> n) == 0
a, n:t
Ha:0 < a
H:0 <= log2 a - n
m:t
Hm:log2 a - n < m

(a >> n).[m] = false
a, n:t
Ha:0 < a
H:log2 a - n < 0
log2 (a >> n) == 0
a, n:t
Ha:0 < a
H:0 <= log2 a - n
m:t
Hm:log2 a - n < m
H0:0 <= m

(a >> n).[m] = false
a, n:t
Ha:0 < a
H:log2 a - n < 0
log2 (a >> n) == 0
a, n:t
Ha:0 < a
H:0 <= log2 a - n
m:t
Hm:log2 a - n < m
H0:0 <= m

a.[m + n] = false
a, n:t
Ha:0 < a
H:log2 a - n < 0
log2 (a >> n) == 0
a, n:t
Ha:0 < a
H:0 <= log2 a - n
m:t
Hm:log2 a - n < m
H0:0 <= m

log2 a < m + n
a, n:t
Ha:0 < a
H:log2 a - n < 0
log2 (a >> n) == 0
a, n:t
Ha:0 < a
H:log2 a - n < 0

log2 (a >> n) == 0
a, n:t
Ha:0 < a
H:log2 a < n

log2 (a >> n) == 0
a, n:t
Ha:0 < a
H:log2 a < n

a >> n <= 0
a, n:t
Ha:0 < a
H:log2 a < n

a >> n == 0
a, n:t
Ha:0 < a
H:log2 a < n

a == 0 \/ 0 < a /\ log2 a < n
a, n:t
Ha:0 < a
H:log2 a < n

0 < a /\ log2 a < n
now split. Qed.

forall a n : t, 0 < a -> 0 <= n -> log2 (a << n) == log2 a + n

forall a n : t, 0 < a -> 0 <= n -> log2 (a << n) == log2 a + n
a, n:t
Ha:0 < a
Hn:0 <= n

log2 (a << n) == log2 a + n
a, n:t
Ha:0 < a
Hn:0 <= n

log2 (a * 2 ^ n) == n + log2 a
now apply log2_mul_pow2. Qed.

forall a n : t, 0 < a -> log2 (a << n) == max 0 (log2 a + n)

forall a n : t, 0 < a -> log2 (a << n) == max 0 (log2 a + n)
a, n:t
Ha:0 < a

log2 (a << n) == max 0 (log2 a + n)
a, n:t
Ha:0 < a

max 0 (log2 a - - n) == max 0 (log2 a + n)
destruct (le_gt_cases 0 (log2 a + n)); [rewrite 2 max_r | rewrite 2 max_l]; rewrite ?sub_opp_r; try order. Qed.

forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)

forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)

forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 b
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
H:a <= b

log2 (lor a b) == log2 b
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)
a, b:t
Ha:0 < a
H:a <= b

log2 (lor a b) == log2 b
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)
a, b:t
Ha:0 < a
H:a <= b

(lor a b).[log2 b] = true
a, b:t
Ha:0 < a
H:a <= b
forall m : t, log2 b < m -> (lor a b).[m] = false
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)
a, b:t
Ha:0 < a
H:a <= b

forall m : t, log2 b < m -> (lor a b).[m] = false
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)
a, b:t
Ha:0 < a
H:a <= b
m:t
Hm:log2 b < m

(lor a b).[m] = false
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)
a, b:t
Ha:0 < a
H:a <= b
m:t
Hm:log2 b < m
H':log2 a <= log2 b

(lor a b).[m] = false
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 b

forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)
(* main *)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b

log2 (lor a b) == max (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:a <= b

log2 (lor a b) == max (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a
log2 (lor a b) == max (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:a <= b

log2 (lor a b) == log2 b
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a
log2 (lor a b) == max (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a

log2 (lor a b) == max (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a

log2 (lor a b) == log2 a
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a

log2 (lor b a) == log2 a
now apply AUX. Qed.

forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)

forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)

forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 a
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 a
forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b

log2 (land a b) <= log2 a
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 a
forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b

~ log2 a < log2 (land a b)
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 a
forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 a < log2 (land a b)

False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 a
forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 a < log2 (land a b)
H:0 <= land a b

False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 a
forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 a < log2 (land a b)
H:0 < land a b

False
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 a < log2 (land a b)
H:0 == land a b
False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 a
forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 a < log2 (land a b)
H:0 < land a b

(land a b).[log2 (land a b)] = true -> False
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 a < log2 (land a b)
H:0 == land a b
False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 a
forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 a < log2 (land a b)
H:0 == land a b

False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 a
forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 a < log2 0
H:0 == land a b

False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 a
forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 a

forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)
(* main *)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0
a, b:t
Ha:0 <= a
Hb:0 <= b

log2 (land a b) <= min (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:a <= b

log2 (land a b) <= min (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a
log2 (land a b) <= min (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:a <= b

log2 (land a b) <= log2 a
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a
log2 (land a b) <= min (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a

log2 (land a b) <= min (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a

log2 (land a b) <= log2 b
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a

log2 (land b a) <= log2 b
now apply AUX. Qed.

forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)

forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)

forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b

log2 (lxor a b) <= log2 b
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b

~ log2 b < log2 (lxor a b)
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)

False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 <= lxor a b

False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 < lxor a b

False
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 == lxor a b
False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 < lxor a b

(lxor a b).[log2 (lxor a b)] = true -> False
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 == lxor a b
False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 < lxor a b

xorb false false = true -> False
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 < lxor a b
log2 a < log2 (lxor a b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 == lxor a b
False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 < lxor a b

log2 a < log2 (lxor a b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 == lxor a b
False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 < lxor a b

log2 a <= log2 b
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 == lxor a b
False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 (lxor a b)
H:0 == lxor a b

False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
a, b:t
Ha:0 <= a
Hb:a <= b
LT:log2 b < log2 0
H:0 == lxor a b

False
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b
forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 b

forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)
(* main *)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b

log2 (lxor a b) <= max (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:a <= b

log2 (lxor a b) <= max (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a
log2 (lxor a b) <= max (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:a <= b

log2 (lxor a b) <= log2 b
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a
log2 (lxor a b) <= max (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a

log2 (lxor a b) <= max (log2 a) (log2 b)
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a

log2 (lxor a b) <= log2 a
AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0
a, b:t
Ha:0 <= a
Hb:0 <= b
H:b <= a

log2 (lxor b a) <= log2 a
now apply AUX. Qed.
Bitwise operations and arithmetical operations
Notation xor3 a b c := (xorb (xorb a b) c).
Notation lxor3 a b c := (lxor (lxor a b) c).
Notation nextcarry a b c := ((a&&b) || (c && (a||b))).
Notation lnextcarry a b c := (lor (land a b) (land c (lor a b))).


forall a b : t, (a + b).[0] = xorb a.[0] b.[0]

forall a b : t, (a + b).[0] = xorb a.[0] b.[0]
a, b:t

(a + b).[0] = xorb a.[0] b.[0]
now rewrite !bit0_odd, odd_add. Qed.

forall a b c : t, (a + b + c).[0] = xor3 a.[0] b.[0] c.[0]

forall a b c : t, (a + b + c).[0] = xor3 a.[0] b.[0] c.[0]
a, b, c:t

(a + b + c).[0] = xor3 a.[0] b.[0] c.[0]
now rewrite !add_bit0. Qed.

forall a0 b0 c0 : bool, (a0 + b0 + c0) / 2 == nextcarry a0 b0 c0

forall a0 b0 c0 : bool, (a0 + b0 + c0) / 2 == nextcarry a0 b0 c0
H:1 + 1 == 2

forall a0 b0 c0 : bool, (a0 + b0 + c0) / 2 == nextcarry a0 b0 c0
H:1 + 1 == 2

(2 + 1) / 2 == 1
H:1 + 1 == 2

1 == (2 + 1) / 2
H:1 + 1 == 2

0 <= 1 < 2 \/ 2 < 1 <= 0
H:1 + 1 == 2
2 + 1 == 2 * 1 + 1
H:1 + 1 == 2

2 + 1 == 2 * 1 + 1
now nzsimpl'. Qed.

forall (a b : t) (c0 : bool), (a + b + c0) / 2 == a / 2 + b / 2 + nextcarry a.[0] b.[0] c0

forall (a b : t) (c0 : bool), (a + b + c0) / 2 == a / 2 + b / 2 + nextcarry a.[0] b.[0] c0
a, b:t
c0:bool

(a + b + c0) / 2 == a / 2 + b / 2 + nextcarry a.[0] b.[0] c0
a, b:t
c0:bool

(a + b + c0) / 2 == a / 2 + b / 2 + (a.[0] + b.[0] + c0) / 2
a, b:t
c0:bool

(a + b + c0) / 2 == (a.[0] + b.[0] + c0) / 2 + (a / 2 + b / 2)
a, b:t
c0:bool

(a + b + c0) / 2 == (a.[0] + b.[0] + c0 + (a / 2 + b / 2) * 2) / 2
a, b:t
c0:bool

a + b + c0 == a.[0] + b.[0] + c0 + (a / 2 + b / 2) * 2
a, b:t
c0:bool

a + b + c0 == a.[0] + b.[0] + c0 + (2 * div2 a + 2 * div2 b)
a, b:t
c0:bool

2 * div2 a + a.[0] + b + c0 == a.[0] + b.[0] + c0 + (2 * div2 a + 2 * div2 b)
a, b:t
c0:bool

2 * div2 a + a.[0] + (2 * div2 b + b.[0]) + c0 == a.[0] + b.[0] + c0 + (2 * div2 a + 2 * div2 b)
a, b:t
c0:bool

2 * div2 a + 2 * div2 b + (a.[0] + b.[0]) + c0 == a.[0] + b.[0] + c0 + (2 * div2 a + 2 * div2 b)
a, b:t
c0:bool

2 * div2 a + 2 * div2 b + (a.[0] + b.[0] + c0) == a.[0] + b.[0] + c0 + (2 * div2 a + 2 * div2 b)
apply add_comm. Qed.
The main result concerning addition: we express the bits of the sum in term of bits of a and b and of some carry stream which is also recursively determined by another equation.

forall n : t, 0 <= n -> forall (a b : t) (c0 : bool), - 2 ^ n <= a < 2 ^ n -> - 2 ^ n <= b < 2 ^ n -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0

forall n : t, 0 <= n -> forall (a b : t) (c0 : bool), - 2 ^ n <= a < 2 ^ n -> - 2 ^ n <= b < 2 ^ n -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n

forall (a b : t) (c0 : bool), - 2 ^ n <= a < 2 ^ n -> - 2 ^ n <= b < 2 ^ n -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n

Proper (eq ==> iff) (fun n0 : t => forall (a b : t) (c0 : bool), - 2 ^ n0 <= a < 2 ^ n0 -> - 2 ^ n0 <= b < 2 ^ n0 -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0)
n:t
Hn:0 <= n
forall (a b : t) (c0 : bool), - 2 ^ 0 <= a < 2 ^ 0 -> - 2 ^ 0 <= b < 2 ^ 0 -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n

forall (a b : t) (c0 : bool), - 2 ^ 0 <= a < 2 ^ 0 -> - 2 ^ 0 <= b < 2 ^ 0 -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
(* base *)
n:t
Hn:0 <= n
a, b:t
c0:bool

- 2 ^ 0 <= a < 2 ^ 0 -> - 2 ^ 0 <= b < 2 ^ 0 -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool

-1 <= a <= 0 -> -1 <= b <= 0 -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 <= a
Ha2:a <= 0
Hb1:-1 <= b
Hb2:b <= 0

exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
(* base, a = 0, b = 0 *)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

a + b + c0 == lxor3 a b c0 /\ c0 / 2 == lnextcarry a b c0 /\ c0.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

0 + 0 + c0 == lxor3 0 0 c0 /\ c0 / 2 == lnextcarry 0 0 c0 /\ c0.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

c0 == c0 /\ c0 / 2 == 0 /\ c0.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
(* base, a = 0, b = -1 *)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

a + b + c0 == lxor3 a b (- c0) /\ - c0 / 2 == lnextcarry a b (- c0) /\ (- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

0 + -1 + c0 == lxor3 0 (-1) (- c0) /\ - c0 / 2 == lnextcarry 0 (-1) (- c0) /\ (- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

0 + -1 + c0 == lxor3 0 (-1) (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
- c0 / 2 == lnextcarry 0 (-1) (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

-1 + c0 == lnot (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
- c0 / 2 == lnextcarry 0 (-1) (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

-1 + c0 == P (- - c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
- c0 / 2 == lnextcarry 0 (-1) (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

- c0 / 2 == lnextcarry 0 (-1) (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

- c0 / 2 == - c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

- c0 == - c0 / 2
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

0 <= c0 < 2 \/ 2 < c0 <= 0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
- c0 == 2 * - c0 + c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

- c0 == 2 * - c0 + c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:0 <= a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
(* base, a = -1, b = 0 *)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

a + b + c0 == lxor3 a b (- c0) /\ - c0 / 2 == lnextcarry a b (- c0) /\ (- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

-1 + 0 + c0 == lxor3 (-1) 0 (- c0) /\ - c0 / 2 == lnextcarry (-1) 0 (- c0) /\ (- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

-1 + 0 + c0 == lxor3 (-1) 0 (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
- c0 / 2 == lnextcarry (-1) 0 (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

-1 + c0 == lnot (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
- c0 / 2 == lnextcarry (-1) 0 (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

-1 + c0 == P (- - c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
- c0 / 2 == lnextcarry (-1) 0 (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

- c0 / 2 == lnextcarry (-1) 0 (- c0)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

- c0 / 2 == - c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

- c0 == - c0 / 2
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

0 <= c0 < 2 \/ 2 < c0 <= 0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
- c0 == 2 * - c0 + c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

- c0 == 2 * - c0 + c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0
(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:0 <= b
Hb2:b <= 0

(- c0).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
(* base, a = -1, b = -1 *)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

a + b + c0 == lxor3 a b (c0 + 2 * -1) /\ (c0 + 2 * -1) / 2 == lnextcarry a b (c0 + 2 * -1) /\ (c0 + 2 * -1).[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

-1 + -1 + c0 == lxor3 (-1) (-1) (c0 + 2 * -1) /\ (c0 + 2 * -1) / 2 == lnextcarry (-1) (-1) (c0 + 2 * -1) /\ (c0 + 2 * -1).[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

-1 + -1 + c0 == lxor3 (-1) (-1) (c0 + 2 * -1)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(c0 + 2 * -1) / 2 == lnextcarry (-1) (-1) (c0 + 2 * -1)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(c0 + 2 * -1).[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

-1 + -1 + c0 == c0 + 2 * -1
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(c0 + 2 * -1) / 2 == lnextcarry (-1) (-1) (c0 + 2 * -1)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(c0 + 2 * -1).[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

(c0 + 2 * -1) / 2 == lnextcarry (-1) (-1) (c0 + 2 * -1)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(c0 + 2 * -1).[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

(c0 + 2 * -1) / 2 == -1
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0
(c0 + 2 * -1).[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha1:-1 == a
Ha2:a <= 0
Hb1:-1 == b
Hb2:b <= 0

(c0 + 2 * -1).[0] = c0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n

forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
(* step *)

forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
IH:forall (a0 b0 : t) (c1 : bool), - 2 ^ n <= a0 < 2 ^ n -> - 2 ^ n <= b0 < 2 ^ n -> exists c : t, a0 + b0 + c1 == lxor3 a0 b0 c /\ c / 2 == lnextcarry a0 b0 c /\ c.[0] = c1
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n

exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
IH:forall (a0 b0 : t) (c2 : bool), - 2 ^ n <= a0 < 2 ^ n -> - 2 ^ n <= b0 < 2 ^ n -> exists c : t, a0 + b0 + c2 == lxor3 a0 b0 c /\ c / 2 == lnextcarry a0 b0 c /\ c.[0] = c2
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

- 2 ^ n <= a / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
- 2 ^ n <= b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

- 2 ^ n <= a / 2
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
a / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
- 2 ^ n <= b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

0 < 2
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
2 * - 2 ^ n <= a
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
a / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
- 2 ^ n <= b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

2 * - 2 ^ n <= a
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
a / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
- 2 ^ n <= b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

a / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
- 2 ^ n <= b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

0 < 2
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
a < 2 * 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
- 2 ^ n <= b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

a < 2 * 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
- 2 ^ n <= b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

- 2 ^ n <= b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

- 2 ^ n <= b / 2
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

0 < 2
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
2 * - 2 ^ n <= b
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

2 * - 2 ^ n <= b
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

b / 2 < 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

0 < 2
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
b < 2 * 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool

b < 2 * 2 ^ n
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1

exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1

a + b + c0 == lxor3 a b (c0 + 2 * c) /\ (c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c) /\ (c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1

a + b + c0 == lxor3 a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
(* step, add *)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 <= m

(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 < m

(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m
(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 <= P m

(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m
(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 <= P m

((a + b + c0) / 2).[P m] = (lxor3 (a / 2) (b / 2) ((c0 + 2 * c) / 2)).[P m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m
(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 <= P m

(a + b + c0) / 2 == lxor3 (a / 2) (b / 2) ((c0 + 2 * c) / 2)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m
(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 <= P m

(a + b + c0) / 2 == a / 2 + b / 2 + c1
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m
(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m

(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m

(a + b + c0).[0] = xor3 a.[0] b.[0] (c0 + 2 * c).[0]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1

(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
(* step, carry *)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1

c == lnextcarry a b (c0 + 2 * c)
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 <= m

c.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 < m

c.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m
c.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 <= P m

c.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m
c.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 <= P m

(lnextcarry (a / 2) (b / 2) c).[P m] = nextcarry (a / 2).[P m] (b / 2).[P m] ((c0 + 2 * c) / 2).[P m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m
c.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 <= P m

nextcarry (a / 2).[P m] (b / 2).[P m] c.[P m] = nextcarry (a / 2).[P m] (b / 2).[P m] ((c0 + 2 * c) / 2).[P m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m
c.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m

c.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
m:t
Hm:0 == m

c.[0] = nextcarry a.[0] b.[0] (c0 + 2 * c).[0]
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1
(c0 + 2 * c).[0] = c0
n:t
Hn:0 <= n
a, b:t
c0:bool
Ha:- 2 ^ S n <= a < 2 ^ S n
Hb:- 2 ^ S n <= b < 2 ^ S n
c1:=nextcarry a.[0] b.[0] c0:bool
c:t
IH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) c
IH2:c / 2 == lnextcarry (a / 2) (b / 2) c
Hc:c.[0] = c1

(c0 + 2 * c).[0] = c0
(* step, carry0 *) apply add_b2z_double_bit0. Qed.

forall (a b : t) (c0 : bool), exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0

forall (a b : t) (c0 : bool), exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
a, b:t
c0:bool

exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
a, b:t
c0:bool
n:=max (abs a) (abs b):t

exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0
a, b:t
c0:bool
n:=max (abs a) (abs b):t

0 <= n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= b < 2 ^ n
(* positivity *)
a, b:t
c0:bool
n:=max (abs a) (abs b):t

0 <= max (abs a) (abs b)
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

- 2 ^ n <= a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= b < 2 ^ n
(* bound for a *)
a, b:t
c0:bool
n:=max (abs a) (abs b):t

abs a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Ha:abs a < 2 ^ n
- 2 ^ n <= a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

abs a < 2 ^ abs a
a, b:t
c0:bool
n:=max (abs a) (abs b):t
2 ^ abs a <= 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Ha:abs a < 2 ^ n
- 2 ^ n <= a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

2 ^ abs a <= 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Ha:abs a < 2 ^ n
- 2 ^ n <= a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

0 < 2
a, b:t
c0:bool
n:=max (abs a) (abs b):t
abs a <= n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Ha:abs a < 2 ^ n
- 2 ^ n <= a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

abs a <= n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Ha:abs a < 2 ^ n
- 2 ^ n <= a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

abs a <= max (abs a) (abs b)
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Ha:abs a < 2 ^ n
- 2 ^ n <= a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Ha:abs a < 2 ^ n

- 2 ^ n <= a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Ha:- 2 ^ n < a < 2 ^ n

- 2 ^ n <= a < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

- 2 ^ n <= b < 2 ^ n
(* bound for b *)
a, b:t
c0:bool
n:=max (abs a) (abs b):t

abs b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Hb:abs b < 2 ^ n
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

abs b < 2 ^ abs b
a, b:t
c0:bool
n:=max (abs a) (abs b):t
2 ^ abs b <= 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Hb:abs b < 2 ^ n
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

2 ^ abs b <= 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Hb:abs b < 2 ^ n
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

0 < 2
a, b:t
c0:bool
n:=max (abs a) (abs b):t
abs b <= n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Hb:abs b < 2 ^ n
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

abs b <= n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Hb:abs b < 2 ^ n
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t

abs b <= max (abs a) (abs b)
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Hb:abs b < 2 ^ n
- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Hb:abs b < 2 ^ n

- 2 ^ n <= b < 2 ^ n
a, b:t
c0:bool
n:=max (abs a) (abs b):t
Hb:- 2 ^ n < b < 2 ^ n

- 2 ^ n <= b < 2 ^ n
destruct Hb; split; order. Qed.
Particular case : the second bit of an addition

forall a b : t, (a + b).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])

forall a b : t, (a + b).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])
a, b:t

(a + b).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])
a, b, c:t
EQ1:a + b + false == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

(a + b).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])
a, b, c:t
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

(a + b).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])
a, b, c:t
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

(lxor3 a b c).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])
a, b, c:t
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

xor3 a.[1] b.[1] c.[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])
a, b, c:t
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

c.[1] = a.[0] && b.[0]
a, b, c:t
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

(lnextcarry a b c).[0] = a.[0] && b.[0]
a, b, c:t
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

nextcarry a.[0] b.[0] c.[0] = a.[0] && b.[0]
a, b, c:t
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

nextcarry a.[0] b.[0] false = a.[0] && b.[0]
a, b, c:t
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

a.[0] && b.[0] || false = a.[0] && b.[0]
apply orb_false_r. Qed.
In an addition, there will be no carries iff there is no common bits in the numbers to add

forall a b c : t, c / 2 == lnextcarry a b c -> c.[0] = false -> c == 0 <-> land a b == 0

forall a b c : t, c / 2 == lnextcarry a b c -> c.[0] = false -> c == 0 <-> land a b == 0
a, b, c:t
H:c / 2 == lnextcarry a b c
H':c.[0] = false

c == 0 <-> land a b == 0
a, b, c:t
H:c / 2 == lnextcarry a b c
H':c.[0] = false

c == 0 -> land a b == 0
a, b, c:t
H:c / 2 == lnextcarry a b c
H':c.[0] = false
land a b == 0 -> c == 0
a, b, c:t
H:0 / 2 == lnextcarry a b 0
H':0.[0] = false
EQ:c == 0

land a b == 0
a, b, c:t
H:c / 2 == lnextcarry a b c
H':c.[0] = false
land a b == 0 -> c == 0
a, b, c:t
H:0 == lnextcarry a b 0
H':0.[0] = false
EQ:c == 0

land a b == 0
a, b, c:t
H:c / 2 == lnextcarry a b c
H':c.[0] = false
land a b == 0 -> c == 0
a, b, c:t
H:lnextcarry a b 0 == 0
H':0.[0] = false
EQ:c == 0

land a b == 0
a, b, c:t
H:c / 2 == lnextcarry a b c
H':c.[0] = false
land a b == 0 -> c == 0
a, b, c:t
H:c / 2 == lnextcarry a b c
H':c.[0] = false

land a b == 0 -> c == 0
a, b, c:t
H:c / 2 == lnextcarry a b c
H':c.[0] = false
EQ:land a b == 0

c == 0
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0

c == 0
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0

forall n : t, 0 <= n -> c.[n] = 0.[n]
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0
n:t
Hn:0 <= n

c.[n] = 0.[n]
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0
n:t
Hn:0 <= n

c.[n] = false
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0
n:t
Hn:0 <= n

Proper (eq ==> iff) (fun n0 : t => c.[n0] = false)
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0
n:t
Hn:0 <= n
c.[0] = false
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> c.[m] = false -> c.[S m] = false
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0
n:t
Hn:0 <= n

c.[0] = false
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0
n:t
Hn:0 <= n
forall m : t, 0 <= m -> c.[m] = false -> c.[S m] = false
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0
n:t
Hn:0 <= n

forall m : t, 0 <= m -> c.[m] = false -> c.[S m] = false
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0

forall m : t, 0 <= m -> c.[m] = false -> c.[S m] = false
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0
n:t
Hn:0 <= n
IH:c.[n] = false

c.[S n] = false
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0
n:t
Hn:0 <= n
IH:c.[n] = false

(land c (lor a b)).[n] = false
a, b, c:t
H:c / 2 == land c (lor a b)
H':c.[0] = false
EQ:land a b == 0
n:t
Hn:0 <= n
IH:c.[n] = false

c.[n] && (a.[n] || b.[n]) = false
now rewrite IH. Qed.
When there is no common bits, the addition is just a xor

forall a b : t, land a b == 0 -> a + b == lxor a b

forall a b : t, land a b == 0 -> a + b == lxor a b
a, b:t
H:land a b == 0

a + b == lxor a b
a, b:t
H:land a b == 0
c:t
EQ1:a + b + false == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

a + b == lxor a b
a, b:t
H:land a b == 0
c:t
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

a + b == lxor a b
a, b:t
H:land a b == 0
c:t
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

lxor3 a b c == lxor a b
a, b, c:t
H:c == 0
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

lxor3 a b c == lxor a b
a, b, c:t
H:c == 0
EQ1:a + b == lxor3 a b c
EQ2:c / 2 == lnextcarry a b c
Hc:c.[0] = false

lxor3 a b 0 == lxor a b
now rewrite lxor_0_r. Qed.
A null ldiff implies being smaller

forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b

forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b

forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n

forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b

Proper (eq ==> iff) (fun n : t => forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b)

forall a b : t, 0 <= a < 2 ^ 0 -> 0 <= b -> ldiff a b == 0 -> a <= b

forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> 0 <= b -> ldiff a b == 0 -> a <= b) -> forall a b : t, 0 <= a < 2 ^ S m -> 0 <= b -> ldiff a b == 0 -> a <= b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b

forall a b : t, 0 <= a < 2 ^ 0 -> 0 <= b -> ldiff a b == 0 -> a <= b

forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> 0 <= b -> ldiff a b == 0 -> a <= b) -> forall a b : t, 0 <= a < 2 ^ S m -> 0 <= b -> ldiff a b == 0 -> a <= b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
a, b:t
Ha:0 <= a < 2 ^ 0
Hb:0 <= b

a <= b

forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> 0 <= b -> ldiff a b == 0 -> a <= b) -> forall a b : t, 0 <= a < 2 ^ S m -> 0 <= b -> ldiff a b == 0 -> a <= b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
a, b:t
Ha:0 <= a <= 0
Hb:0 <= b

a <= b

forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> 0 <= b -> ldiff a b == 0 -> a <= b) -> forall a b : t, 0 <= a < 2 ^ S m -> 0 <= b -> ldiff a b == 0 -> a <= b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b

forall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> 0 <= b -> ldiff a b == 0 -> a <= b) -> forall a b : t, 0 <= a < 2 ^ S m -> 0 <= b -> ldiff a b == 0 -> a <= b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0

a <= b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

a <= b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

2 * (a / 2) + a mod 2 <= 2 * (b / 2) + b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

2 * (a / 2) <= 2 * (b / 2)
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
a mod 2 <= b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

a / 2 <= b / 2
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
a mod 2 <= b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

0 <= a / 2 < 2 ^ n
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
0 <= b / 2
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
ldiff (a / 2) (b / 2) == 0
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
a mod 2 <= b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

0 <= a / 2
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
a / 2 < 2 ^ n
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
0 <= b / 2
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
ldiff (a / 2) (b / 2) == 0
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
a mod 2 <= b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

a / 2 < 2 ^ n
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
0 <= b / 2
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
ldiff (a / 2) (b / 2) == 0
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
a mod 2 <= b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

a < 2 * 2 ^ n
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
0 <= b / 2
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
ldiff (a / 2) (b / 2) == 0
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
a mod 2 <= b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

0 <= b / 2
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
ldiff (a / 2) (b / 2) == 0
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
a mod 2 <= b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

ldiff (a / 2) (b / 2) == 0
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
a mod 2 <= b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

ldiff (a >> 1) (b >> 1) == 0
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0
a mod 2 <= b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

a mod 2 <= b mod 2
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:ldiff a b == 0
NEQ:2 ~= 0

a.[0] <= b.[0]
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:testbit (ldiff a b) === testbit 0
NEQ:2 ~= 0

a.[0] <= b.[0]
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:(ldiff a b).[0] = 0.[0]
NEQ:2 ~= 0

a.[0] <= b.[0]
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
n:t
Hn:0 <= n
IH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Ha:0 <= a
Ha':a < 2 ^ S n
Hb:0 <= b
H:a.[0] && negb b.[0] = false
NEQ:2 ~= 0

a.[0] <= b.[0]
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b

forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b
(* main *)
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0

0 <= a <= b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0

0 <= a
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha:0 <= a
0 <= a <= b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha':a < 0

False
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha:0 <= a
0 <= a <= b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha':a < 0

0 < 0
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha:0 <= a
0 <= a <= b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha':a < 0

ldiff a b < 0
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha:0 <= a
0 <= a <= b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha':a < 0

a < 0 <= b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha:0 <= a
0 <= a <= b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha:0 <= a

0 <= a <= b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha:0 <= a

a <= b
AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0
a, b:t
Hb:0 <= b
Hd:ldiff a b == 0
Ha:0 <= a

a < 2 ^ a
apply pow_gt_lin_r; order'. Qed.
Subtraction can be a ldiff when the opposite ldiff is null.

forall a b : t, ldiff b a == 0 -> a - b == ldiff a b

forall a b : t, ldiff b a == 0 -> a - b == ldiff a b
a, b:t
H:ldiff b a == 0

a - b == ldiff a b
a, b:t
H:ldiff b a == 0

a - b + b == ldiff a b + b
a, b:t
H:ldiff b a == 0

a == ldiff a b + b
a, b:t
H:ldiff b a == 0

ldiff a b + b == a
a, b:t
H:ldiff b a == 0

lxor (ldiff a b) b == a
a, b:t
H:ldiff b a == 0
land (ldiff a b) b == 0
a, b:t
H:ldiff b a == 0
m:t
Hm:0 <= m

xorb (a.[m] && negb b.[m]) b.[m] = a.[m]
a, b:t
H:ldiff b a == 0
land (ldiff a b) b == 0
a, b:t
H:testbit (ldiff b a) === testbit 0
m:t
Hm:0 <= m

xorb (a.[m] && negb b.[m]) b.[m] = a.[m]
a, b:t
H:ldiff b a == 0
land (ldiff a b) b == 0
a, b, m:t
H:(ldiff b a).[m] = 0.[m]
Hm:0 <= m

xorb (a.[m] && negb b.[m]) b.[m] = a.[m]
a, b:t
H:ldiff b a == 0
land (ldiff a b) b == 0
a, b, m:t
H:b.[m] && negb a.[m] = false
Hm:0 <= m

xorb (a.[m] && negb b.[m]) b.[m] = a.[m]
a, b:t
H:ldiff b a == 0
land (ldiff a b) b == 0
a, b:t
H:ldiff b a == 0

land (ldiff a b) b == 0
apply land_ldiff. Qed.
Adding numbers with no common bits cannot lead to a much bigger number

forall a b n : t, land a b == 0 -> a < 2 ^ n -> b < 2 ^ n -> a + b < 2 ^ n

forall a b n : t, land a b == 0 -> a < 2 ^ n -> b < 2 ^ n -> a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n

a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':a <= 0

a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':a <= 0

a + b <= 0 + b
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':a <= 0
0 + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':a <= 0

0 + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a

a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
Hb':b <= 0

a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
Hb':0 < b
a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
Hb':b <= 0

a + b <= a + 0
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
Hb':b <= 0
a + 0 < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
Hb':0 < b
a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
Hb':b <= 0

a + 0 < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
Hb':0 < b
a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
Hb':0 < b

a + b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
Hb':0 < b

lxor a b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
Hb':0 < b
H0:0 < lxor a b

lxor a b < 2 ^ n
a, b, n:t
H:land a b == 0
Ha:a < 2 ^ n
Hb:b < 2 ^ n
Ha':0 < a
Hb':0 < b
H0:0 < lxor a b

log2 (lxor a b) < n
a, b, n:t
H:land a b == 0
Ha:log2 a < n
Hb:b < 2 ^ n
Ha':0 < a
Hb':0 < b
H0:0 < lxor a b

log2 (lxor a b) < n
a, b, n:t
H:land a b == 0
Ha:log2 a < n
Hb:log2 b < n
Ha':0 < a
Hb':0 < b
H0:0 < lxor a b

log2 (lxor a b) < n
a, b, n:t
H:land a b == 0
Ha:log2 a < n
Hb:log2 b < n
Ha':0 < a
Hb':0 < b
H0:0 < lxor a b

log2 (lxor a b) <= max (log2 a) (log2 b)
a, b, n:t
H:land a b == 0
Ha:log2 a < n
Hb:log2 b < n
Ha':0 < a
Hb':0 < b
H0:0 < lxor a b
max (log2 a) (log2 b) < n
a, b, n:t
H:land a b == 0
Ha:log2 a < n
Hb:log2 b < n
Ha':0 < a
Hb':0 < b
H0:0 < lxor a b

max (log2 a) (log2 b) < n
destruct (le_ge_cases (log2 a) (log2 b)); [rewrite max_r|rewrite max_l]; order. Qed.

forall a b n : t, 0 <= n -> land a b == 0 -> a mod 2 ^ n + b mod 2 ^ n < 2 ^ n

forall a b n : t, 0 <= n -> land a b == 0 -> a mod 2 ^ n + b mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0

a mod 2 ^ n + b mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0

land (a mod 2 ^ n) (b mod 2 ^ n) == 0
a, b, n:t
Hn:0 <= n
H:land a b == 0
a mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0
b mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0
m:t
Hm:0 <= m

(a mod 2 ^ n).[m] && (b mod 2 ^ n).[m] = false
a, b, n:t
Hn:0 <= n
H:land a b == 0
a mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0
b mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0
m:t
Hm:0 <= m
H0:n <= m

(a mod 2 ^ n).[m] && (b mod 2 ^ n).[m] = false
a, b, n:t
Hn:0 <= n
H:land a b == 0
m:t
Hm:0 <= m
H0:m < n
(a mod 2 ^ n).[m] && (b mod 2 ^ n).[m] = false
a, b, n:t
Hn:0 <= n
H:land a b == 0
a mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0
b mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0
m:t
Hm:0 <= m
H0:m < n

(a mod 2 ^ n).[m] && (b mod 2 ^ n).[m] = false
a, b, n:t
Hn:0 <= n
H:land a b == 0
a mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0
b mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0

a mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0
b mod 2 ^ n < 2 ^ n
a, b, n:t
Hn:0 <= n
H:land a b == 0

b mod 2 ^ n < 2 ^ n
apply mod_pos_bound; order_pos. Qed. End ZBitsProp.