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 Morphisms Setoid Bvector BinPos BinNat PeanoNat Pnat Nnat
        Basics ByteVector.

Local Open Scope N_scope.
Local Open Scope program_scope.
This file is mostly obsolete, see directly BinNat now.
Compatibility names for some bitwise operations
Notation Pxor := Pos.lxor (only parsing).
Notation Nxor := N.lxor (only parsing).
Notation Pbit := Pos.testbit_nat (only parsing).
Notation Nbit := N.testbit_nat (only parsing).

Notation Nxor_eq := N.lxor_eq (only parsing).
Notation Nxor_comm := N.lxor_comm (only parsing).
Notation Nxor_assoc := N.lxor_assoc (only parsing).
Notation Nxor_neutral_left := N.lxor_0_l (only parsing).
Notation Nxor_neutral_right := N.lxor_0_r (only parsing).
Notation Nxor_nilpotent := N.lxor_nilpotent (only parsing).
Equivalence of bit-testing functions, either with index in N or in nat.

forall (p : positive) (n : nat), Pos.testbit p (N.of_nat n) = Pos.testbit_nat p n

forall (p : positive) (n : nat), Pos.testbit p (N.of_nat n) = Pos.testbit_nat p n
induction p as [p IH|p IH| ]; intros [|n]; simpl; trivial; rewrite <- IH; f_equal; rewrite (pred_Sn n) at 2; now rewrite Nat2N.inj_pred. Qed.

forall (a : N) (n : nat), N.testbit a (N.of_nat n) = N.testbit_nat a n

forall (a : N) (n : nat), N.testbit a (N.of_nat n) = N.testbit_nat a n

forall n : nat, N.testbit 0 (N.of_nat n) = N.testbit_nat 0 n
p:positive
forall n : nat, N.testbit (N.pos p) (N.of_nat n) = N.testbit_nat (N.pos p) n
p:positive

forall n : nat, N.testbit (N.pos p) (N.of_nat n) = N.testbit_nat (N.pos p) n
apply Ptestbit_Pbit. Qed.

forall (p : positive) (n : N), Pos.testbit_nat p (N.to_nat n) = Pos.testbit p n

forall (p : positive) (n : N), Pos.testbit_nat p (N.to_nat n) = Pos.testbit p n
intros; now rewrite <- Ptestbit_Pbit, N2Nat.id. Qed.

forall a n : N, N.testbit_nat a (N.to_nat n) = N.testbit a n

forall a n : N, N.testbit_nat a (N.to_nat n) = N.testbit a n

forall n : N, N.testbit_nat 0 (N.to_nat n) = N.testbit 0 n
p:positive
forall n : N, N.testbit_nat (N.pos p) (N.to_nat n) = N.testbit (N.pos p) n
p:positive

forall n : N, N.testbit_nat (N.pos p) (N.to_nat n) = N.testbit (N.pos p) n
apply Pbit_Ptestbit. Qed.
Equivalence of shifts, index in N or nat

forall (a : N) (n : nat), N.shiftr_nat a (S n) = N.div2 (N.shiftr_nat a n)

forall (a : N) (n : nat), N.shiftr_nat a (S n) = N.div2 (N.shiftr_nat a n)
reflexivity. Qed.

forall (a : N) (n : nat), N.shiftl_nat a (S n) = N.double (N.shiftl_nat a n)

forall (a : N) (n : nat), N.shiftl_nat a (S n) = N.double (N.shiftl_nat a n)
reflexivity. Qed.

forall a n : N, N.shiftr_nat a (N.to_nat n) = N.shiftr a n

forall a n : N, N.shiftr_nat a (N.to_nat n) = N.shiftr a n
a:N

a = a
a:N
n:positive
N.shiftr_nat a (Pos.to_nat n) = Pos.iter N.div2 a n
a:N

a = a
a:N
n:positive
N.shiftr_nat a (Pos.to_nat n) = Pos.iter N.div2 a n
a:N
n:positive

N.shiftr_nat a (Pos.to_nat n) = Pos.iter N.div2 a n
a:N
n:positive

Pos.iter N.div2 a n = N.shiftr_nat a (Pos.to_nat n)
apply Pos2Nat.inj_iter. Qed.

forall (a : N) (n : nat), N.shiftr a (N.of_nat n) = N.shiftr_nat a n

forall (a : N) (n : nat), N.shiftr a (N.of_nat n) = N.shiftr_nat a n
a:N
n:nat

N.shiftr a (N.of_nat n) = N.shiftr_nat a n
now rewrite <- Nshiftr_nat_equiv, Nat2N.id. Qed.

forall a n : N, N.shiftl_nat a (N.to_nat n) = N.shiftl a n

forall a n : N, N.shiftl_nat a (N.to_nat n) = N.shiftl a n
n:positive

nat_rect (fun _ : nat => N) 0 (fun _ : nat => N.double) (Pos.to_nat n) = 0
a, n:positive
nat_rect (fun _ : nat => N) (N.pos a) (fun _ : nat => N.double) (Pos.to_nat n) = N.pos (Pos.iter xO a n)
a, n:positive

nat_rect (fun _ : nat => N) (N.pos a) (fun _ : nat => N.double) (Pos.to_nat n) = N.pos (Pos.iter xO a n)
a, n:positive

Pos.iter N.double (N.pos a) n = N.pos (Pos.iter xO a n)
a, n:positive

N.pos (Pos.iter xO a n) = Pos.iter N.double (N.pos a) n
now apply Pos.iter_swap_gen. Qed.

forall (a : N) (n : nat), N.shiftl a (N.of_nat n) = N.shiftl_nat a n

forall (a : N) (n : nat), N.shiftl a (N.of_nat n) = N.shiftl_nat a n
a:N
n:nat

N.shiftl a (N.of_nat n) = N.shiftl_nat a n
now rewrite <- Nshiftl_nat_equiv, Nat2N.id. Qed.
Correctness proofs for shifts, nat version

forall (a : N) (n m : nat), N.testbit_nat (N.shiftr_nat a n) m = N.testbit_nat a (m + n)

forall (a : N) (n m : nat), N.testbit_nat (N.shiftr_nat a n) m = N.testbit_nat a (m + n)
a:N
m:nat

N.testbit_nat (N.shiftr_nat a 0) m = N.testbit_nat a (m + 0)
a:N
n:nat
IHn:forall m0 : nat, N.testbit_nat (N.shiftr_nat a n) m0 = N.testbit_nat a (m0 + n)
m:nat
N.testbit_nat (N.shiftr_nat a (S n)) m = N.testbit_nat a (m + S n)
a:N
n:nat
IHn:forall m0 : nat, N.testbit_nat (N.shiftr_nat a n) m0 = N.testbit_nat a (m0 + n)
m:nat

N.testbit_nat (N.shiftr_nat a (S n)) m = N.testbit_nat a (m + S n)
a:N
n:nat
IHn:forall m0 : nat, N.testbit_nat (N.shiftr_nat a n) m0 = N.testbit_nat a (m0 + n)
m:nat

N.testbit_nat (N.div2 (N.shiftr_nat a n)) m = N.testbit_nat a (m + S n)
a:N
n:nat
IHn:forall m0 : nat, N.testbit_nat (N.shiftr_nat a n) m0 = N.testbit_nat a (m0 + n)
m:nat

N.testbit_nat (N.div2 (N.shiftr_nat a n)) m = N.testbit_nat (N.shiftr_nat a n) (S m)
destruct (N.shiftr_nat a n) as [|[p|p|]]; simpl; trivial. Qed.

forall (a : N) (n m : nat), (n <= m)%nat -> N.testbit_nat (N.shiftl_nat a n) m = N.testbit_nat a (m - n)

forall (a : N) (n m : nat), (n <= m)%nat -> N.testbit_nat (N.shiftl_nat a n) m = N.testbit_nat a (m - n)
a:N
m:nat
H:(0 <= m)%nat

N.testbit_nat (N.shiftl_nat a 0) m = N.testbit_nat a (m - 0)
a:N
n:nat
IHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)
m:nat
H:(S n <= m)%nat
N.testbit_nat (N.shiftl_nat a (S n)) m = N.testbit_nat a (m - S n)
a:N
m:nat
H:(0 <= m)%nat

N.testbit_nat (N.shiftl_nat a 0) m = N.testbit_nat a (m - 0)
now rewrite Nat.sub_0_r.
a:N
n:nat
IHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)
m:nat
H:(S n <= m)%nat

N.testbit_nat (N.shiftl_nat a (S n)) m = N.testbit_nat a (m - S n)
a:N
n:nat
IHn:forall m : nat, (n <= m)%nat -> N.testbit_nat (N.shiftl_nat a n) m = N.testbit_nat a (m - n)
H:(S n <= 0)%nat

N.testbit_nat (N.shiftl_nat a (S n)) 0 = N.testbit_nat a (0 - S n)
a:N
n:nat
IHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)
m:nat
H:(S n <= S m)%nat
N.testbit_nat (N.shiftl_nat a (S n)) (S m) = N.testbit_nat a (S m - S n)
a:N
n:nat
IHn:forall m : nat, (n <= m)%nat -> N.testbit_nat (N.shiftl_nat a n) m = N.testbit_nat a (m - n)
H:(S n <= 0)%nat

N.testbit_nat (N.shiftl_nat a (S n)) 0 = N.testbit_nat a (0 - S n)
inversion H.
a:N
n:nat
IHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)
m:nat
H:(S n <= S m)%nat

N.testbit_nat (N.shiftl_nat a (S n)) (S m) = N.testbit_nat a (S m - S n)
a:N
n:nat
IHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)
m:nat
H:(n <= m)%nat

N.testbit_nat (N.shiftl_nat a (S n)) (S m) = N.testbit_nat a (S m - S n)
a:N
n:nat
IHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)
m:nat
H:(n <= m)%nat

N.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = N.testbit_nat a (m - n)
a:N
n:nat
IHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)
m:nat
H:(n <= m)%nat

N.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = N.testbit_nat (N.shiftl_nat a n) m
destruct (N.shiftl_nat a n) as [|[p|p|]]; simpl; trivial. Qed.

forall (a : N) (n m : nat), (m < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m = false

forall (a : N) (n m : nat), (m < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m = false
a:N
m:nat
H:(m < 0)%nat

N.testbit_nat (N.shiftl_nat a 0) m = false
a:N
n:nat
IHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = false
m:nat
H:(m < S n)%nat
N.testbit_nat (N.shiftl_nat a (S n)) m = false
a:N
n:nat
IHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = false
m:nat
H:(m < S n)%nat

N.testbit_nat (N.shiftl_nat a (S n)) m = false
a:N
n:nat
IHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = false
m:nat
H:(m < S n)%nat

N.testbit_nat (N.double (N.shiftl_nat a n)) m = false
a:N
n:nat
IHn:forall m : nat, (m < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m = false
H:(0 < S n)%nat

N.testbit_nat (N.double (N.shiftl_nat a n)) 0 = false
a:N
n:nat
IHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = false
m:nat
H:(S m < S n)%nat
N.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = false
a:N
n:nat
IHn:forall m : nat, (m < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m = false
H:(0 < S n)%nat

N.testbit_nat (N.double (N.shiftl_nat a n)) 0 = false
destruct (N.shiftl_nat a n); trivial.
a:N
n:nat
IHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = false
m:nat
H:(S m < S n)%nat

N.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = false
a:N
n:nat
IHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = false
m:nat
H:(m < n)%nat

N.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = false
a:N
n, m:nat
IHn:N.testbit_nat (N.shiftl_nat a n) m = false
H:(m < n)%nat

N.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = false
destruct (N.shiftl_nat a n); trivial. Qed.
A left shift for positive numbers (used in BigN)

forall p : positive, Pos.shiftl_nat p 0 = p

forall p : positive, Pos.shiftl_nat p 0 = p
reflexivity. Qed.

forall (p : positive) (n : nat), Pos.shiftl_nat p (S n) = ((Pos.shiftl_nat p n)~0)%positive

forall (p : positive) (n : nat), Pos.shiftl_nat p (S n) = ((Pos.shiftl_nat p n)~0)%positive
reflexivity. Qed.

forall (p : positive) (n : nat), N.pos (Pos.shiftl_nat p n) = N.shiftl_nat (N.pos p) n

forall (p : positive) (n : nat), N.pos (Pos.shiftl_nat p n) = N.shiftl_nat (N.pos p) n

forall (p : positive) (n : nat), N.pos (nat_rect (fun _ : nat => positive) p (fun _ : nat => xO) n) = nat_rect (fun _ : nat => N) (N.pos p) (fun _ : nat => N.double) n
p:positive
n:nat
IHn:N.pos (nat_rect (fun _ : nat => positive) p (fun _ : nat => xO) n) = nat_rect (fun _ : nat => N) (N.pos p) (fun _ : nat => N.double) n

N.pos (nat_rect (fun _ : nat => positive) p (fun _ : nat => xO) n)~0 = N.double (nat_rect (fun _ : nat => N) (N.pos p) (fun _ : nat => N.double) n)
now rewrite <- IHn. Qed.

forall (n m : nat) (p : positive), Pos.shiftl_nat p (m + n) = Pos.shiftl_nat (Pos.shiftl_nat p n) m

forall (n m : nat) (p : positive), Pos.shiftl_nat p (m + n) = Pos.shiftl_nat (Pos.shiftl_nat p n) m
n:nat
p:positive

Pos.shiftl_nat p n = Pos.shiftl_nat p n
n, m:nat
IHm:forall p0 : positive, Pos.shiftl_nat p0 (m + n) = Pos.shiftl_nat (Pos.shiftl_nat p0 n) m
p:positive
((Pos.shiftl_nat p (m + n))~0)%positive = ((Pos.shiftl_nat (Pos.shiftl_nat p n) m)~0)%positive
n, m:nat
IHm:forall p0 : positive, Pos.shiftl_nat p0 (m + n) = Pos.shiftl_nat (Pos.shiftl_nat p0 n) m
p:positive

((Pos.shiftl_nat p (m + n))~0)%positive = ((Pos.shiftl_nat (Pos.shiftl_nat p n) m)~0)%positive
now f_equal. Qed.
Semantics of bitwise operations with respect to N.testbit_nat
p, p':positive
n:nat

N.testbit_nat (Pos.lxor p p') n = xorb (Pos.testbit_nat p n) (Pos.testbit_nat p' n)
p, p':positive
n:nat

N.testbit_nat (Pos.lxor p p') n = xorb (Pos.testbit_nat p n) (Pos.testbit_nat p' n)
p, p':positive
n:nat

N.testbit (Pos.lxor p p') (N.of_nat n) = xorb (Pos.testbit p (N.of_nat n)) (Pos.testbit p' (N.of_nat n))
apply N.pos_lxor_spec. Qed.
a, a':N
n:nat

N.testbit_nat (N.lxor a a') n = xorb (N.testbit_nat a n) (N.testbit_nat a' n)
a, a':N
n:nat

N.testbit_nat (N.lxor a a') n = xorb (N.testbit_nat a n) (N.testbit_nat a' n)
a, a':N
n:nat

N.testbit (N.lxor a a') (N.of_nat n) = xorb (N.testbit a (N.of_nat n)) (N.testbit a' (N.of_nat n))
apply N.lxor_spec. Qed.
p, p':positive
n:nat

Pos.testbit_nat (Pos.lor p p') n = Pos.testbit_nat p n || Pos.testbit_nat p' n
p, p':positive
n:nat

Pos.testbit_nat (Pos.lor p p') n = Pos.testbit_nat p n || Pos.testbit_nat p' n
p, p':positive
n:nat

Pos.testbit (Pos.lor p p') (N.of_nat n) = Pos.testbit p (N.of_nat n) || Pos.testbit p' (N.of_nat n)
apply N.pos_lor_spec. Qed.
a, a':N
n:nat

N.testbit_nat (N.lor a a') n = N.testbit_nat a n || N.testbit_nat a' n
a, a':N
n:nat

N.testbit_nat (N.lor a a') n = N.testbit_nat a n || N.testbit_nat a' n
a, a':N
n:nat

N.testbit (N.lor a a') (N.of_nat n) = N.testbit a (N.of_nat n) || N.testbit a' (N.of_nat n)
apply N.lor_spec. Qed.
p, p':positive
n:nat

N.testbit_nat (Pos.land p p') n = Pos.testbit_nat p n && Pos.testbit_nat p' n
p, p':positive
n:nat

N.testbit_nat (Pos.land p p') n = Pos.testbit_nat p n && Pos.testbit_nat p' n
p, p':positive
n:nat

N.testbit (Pos.land p p') (N.of_nat n) = Pos.testbit p (N.of_nat n) && Pos.testbit p' (N.of_nat n)
apply N.pos_land_spec. Qed.
a, a':N
n:nat

N.testbit_nat (N.land a a') n = N.testbit_nat a n && N.testbit_nat a' n
a, a':N
n:nat

N.testbit_nat (N.land a a') n = N.testbit_nat a n && N.testbit_nat a' n
a, a':N
n:nat

N.testbit (N.land a a') (N.of_nat n) = N.testbit a (N.of_nat n) && N.testbit a' (N.of_nat n)
apply N.land_spec. Qed.
p, p':positive
n:nat

N.testbit_nat (Pos.ldiff p p') n = Pos.testbit_nat p n && negb (Pos.testbit_nat p' n)
p, p':positive
n:nat

N.testbit_nat (Pos.ldiff p p') n = Pos.testbit_nat p n && negb (Pos.testbit_nat p' n)
p, p':positive
n:nat

N.testbit (Pos.ldiff p p') (N.of_nat n) = Pos.testbit p (N.of_nat n) && negb (Pos.testbit p' (N.of_nat n))
apply N.pos_ldiff_spec. Qed.
a, a':N
n:nat

N.testbit_nat (N.ldiff a a') n = N.testbit_nat a n && negb (N.testbit_nat a' n)
a, a':N
n:nat

N.testbit_nat (N.ldiff a a') n = N.testbit_nat a n && negb (N.testbit_nat a' n)
a, a':N
n:nat

N.testbit (N.ldiff a a') (N.of_nat n) = N.testbit a (N.of_nat n) && negb (N.testbit a' (N.of_nat n))
apply N.ldiff_spec. Qed.
Equality over functional streams of bits
Definition eqf (f g:nat -> bool) := forall n:nat, f n = g n.

Instance eqf_equiv : Equivalence eqf.

Local Infix "==" := eqf (at level 70, no associativity).
If two numbers produce the same stream of bits, they are equal.
Notation Step H := (fun n => H (S n)).


forall p : positive, ~ Pos.testbit_nat p == (fun _ : nat => false)

forall p : positive, ~ Pos.testbit_nat p == (fun _ : nat => false)
p:positive
IHp:~ Pos.testbit_nat p == (fun _ : nat => false)
H:Pos.testbit_nat p~0 == (fun _ : nat => false)

False
apply (IHp (Step H)). Qed.

forall p p' : positive, Pos.testbit_nat p == Pos.testbit_nat p' -> p = p'

forall p p' : positive, Pos.testbit_nat p == Pos.testbit_nat p' -> p = p'
p:positive
IHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0
p':positive
H:Pos.testbit_nat p~1 == Pos.testbit_nat p'~1

(p~1)%positive = (p'~1)%positive
p:positive
IHp:forall p' : positive, Pos.testbit_nat p == Pos.testbit_nat p' -> p = p'
H:Pos.testbit_nat p~1 == Pos.testbit_nat 1
(p~1)%positive = 1%positive
p:positive
IHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0
p':positive
H:Pos.testbit_nat p~0 == Pos.testbit_nat p'~0
(p~0)%positive = (p'~0)%positive
p':positive
H:Pos.testbit_nat 1 == Pos.testbit_nat p'~1
1%positive = (p'~1)%positive
p:positive
IHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0
p':positive
H:Pos.testbit_nat p~1 == Pos.testbit_nat p'~1

p = p'
p:positive
IHp:forall p' : positive, Pos.testbit_nat p == Pos.testbit_nat p' -> p = p'
H:Pos.testbit_nat p~1 == Pos.testbit_nat 1
(p~1)%positive = 1%positive
p:positive
IHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0
p':positive
H:Pos.testbit_nat p~0 == Pos.testbit_nat p'~0
(p~0)%positive = (p'~0)%positive
p':positive
H:Pos.testbit_nat 1 == Pos.testbit_nat p'~1
1%positive = (p'~1)%positive
p:positive
IHp:forall p' : positive, Pos.testbit_nat p == Pos.testbit_nat p' -> p = p'
H:Pos.testbit_nat p~1 == Pos.testbit_nat 1

(p~1)%positive = 1%positive
p:positive
IHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0
p':positive
H:Pos.testbit_nat p~0 == Pos.testbit_nat p'~0
(p~0)%positive = (p'~0)%positive
p':positive
H:Pos.testbit_nat 1 == Pos.testbit_nat p'~1
1%positive = (p'~1)%positive
p:positive
IHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0
p':positive
H:Pos.testbit_nat p~0 == Pos.testbit_nat p'~0

(p~0)%positive = (p'~0)%positive
p':positive
H:Pos.testbit_nat 1 == Pos.testbit_nat p'~1
1%positive = (p'~1)%positive
p:positive
IHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0
p':positive
H:Pos.testbit_nat p~0 == Pos.testbit_nat p'~0

p = p'
p':positive
H:Pos.testbit_nat 1 == Pos.testbit_nat p'~1
1%positive = (p'~1)%positive
p':positive
H:Pos.testbit_nat 1 == Pos.testbit_nat p'~1

1%positive = (p'~1)%positive
p':positive
H:Pos.testbit_nat p'~1 == Pos.testbit_nat 1

1%positive = (p'~1)%positive
destruct (Pbit_faithful_0 _ (Step H)). Qed.

forall n n' : N, N.testbit_nat n == N.testbit_nat n' -> n = n'

forall n n' : N, N.testbit_nat n == N.testbit_nat n' -> n = n'
p':positive
H:N.testbit_nat 0 == N.testbit_nat (N.pos p')

0 = N.pos p'
p:positive
H:N.testbit_nat (N.pos p) == N.testbit_nat 0
N.pos p = 0
p, p':positive
H:N.testbit_nat (N.pos p) == N.testbit_nat (N.pos p')
N.pos p = N.pos p'
p':positive
H:N.testbit_nat (N.pos p') == N.testbit_nat 0

0 = N.pos p'
p:positive
H:N.testbit_nat (N.pos p) == N.testbit_nat 0
N.pos p = 0
p, p':positive
H:N.testbit_nat (N.pos p) == N.testbit_nat (N.pos p')
N.pos p = N.pos p'
p:positive
H:N.testbit_nat (N.pos p) == N.testbit_nat 0

N.pos p = 0
p, p':positive
H:N.testbit_nat (N.pos p) == N.testbit_nat (N.pos p')
N.pos p = N.pos p'
p, p':positive
H:N.testbit_nat (N.pos p) == N.testbit_nat (N.pos p')

N.pos p = N.pos p'
p, p':positive
H:N.testbit_nat (N.pos p) == N.testbit_nat (N.pos p')

p = p'
apply Pbit_faithful, H. Qed.

forall n n' : N, N.testbit_nat n == N.testbit_nat n' <-> n = n'

forall n n' : N, N.testbit_nat n == N.testbit_nat n' <-> n = n'
n, n':N

N.testbit_nat n == N.testbit_nat n' -> n = n'
n, n':N
n = n' -> N.testbit_nat n == N.testbit_nat n'
n, n':N

n = n' -> N.testbit_nat n == N.testbit_nat n'
intros; now subst. Qed. Local Close Scope N_scope.
Checking whether a number is odd, i.e. if its lower bit is set.
Notation Nbit0 := N.odd (only parsing).

Definition Nodd (n:N) := N.odd n = true.
Definition Neven (n:N) := N.odd n = false.


forall n : N, N.testbit_nat n 0 = N.odd n

forall n : N, N.testbit_nat n 0 = N.odd n
p:positive

N.testbit_nat (N.pos p) 0 = N.odd (N.pos p)
destruct p; trivial. Qed.

forall n : N, N.odd (N.double n) = false

forall n : N, N.odd (N.double n) = false
destruct n; trivial. Qed.

forall n : N, N.odd (N.succ_double n) = true

forall n : N, N.odd (N.succ_double n) = true
destruct n; trivial. Qed.

forall n : N, Neven n -> N.double (N.div2 n) = n

forall n : N, Neven n -> N.double (N.div2 n) = n

Neven 0 -> N.double (N.div2 0) = 0%N
p:positive
Neven (N.pos p) -> N.double (N.div2 (N.pos p)) = N.pos p
p:positive

Neven (N.pos p) -> N.double (N.div2 (N.pos p)) = N.pos p
p:positive

Neven (N.pos p~1) -> N.double (N.div2 (N.pos p~1)) = N.pos p~1
p:positive
Neven (N.pos p~0) -> N.double (N.div2 (N.pos p~0)) = N.pos p~0

Neven 1 -> N.double (N.div2 1) = 1%N
p:positive
H:Neven (N.pos p~1)

N.double (N.div2 (N.pos p~1)) = N.pos p~1
p:positive
Neven (N.pos p~0) -> N.double (N.div2 (N.pos p~0)) = N.pos p~0

Neven 1 -> N.double (N.div2 1) = 1%N
p:positive

Neven (N.pos p~0) -> N.double (N.div2 (N.pos p~0)) = N.pos p~0

Neven 1 -> N.double (N.div2 1) = 1%N
p:positive
H:Neven (N.pos p~0)

N.double (N.div2 (N.pos p~0)) = N.pos p~0

Neven 1 -> N.double (N.div2 1) = 1%N

Neven 1 -> N.double (N.div2 1) = 1%N
H:Neven 1

N.double (N.div2 1) = 1%N
discriminate H. Qed.

forall n : N, Nodd n -> N.succ_double (N.div2 n) = n

forall n : N, Nodd n -> N.succ_double (N.div2 n) = n

Nodd 0 -> N.succ_double (N.div2 0) = 0%N
p:positive
Nodd (N.pos p) -> N.succ_double (N.div2 (N.pos p)) = N.pos p
H:Nodd 0

N.succ_double (N.div2 0) = 0%N
p:positive
Nodd (N.pos p) -> N.succ_double (N.div2 (N.pos p)) = N.pos p
p:positive

Nodd (N.pos p) -> N.succ_double (N.div2 (N.pos p)) = N.pos p
p:positive

Nodd (N.pos p~1) -> N.succ_double (N.div2 (N.pos p~1)) = N.pos p~1
p:positive
Nodd (N.pos p~0) -> N.succ_double (N.div2 (N.pos p~0)) = N.pos p~0

Nodd 1 -> N.succ_double (N.div2 1) = 1%N
p:positive
H:Nodd (N.pos p~1)

N.succ_double (N.div2 (N.pos p~1)) = N.pos p~1
p:positive
Nodd (N.pos p~0) -> N.succ_double (N.div2 (N.pos p~0)) = N.pos p~0

Nodd 1 -> N.succ_double (N.div2 1) = 1%N
p:positive

Nodd (N.pos p~0) -> N.succ_double (N.div2 (N.pos p~0)) = N.pos p~0

Nodd 1 -> N.succ_double (N.div2 1) = 1%N
p:positive
H:Nodd (N.pos p~0)

N.succ_double (N.div2 (N.pos p~0)) = N.pos p~0

Nodd 1 -> N.succ_double (N.div2 1) = 1%N

Nodd 1 -> N.succ_double (N.div2 1) = 1%N
H:Nodd 1

N.succ_double (N.div2 1) = 1%N
reflexivity. Qed.

forall (a : N) (n : nat), N.testbit_nat (N.div2 a) n = N.testbit_nat a (S n)

forall (a : N) (n : nat), N.testbit_nat (N.div2 a) n = N.testbit_nat a (S n)
p:positive

forall n : nat, N.testbit_nat (N.div2 (N.pos p)) n = N.testbit_nat (N.pos p) (S n)
destruct p; trivial. Qed.

forall a a' : N, N.odd (N.lxor a a') = xorb (N.odd a) (N.odd a')

forall a a' : N, N.odd (N.lxor a a') = xorb (N.odd a) (N.odd a')
a, a':N

N.odd (N.lxor a a') = xorb (N.odd a) (N.odd a')
a, a':N

xorb (N.testbit_nat a 0) (N.testbit_nat a' 0) = xorb (N.odd a) (N.odd a')
a, a':N

xorb (N.odd a) (N.odd a') = xorb (N.odd a) (N.odd a')
reflexivity. Qed.

forall a a' : N, N.div2 (N.lxor a a') = N.lxor (N.div2 a) (N.div2 a')

forall a a' : N, N.div2 (N.lxor a a') = N.lxor (N.div2 a) (N.div2 a')
a, a':N

N.div2 (N.lxor a a') = N.lxor (N.div2 a) (N.div2 a')
a, a':N

N.testbit_nat (N.div2 (N.lxor a a')) == N.testbit_nat (N.lxor (N.div2 a) (N.div2 a'))
a, a':N

forall n : nat, N.testbit_nat (N.div2 (N.lxor a a')) n = N.testbit_nat (N.lxor (N.div2 a) (N.div2 a')) n
a, a':N
n:nat

N.testbit_nat (N.div2 (N.lxor a a')) n = N.testbit_nat (N.lxor (N.div2 a) (N.div2 a')) n
a, a':N
n:nat

xorb (N.testbit_nat a (S n)) (N.testbit_nat a' (S n)) = xorb (N.testbit_nat (N.div2 a) n) (N.testbit_nat (N.div2 a') n)
a, a':N
n:nat

xorb (N.testbit_nat a (S n)) (N.testbit_nat a' (S n)) = xorb (N.testbit_nat a (S n)) (N.testbit_nat a' (S n))
reflexivity. Qed.

forall a a' : N, N.odd (N.lxor a a') = true -> N.odd a = negb (N.odd a')

forall a a' : N, N.odd (N.lxor a a') = true -> N.odd a = negb (N.odd a')
a, a':N
H:N.odd (N.lxor a a') = true

N.odd a = negb (N.odd a')
a, a':N
H:N.odd (N.lxor a a') = true

N.odd a = N.odd a
reflexivity. Qed.

forall a a' : N, N.lxor a a' = 1%N -> N.odd a = negb (N.odd a')

forall a a' : N, N.lxor a a' = 1%N -> N.odd a = negb (N.odd a')
a, a':N
H:N.lxor a a' = 1%N

N.odd a = negb (N.odd a')
a, a':N
H:N.lxor a a' = 1%N

N.odd (N.lxor a a') = true
a, a':N
H:N.lxor a a' = 1%N

N.odd 1 = true
reflexivity. Qed.

forall (a a' : N) (p : positive), N.lxor a a' = N.pos p~1 -> N.odd a = negb (N.odd a')

forall (a a' : N) (p : positive), N.lxor a a' = N.pos p~1 -> N.odd a = negb (N.odd a')
a, a':N
p:positive
H:N.lxor a a' = N.pos p~1

N.odd a = negb (N.odd a')
a, a':N
p:positive
H:N.lxor a a' = N.pos p~1

N.odd (N.lxor a a') = true
a, a':N
p:positive
H:N.lxor a a' = N.pos p~1

N.odd (N.pos p~1) = true
reflexivity. Qed.

forall (a a' : N) (p : positive), N.lxor a a' = N.pos p~0 -> N.odd a = N.odd a'

forall (a a' : N) (p : positive), N.lxor a a' = N.pos p~0 -> N.odd a = N.odd a'
a, a':N
p:positive
H:N.lxor a a' = N.pos p~0

N.odd a = N.odd a'
a, a':N
p:positive
H:N.lxor a a' = N.pos p~0

xorb (N.odd a) false = N.odd a'
a, a':N
p:positive
H:N.lxor a a' = N.pos p~0
H0:N.odd (N.pos p~0) = false

xorb (N.odd a) false = N.odd a'
a, a':N
p:positive
H:N.lxor a a' = N.pos p~0
H0:N.odd (N.pos p~0) = false

N.odd a' = N.odd a'
reflexivity. Qed.
a lexicographic order on bits, starting from the lowest bit
Fixpoint Nless_aux (a a':N) (p:positive) : bool :=
  match p with
  | xO p' => Nless_aux (N.div2 a) (N.div2 a') p'
  | _ => andb (negb (N.odd a)) (N.odd a')
  end.

Definition Nless (a a':N) :=
  match N.lxor a a' with
  | N0 => false
  | Npos p => Nless_aux a a' p
  end.


forall a a' : N, N.odd a = false -> N.odd a' = true -> Nless a a' = true

forall a a' : N, N.odd a = false -> N.odd a' = true -> Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true

Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p

Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p

match N.lxor a a' with | 0%N => false | N.pos p0 => Nless_aux a a' p0 end = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p

Nless_aux a a' p = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p~1

Nless_aux a a' p~1 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p~0
Nless_aux a a' p~0 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p~1

negb (N.odd a) && N.odd a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p~0
Nless_aux a a' p~0 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p~1

negb false && true = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p~0
Nless_aux a a' p~0 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p~0

Nless_aux a a' p~0 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p~0
H1:N.odd (N.lxor a a') = false

Nless_aux a a' p~0 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
p:positive
H2:N.lxor a a' = N.pos p~0
H1:xorb false true = false

Nless_aux a a' p~0 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H2:N.lxor a a' = 1%N

Nless_aux a a' 1 = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H2:N.lxor a a' = 1%N

negb (N.odd a) && N.odd a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H2:N.lxor a a' = 1%N

negb false && true = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N

Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
H2:N.odd (N.lxor a a') = false

Nless a a' = true
a, a':N
H:N.odd a = false
H0:N.odd a' = true
H1:N.lxor a a' = 0%N
H2:xorb false true = false

Nless a a' = true
discriminate H2. Qed.

forall a a' : N, N.odd a = true -> N.odd a' = false -> Nless a a' = false

forall a a' : N, N.odd a = true -> N.odd a' = false -> Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false

Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p

Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p

match N.lxor a a' with | 0%N => false | N.pos p0 => Nless_aux a a' p0 end = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p

Nless_aux a a' p = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p~1

Nless_aux a a' p~1 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p~0
Nless_aux a a' p~0 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p~1

negb (N.odd a) && N.odd a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p~0
Nless_aux a a' p~0 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p~1

negb true && false = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p~0
Nless_aux a a' p~0 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p~0

Nless_aux a a' p~0 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p~0
H1:N.odd (N.lxor a a') = false

Nless_aux a a' p~0 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
p:positive
H2:N.lxor a a' = N.pos p~0
H1:xorb true false = false

Nless_aux a a' p~0 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H2:N.lxor a a' = 1%N
Nless_aux a a' 1 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H2:N.lxor a a' = 1%N

Nless_aux a a' 1 = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H2:N.lxor a a' = 1%N

negb (N.odd a) && N.odd a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H2:N.lxor a a' = 1%N

negb true && false = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N

Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
H2:N.odd (N.lxor a a') = false

Nless a a' = false
a, a':N
H:N.odd a = true
H0:N.odd a' = false
H1:N.lxor a a' = 0%N
H2:xorb true false = false

Nless a a' = false
discriminate H2. Qed.

forall a : N, Nless a a = false

forall a : N, Nless a a = false
a:N

Nless a a = false
a:N

match N.lxor a a with | 0%N => false | N.pos p => Nless_aux a a p end = false
a:N

false = false
reflexivity. Qed.

forall a a' : N, Nless (N.double a) (N.double a') = Nless a a'

forall a a' : N, Nless (N.double a) (N.double a') = Nless a a'

Nless (N.double 0) (N.double 0) = Nless 0 0
p:positive
Nless (N.double 0) (N.double (N.pos p)) = Nless 0 (N.pos p)
p:positive
Nless (N.double (N.pos p)) (N.double 0) = Nless (N.pos p) 0
p, p0:positive
Nless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p:positive

Nless (N.double 0) (N.double (N.pos p)) = Nless 0 (N.pos p)
p:positive
Nless (N.double (N.pos p)) (N.double 0) = Nless (N.pos p) 0
p, p0:positive
Nless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p:positive

Nless (N.double (N.pos p)) (N.double 0) = Nless (N.pos p) 0
p, p0:positive
Nless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p:positive

match N.lxor (N.double (N.pos p)) (N.double 0) with | 0%N => false | N.pos p0 => Nless_aux (N.double (N.pos p)) (N.double 0) p0 end = match N.lxor (N.pos p) 0 with | 0%N => false | N.pos p0 => Nless_aux (N.pos p) 0 p0 end
p, p0:positive
Nless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p:positive

Nless_aux (N.pos p) 0 p = Nless_aux (N.pos p) 0 p
p, p0:positive
Nless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p, p0:positive

Nless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p, p0:positive

match N.lxor (N.double (N.pos p)) (N.double (N.pos p0)) with | 0%N => false | N.pos p1 => Nless_aux (N.double (N.pos p)) (N.double (N.pos p0)) p1 end = match N.lxor (N.pos p) (N.pos p0) with | 0%N => false | N.pos p1 => Nless_aux (N.pos p) (N.pos p0) p1 end
p, p0:positive

match Pos.Ndouble (Pos.lxor p p0) with | 0%N => false | N.pos p1 => Nless_aux (N.pos p~0) (N.pos p0~0) p1 end = match Pos.lxor p p0 with | 0%N => false | N.pos p1 => Nless_aux (N.pos p) (N.pos p0) p1 end
p, p0:positive

match Pos.Ndouble 0 with | 0%N => false | N.pos p1 => Nless_aux (N.pos p~0) (N.pos p0~0) p1 end = false
p, p0, p1:positive
match Pos.Ndouble (N.pos p1) with | 0%N => false | N.pos p2 => Nless_aux (N.pos p~0) (N.pos p0~0) p2 end = Nless_aux (N.pos p) (N.pos p0) p1
p, p0, p1:positive

match Pos.Ndouble (N.pos p1) with | 0%N => false | N.pos p2 => Nless_aux (N.pos p~0) (N.pos p0~0) p2 end = Nless_aux (N.pos p) (N.pos p0) p1
trivial. Qed.

forall a a' : N, Nless (N.succ_double a) (N.succ_double a') = Nless a a'

forall a a' : N, Nless (N.succ_double a) (N.succ_double a') = Nless a a'

Nless (N.succ_double 0) (N.succ_double 0) = Nless 0 0
p:positive
Nless (N.succ_double 0) (N.succ_double (N.pos p)) = Nless 0 (N.pos p)
p:positive
Nless (N.succ_double (N.pos p)) (N.succ_double 0) = Nless (N.pos p) 0
p, p0:positive
Nless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p:positive

Nless (N.succ_double 0) (N.succ_double (N.pos p)) = Nless 0 (N.pos p)
p:positive
Nless (N.succ_double (N.pos p)) (N.succ_double 0) = Nless (N.pos p) 0
p, p0:positive
Nless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p:positive

Nless (N.succ_double (N.pos p)) (N.succ_double 0) = Nless (N.pos p) 0
p, p0:positive
Nless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p:positive

match N.lxor (N.succ_double (N.pos p)) (N.succ_double 0) with | 0%N => false | N.pos p0 => Nless_aux (N.succ_double (N.pos p)) (N.succ_double 0) p0 end = match N.lxor (N.pos p) 0 with | 0%N => false | N.pos p0 => Nless_aux (N.pos p) 0 p0 end
p, p0:positive
Nless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p:positive

Nless_aux (N.pos p) 0 p = Nless_aux (N.pos p) 0 p
p, p0:positive
Nless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p, p0:positive

Nless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)
p, p0:positive

match N.lxor (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) with | 0%N => false | N.pos p1 => Nless_aux (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) p1 end = match N.lxor (N.pos p) (N.pos p0) with | 0%N => false | N.pos p1 => Nless_aux (N.pos p) (N.pos p0) p1 end
p, p0:positive

match Pos.Ndouble (Pos.lxor p p0) with | 0%N => false | N.pos p1 => Nless_aux (N.pos p~1) (N.pos p0~1) p1 end = match Pos.lxor p p0 with | 0%N => false | N.pos p1 => Nless_aux (N.pos p) (N.pos p0) p1 end
p, p0:positive

match Pos.Ndouble 0 with | 0%N => false | N.pos p1 => Nless_aux (N.pos p~1) (N.pos p0~1) p1 end = false
p, p0, p1:positive
match Pos.Ndouble (N.pos p1) with | 0%N => false | N.pos p2 => Nless_aux (N.pos p~1) (N.pos p0~1) p2 end = Nless_aux (N.pos p) (N.pos p0) p1
p, p0, p1:positive

match Pos.Ndouble (N.pos p1) with | 0%N => false | N.pos p2 => Nless_aux (N.pos p~1) (N.pos p0~1) p2 end = Nless_aux (N.pos p) (N.pos p0) p1
trivial. Qed.

forall a a' : N, Nless (N.double a) (N.succ_double a') = true

forall a a' : N, Nless (N.double a) (N.succ_double a') = true
a, a':N

Nless (N.double a) (N.succ_double a') = true
a, a':N

N.odd (N.double a) = false
a, a':N
N.odd (N.succ_double a') = true
a, a':N

N.odd (N.succ_double a') = true
apply Ndouble_plus_one_bit0. Qed.

forall a a' : N, Nless (N.succ_double a) (N.double a') = false

forall a a' : N, Nless (N.succ_double a) (N.double a') = false
a, a':N

Nless (N.succ_double a) (N.double a') = false
a, a':N

N.odd (N.succ_double a) = true
a, a':N
N.odd (N.double a') = false
a, a':N

N.odd (N.double a') = false
apply Ndouble_bit0. Qed.

forall a : N, Nless a 0 = false

forall a : N, Nless a 0 = false

Nless 0 0 = false
p:positive
Nless (N.pos p) 0 = false
p:positive

Nless (N.pos p) 0 = false
p:positive

match N.lxor (N.pos p) 0 with | 0%N => false | N.pos p0 => Nless_aux (N.pos p) 0 p0 end = false
p:positive

Nless_aux (N.pos p) 0 p = false
induction p; trivial. Qed.

forall a : N, Nless 0 a = true -> {p : positive | a = N.pos p}

forall a : N, Nless 0 a = true -> {p : positive | a = N.pos p}

Nless 0 0 = true -> {p : positive | 0%N = N.pos p}
p:positive
Nless 0 (N.pos p) = true -> {p0 : positive | N.pos p = N.pos p0}
p:positive

Nless 0 (N.pos p) = true -> {p0 : positive | N.pos p = N.pos p0}
p:positive
H:Nless 0 (N.pos p) = true

{p0 : positive | N.pos p = N.pos p0}
p:positive
H:Nless 0 (N.pos p) = true

N.pos p = N.pos p
reflexivity. Qed.

forall a : N, Nless 0 a = false -> a = 0%N

forall a : N, Nless 0 a = false -> a = 0%N
H:Nless 0 0 = false

0%N = 0%N
p:positive
H:Nless 0 (N.pos p) = false
N.pos p = 0%N
p:positive
H:Nless 0 (N.pos p) = false

N.pos p = 0%N
p:positive
H:Nless 0 (N.pos p) = false

False
induction p as [|p IHp|]; discriminate || simpl; auto using IHp. Qed.

forall a a' a'' : N, Nless a a' = true -> Nless a' a'' = true -> Nless a a'' = true

forall a a' a'' : N, Nless a a' = true -> Nless a' a'' = true -> Nless a a'' = true
a', a'':N
H:Nless 0 a' = true
H0:Nless a' a'' = true

Nless 0 a'' = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.double a) a' = true
H0:Nless a' a'' = true
Nless (N.double a) a'' = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) a' = true
H0:Nless a' a'' = true
Nless (N.succ_double a) a'' = true
a', a'':N
H:Nless 0 a' = true
H0:Nless a' a'' = true

Nless 0 a'' = true
a', a'':N
H:Nless 0 a' = true
H0:Nless a' a'' = true
Heqn:Nless 0 a'' = true

true = true
a', a'':N
H:Nless 0 a' = true
H0:Nless a' a'' = true
Heqn:Nless 0 a'' = false
false = true
a', a'':N
H:Nless 0 a' = true
H0:Nless a' a'' = true
Heqn:Nless 0 a'' = true

true = true
trivial.
a', a'':N
H:Nless 0 a' = true
H0:Nless a' a'' = true
Heqn:Nless 0 a'' = false

false = true
a', a'':N
H:Nless 0 a' = true
H0:false = true
Heqn:Nless 0 a'' = false

false = true
discriminate H0.
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.double a) a' = true
H0:Nless a' a'' = true

Nless (N.double a) a'' = true
a:N
IHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = true
a'':N
H:Nless (N.double a) 0 = true
H0:Nless 0 a'' = true

Nless (N.double a) a'' = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.double a) (N.double a') = true
H0:Nless (N.double a') a'' = true
Nless (N.double a) a'' = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') a'' = true
Nless (N.double a) a'' = true
a:N
IHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = true
a'':N
H:Nless (N.double a) 0 = true
H0:Nless 0 a'' = true

Nless (N.double a) a'' = true
a:N
IHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = true
a'':N
H:false = true
H0:Nless 0 a'' = true

Nless (N.double a) a'' = true
discriminate H.
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.double a) (N.double a') = true
H0:Nless (N.double a') a'' = true

Nless (N.double a) a'' = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless a a' = true
H0:Nless (N.double a') a'' = true

Nless (N.double a) a'' = true
a:N
IHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = true
a':N
H:Nless a a' = true
H0:Nless (N.double a') 0 = true

Nless (N.double a) 0 = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless a a' = true
H0:Nless (N.double a') (N.double a'') = true
IHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = true
Nless (N.double a) (N.double a'') = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless a a' = true
H0:Nless (N.double a') (N.succ_double a'') = true
IHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = true
Nless (N.double a) (N.succ_double a'') = true
a:N
IHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = true
a':N
H:Nless a a' = true
H0:Nless (N.double a') 0 = true

Nless (N.double a) 0 = true
a:N
IHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = true
a':N
H:Nless a a' = true
H0:false = true

Nless (N.double a) 0 = true
discriminate H0.
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless a a' = true
H0:Nless (N.double a') (N.double a'') = true
IHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = true

Nless (N.double a) (N.double a'') = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless a a' = true
H0:Nless a' a'' = true
IHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = true

Nless (N.double a) (N.double a'') = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless a a' = true
H0:Nless a' a'' = true
IHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = true

Nless a a'' = true
exact (IHa _ _ H H0).
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless a a' = true
H0:Nless (N.double a') (N.succ_double a'') = true
IHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = true

Nless (N.double a) (N.succ_double a'') = true
apply Nless_def_3.
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') a'' = true

Nless (N.double a) a'' = true
a:N
IHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = true
a':N
H:Nless (N.double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') 0 = true

Nless (N.double a) 0 = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') (N.double a'') = true
Nless (N.double a) (N.double a'') = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') (N.succ_double a'') = true
Nless (N.double a) (N.succ_double a'') = true
a:N
IHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = true
a':N
H:Nless (N.double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') 0 = true

Nless (N.double a) 0 = true
a:N
IHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = true
a':N
H:Nless (N.double a) (N.succ_double a') = true
H0:false = true

Nless (N.double a) 0 = true
discriminate H0.
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') (N.double a'') = true

Nless (N.double a) (N.double a'') = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.double a) (N.succ_double a') = true
H0:false = true

Nless (N.double a) (N.double a'') = true
discriminate H0.
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') (N.succ_double a'') = true

Nless (N.double a) (N.succ_double a'') = true
apply Nless_def_3.
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) a' = true
H0:Nless a' a'' = true

Nless (N.succ_double a) a'' = true
a:N
IHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = true
a'':N
H:Nless (N.succ_double a) 0 = true
H0:Nless 0 a'' = true

Nless (N.succ_double a) a'' = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) (N.double a') = true
H0:Nless (N.double a') a'' = true
Nless (N.succ_double a) a'' = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') a'' = true
Nless (N.succ_double a) a'' = true
a:N
IHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = true
a'':N
H:Nless (N.succ_double a) 0 = true
H0:Nless 0 a'' = true

Nless (N.succ_double a) a'' = true
a:N
IHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = true
a'':N
H:false = true
H0:Nless 0 a'' = true

Nless (N.succ_double a) a'' = true
discriminate H.
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) (N.double a') = true
H0:Nless (N.double a') a'' = true

Nless (N.succ_double a) a'' = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:false = true
H0:Nless (N.double a') a'' = true

Nless (N.succ_double a) a'' = true
discriminate H.
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') a'' = true

Nless (N.succ_double a) a'' = true
a:N
IHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = true
a':N
H:Nless (N.succ_double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') 0 = true

Nless (N.succ_double a) 0 = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') (N.double a'') = true
IHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = true
Nless (N.succ_double a) (N.double a'') = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') (N.succ_double a'') = true
IHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = true
Nless (N.succ_double a) (N.succ_double a'') = true
a:N
IHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = true
a':N
H:Nless (N.succ_double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') 0 = true

Nless (N.succ_double a) 0 = true
a:N
IHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = true
a':N
H:Nless (N.succ_double a) (N.succ_double a') = true
H0:false = true

Nless (N.succ_double a) 0 = true
discriminate H0.
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') (N.double a'') = true
IHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = true

Nless (N.succ_double a) (N.double a'') = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) (N.succ_double a') = true
H0:false = true
IHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = true

Nless (N.succ_double a) (N.double a'') = true
discriminate H0.
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) (N.succ_double a') = true
H0:Nless (N.succ_double a') (N.succ_double a'') = true
IHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = true

Nless (N.succ_double a) (N.succ_double a'') = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless (N.succ_double a) (N.succ_double a') = true
H0:Nless a' a'' = true
IHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = true

Nless (N.succ_double a) (N.succ_double a'') = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless a a' = true
H0:Nless a' a'' = true
IHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = true

Nless (N.succ_double a) (N.succ_double a'') = true
a:N
IHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = true
a', a'':N
H:Nless a a' = true
H0:Nless a' a'' = true
IHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = true

Nless a a'' = true
exact (IHa _ _ H H0). Qed.

forall a a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}

forall a a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}
a':N

{Nless 0 a' = true} + {Nless a' 0 = true} + {0%N = a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
{Nless (N.double a) a' = true} + {Nless a' (N.double a) = true} + {N.double a = a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
{Nless (N.succ_double a) a' = true} + {Nless a' (N.succ_double a) = true} + {N.succ_double a = a'}
a':N

{Nless 0 a' = true} + {Nless a' 0 = true} + {0%N = a'}
a':N
Heqb:Nless 0 a' = true

{true = true} + {Nless a' 0 = true} + {0%N = a'}
a':N
Heqb:Nless 0 a' = false
{false = true} + {Nless a' 0 = true} + {0%N = a'}
a':N
Heqb:Nless 0 a' = true

{true = true} + {Nless a' 0 = true} + {0%N = a'}
a':N
Heqb:Nless 0 a' = true

{true = true} + {Nless a' 0 = true}
a':N
Heqb:Nless 0 a' = true

true = true
auto.
a':N
Heqb:Nless 0 a' = false

{false = true} + {Nless a' 0 = true} + {0%N = a'}
a':N
Heqb:Nless 0 a' = false

0%N = a'
a':N
Heqb:Nless 0 a' = false

0%N = 0%N
reflexivity.
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

{Nless (N.double a) a' = true} + {Nless a' (N.double a) = true} + {N.double a = a'}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}

{Nless (N.double a) 0 = true} + {Nless 0 (N.double a) = true} + {N.double a = 0%N}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
{Nless (N.double a) (N.double a') = true} + {Nless (N.double a') (N.double a) = true} + {N.double a = N.double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
{Nless (N.double a) (N.succ_double a') = true} + {Nless (N.succ_double a') (N.double a) = true} + {N.double a = N.succ_double a'}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}

{Nless (N.double a) 0 = true} + {Nless 0 (N.double a) = true} + {N.double a = 0%N}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}
Heqb:Nless 0 (N.double a) = true

{Nless (N.double a) 0 = true} + {true = true} + {N.double a = 0%N}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}
Heqb:Nless 0 (N.double a) = false
{Nless (N.double a) 0 = true} + {false = true} + {N.double a = 0%N}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}
Heqb:Nless 0 (N.double a) = true

{Nless (N.double a) 0 = true} + {true = true} + {N.double a = 0%N}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}
Heqb:Nless 0 (N.double a) = true

{Nless (N.double a) 0 = true} + {true = true}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}
Heqb:Nless 0 (N.double a) = true

true = true
auto.
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}
Heqb:Nless 0 (N.double a) = false

{Nless (N.double a) 0 = true} + {false = true} + {N.double a = 0%N}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}
Heqb:Nless 0 (N.double a) = false

N.double a = 0%N
exact (N0_less_2 _ Heqb).
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

{Nless (N.double a) (N.double a') = true} + {Nless (N.double a') (N.double a) = true} + {N.double a = N.double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

{Nless a a' = true} + {Nless a' a = true} + {N.double a = N.double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
s:{Nless a a' = true} + {Nless a' a = true}

{Nless a a' = true} + {Nless a' a = true} + {N.double a = N.double a'}
a':N
IHa:forall a'0 : N, {Nless a' a'0 = true} + {Nless a'0 a' = true} + {a' = a'0}
{Nless a' a' = true} + {Nless a' a' = true} + {N.double a' = N.double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
s:{Nless a a' = true} + {Nless a' a = true}

{Nless a a' = true} + {Nless a' a = true} + {N.double a = N.double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
s:{Nless a a' = true} + {Nless a' a = true}

{Nless a a' = true} + {Nless a' a = true}
assumption.
a':N
IHa:forall a'0 : N, {Nless a' a'0 = true} + {Nless a'0 a' = true} + {a' = a'0}

{Nless a' a' = true} + {Nless a' a' = true} + {N.double a' = N.double a'}
a':N
IHa:forall a'0 : N, {Nless a' a'0 = true} + {Nless a'0 a' = true} + {a' = a'0}

N.double a' = N.double a'
reflexivity.
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

{Nless (N.double a) (N.succ_double a') = true} + {Nless (N.succ_double a') (N.double a) = true} + {N.double a = N.succ_double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

{Nless (N.double a) (N.succ_double a') = true} + {Nless (N.succ_double a') (N.double a) = true}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

Nless (N.double a) (N.succ_double a') = true
apply Nless_def_3.
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

{Nless (N.succ_double a) a' = true} + {Nless a' (N.succ_double a) = true} + {N.succ_double a = a'}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}

{Nless (N.succ_double a) 0 = true} + {Nless 0 (N.succ_double a) = true} + {N.succ_double a = 0%N}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
{Nless (N.succ_double a) (N.double a') = true} + {Nless (N.double a') (N.succ_double a) = true} + {N.succ_double a = N.double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
{Nless (N.succ_double a) (N.succ_double a') = true} + {Nless (N.succ_double a') (N.succ_double a) = true} + {N.succ_double a = N.succ_double a'}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}

{Nless (N.succ_double a) 0 = true} + {Nless 0 (N.succ_double a) = true} + {N.succ_double a = 0%N}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}

{Nless (N.succ_double a) 0 = true} + {Nless 0 (N.succ_double a) = true}
a:N
IHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}

Nless 0 (N.succ_double a) = true
destruct a; reflexivity.
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

{Nless (N.succ_double a) (N.double a') = true} + {Nless (N.double a') (N.succ_double a) = true} + {N.succ_double a = N.double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

{Nless (N.succ_double a) (N.double a') = true} + {Nless (N.double a') (N.succ_double a) = true}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

Nless (N.double a') (N.succ_double a) = true
apply Nless_def_3.
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

{Nless (N.succ_double a) (N.succ_double a') = true} + {Nless (N.succ_double a') (N.succ_double a) = true} + {N.succ_double a = N.succ_double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N

{Nless a a' = true} + {Nless a' a = true} + {N.succ_double a = N.succ_double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
s:{Nless a a' = true} + {Nless a' a = true}

{Nless a a' = true} + {Nless a' a = true} + {N.succ_double a = N.succ_double a'}
a':N
IHa:forall a'0 : N, {Nless a' a'0 = true} + {Nless a'0 a' = true} + {a' = a'0}
{Nless a' a' = true} + {Nless a' a' = true} + {N.succ_double a' = N.succ_double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
s:{Nless a a' = true} + {Nless a' a = true}

{Nless a a' = true} + {Nless a' a = true} + {N.succ_double a = N.succ_double a'}
a:N
IHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}
a':N
s:{Nless a a' = true} + {Nless a' a = true}

{Nless a a' = true} + {Nless a' a = true}
assumption.
a':N
IHa:forall a'0 : N, {Nless a' a'0 = true} + {Nless a'0 a' = true} + {a' = a'0}

{Nless a' a' = true} + {Nless a' a' = true} + {N.succ_double a' = N.succ_double a'}
a':N
IHa:forall a'0 : N, {Nless a' a'0 = true} + {Nless a'0 a' = true} + {a' = a'0}

N.succ_double a' = N.succ_double a'
reflexivity. Qed.
Number of digits in a number
Notation Nsize := N.size_nat (only parsing).
conversions between N and bit vectors.
Fixpoint P2Bv (p:positive) : Bvector (Pos.size_nat p) :=
 match p return Bvector (Pos.size_nat p) with
   | xH => Bvect_true 1%nat
   | xO p => Bcons false (Pos.size_nat p) (P2Bv p)
   | xI p => Bcons true (Pos.size_nat p) (P2Bv p)
 end.

Definition N2Bv (n:N) : Bvector (N.size_nat n) :=
  match n as n0 return Bvector (N.size_nat n0) with
    | N0 => Bnil
    | Npos p => P2Bv p
  end.

Fixpoint P2Bv_sized (m : nat) (p : positive) : Bvector m :=
  match m with
  | O => []
  | S m =>
    match p with
    | xI p => true  :: P2Bv_sized  m p
    | xO p => false :: P2Bv_sized  m p
    | xH   => true  :: Bvect_false m
    end
  end.

Definition N2Bv_sized (m : nat) (n : N) : Bvector m :=
  match n with
  | N0     => Bvect_false m
  | Npos p => P2Bv_sized  m p
  end.

Definition N2ByteV_sized (m : nat) : N -> ByteVector m :=
  of_Bvector ∘ N2Bv_sized (m * 8).

Fixpoint Bv2N (n:nat)(bv:Bvector n) : N :=
  match bv with
    | Vector.nil _ => N0
    | Vector.cons _ false n bv => N.double (Bv2N n bv)
    | Vector.cons _ true n bv => N.succ_double (Bv2N n bv)
  end.

Arguments Bv2N {n} bv, n bv.

Definition ByteV2N {n : nat} : ByteVector n -> N :=
  Bv2N ∘ to_Bvector.


forall n : N, Bv2N (N2Bv n) = n

forall n : N, Bv2N (N2Bv n) = n

Bv2N (N2Bv 0) = 0%N
p:positive
Bv2N (N2Bv (N.pos p)) = N.pos p
p:positive

Bv2N (N2Bv (N.pos p)) = N.pos p
induction p; simpl in *; auto; rewrite IHp; simpl; auto. Qed.
The opposite composition is not so simple: if the considered bit vector has some zeros on its right, they will disappear during the return Bv2N translation:

forall (n : nat) (bv : Bvector n), N.size_nat (Bv2N bv) <= n

forall (n : nat) (bv : Bvector n), N.size_nat (Bv2N bv) <= n

N.size_nat (Bv2N []) <= 0
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:N.size_nat (Bv2N bv) <= n
N.size_nat (Bv2N (h :: bv)) <= S n
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:N.size_nat (Bv2N bv) <= n

N.size_nat (Bv2N (h :: bv)) <= S n
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:N.size_nat (Bv2N bv) <= n

N.size_nat (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) <= S n
destruct h; destruct (Bv2N n bv); simpl ; auto with arith. Qed.
In the previous lemma, we can only replace the inequality by an equality whenever the highest bit is non-null.

forall (n : nat) (bv : Bvector (S n)), Bsign n bv = true <-> N.size_nat (Bv2N bv) = S n

forall (n : nat) (bv : Bvector (S n)), Bsign n bv = true <-> N.size_nat (Bv2N bv) = S n
a:bool

a = true <-> N.size_nat (if a then 1%N else 0%N) = 1
a:bool
n:nat
v:Vector.t bool (S n)
H:Bsign n v = true <-> N.size_nat (Bv2N v) = S n
Bsign n v = true <-> N.size_nat (if a then N.succ_double (Bv2N v) else N.double (Bv2N v)) = S (S n)
a:bool
n:nat
v:Vector.t bool (S n)
H:Bsign n v = true <-> N.size_nat (Bv2N v) = S n

Bsign n v = true <-> N.size_nat (if a then N.succ_double (Bv2N v) else N.double (Bv2N v)) = S (S n)
destruct a, (Bv2N (S n) v) ; simpl ;intuition ; try discriminate. Qed.
n:nat
bv:Bvector n

(Bv2N bv < N.shiftl_nat 1 n)%N
n:nat
bv:Bvector n

(Bv2N bv < N.shiftl_nat 1 n)%N

(0 < 1)%N
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:(Bv2N bv < N.shiftl_nat 1 n)%N
((if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) < N.double (N.shiftl_nat 1 n))%N

(0 < 1)%N
constructor.
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:(Bv2N bv < N.shiftl_nat 1 n)%N

((if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) < N.double (N.shiftl_nat 1 n))%N
n:nat
bv:VectorDef.t bool n
IHbv:(Bv2N bv < N.shiftl_nat 1 n)%N

(N.succ_double (Bv2N bv) < N.double (N.shiftl_nat 1 n))%N
n:nat
bv:VectorDef.t bool n
IHbv:(Bv2N bv < N.shiftl_nat 1 n)%N
(N.double (Bv2N bv) < N.double (N.shiftl_nat 1 n))%N
n:nat
bv:VectorDef.t bool n
IHbv:(Bv2N bv < N.shiftl_nat 1 n)%N

(N.succ_double (Bv2N bv) < N.double (N.shiftl_nat 1 n))%N
apply N.succ_double_lt...
n:nat
bv:VectorDef.t bool n
IHbv:(Bv2N bv < N.shiftl_nat 1 n)%N

(N.double (Bv2N bv) < N.double (N.shiftl_nat 1 n))%N
apply N.double_lt_mono... Qed.
n:nat
v:ByteVector n

(ByteV2N v < N.shiftl_nat 1 (n * 8))%N
n:nat
v:ByteVector n

(ByteV2N v < N.shiftl_nat 1 (n * 8))%N
n:nat
v:ByteVector n

(Bv2N (to_Bvector v) < N.shiftl_nat 1 (n * 8))%N
apply Bv2N_upper_bound. Qed.
To state nonetheless a second result about composition of conversions, we define a conversion on a given number of bits :
#[deprecated(since = "8.9.0", note = "Use N2Bv_sized instead.")]
Fixpoint N2Bv_gen (n:nat)(a:N) : Bvector n :=
 match n return Bvector n with
   | 0 => Bnil
   | S n => match a with
       | N0 => Bvect_false (S n)
       | Npos xH => Bcons true _ (Bvect_false n)
       | Npos (xO p) => Bcons false _ (N2Bv_gen n (Npos p))
       | Npos (xI p) => Bcons true _ (N2Bv_gen n (Npos p))
      end
  end.
The first N2Bv is then a special case of N2Bv_gen

forall a : N, N2Bv a = N2Bv_gen (N.size_nat a) a

forall a : N, N2Bv a = N2Bv_gen (N.size_nat a) a

Bnil = Bnil
p:positive
P2Bv p = N2Bv_gen (Pos.size_nat p) (N.pos p)
p:positive

P2Bv p = N2Bv_gen (Pos.size_nat p) (N.pos p)
induction p; simpl; intros; auto; congruence. Qed.
In fact, if k is large enough, N2Bv_gen k a contains all digits of a plus some zeros.

forall (a : N) (k : nat), N2Bv_gen (N.size_nat a + k) a = N2Bv a ++ Bvect_false k

forall (a : N) (k : nat), N2Bv_gen (N.size_nat a + k) a = N2Bv a ++ Bvect_false k

forall k : nat, N2Bv_gen k 0 = Bvect_false k
p:positive
forall k : nat, N2Bv_gen (Pos.size_nat p + k) (N.pos p) = P2Bv p ++ Bvect_false k
p:positive

forall k : nat, N2Bv_gen (Pos.size_nat p + k) (N.pos p) = P2Bv p ++ Bvect_false k
induction p; simpl; intros;unfold Bcons; f_equal; auto. Qed.
Here comes now the second composition result.

forall (n : nat) (bv : Bvector n), N2Bv_gen n (Bv2N bv) = bv

forall (n : nat) (bv : Bvector n), N2Bv_gen n (Bv2N bv) = bv

N2Bv_gen 0 (Bv2N []) = []
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:N2Bv_gen n (Bv2N bv) = bv
N2Bv_gen (S n) (Bv2N (h :: bv)) = h :: bv
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:N2Bv_gen n (Bv2N bv) = bv

N2Bv_gen (S n) (Bv2N (h :: bv)) = h :: bv
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:N2Bv_gen n (Bv2N bv) = bv

match (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) with | 0%N => false :: Bvect_false n | N.pos (p~1)%positive => Bcons true n (N2Bv_gen n (N.pos p)) | N.pos (p~0)%positive => Bcons false n (N2Bv_gen n (N.pos p)) | 1%N => Bcons true n (Bvect_false n) end = h :: bv
h:bool
n:nat
bv:VectorDef.t bool n

N2Bv_gen n (Bv2N bv) = bv -> match (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) with | 0%N => false :: Bvect_false n | N.pos (p~1)%positive => Bcons true n (N2Bv_gen n (N.pos p)) | N.pos (p~0)%positive => Bcons false n (N2Bv_gen n (N.pos p)) | 1%N => Bcons true n (Bvect_false n) end = h :: bv
h:bool
n:nat
bv:VectorDef.t bool n

N2Bv_gen n (Bv2N bv) = bv -> match (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) with | 0%N => false :: Bvect_false n | N.pos (p~1)%positive => true :: N2Bv_gen n (N.pos p) | N.pos (p~0)%positive => false :: N2Bv_gen n (N.pos p) | 1%N => true :: Bvect_false n end = h :: bv
destruct (Bv2N _ bv); destruct h; intro H; rewrite <- H; simpl; trivial; induction n; simpl; auto. Qed.
accessing some precise bits.

forall (n : nat) (bv : Bvector (S n)), N.odd (Bv2N bv) = Blow n bv

forall (n : nat) (bv : Bvector (S n)), N.odd (Bv2N bv) = Blow n bv

forall (h : bool) (n : nat) (t : Vector.t bool n), N.odd (Bv2N (h :: t)) = Blow n (h :: t)
h:bool
n:nat
t:Vector.t bool n

N.odd (Bv2N (h :: t)) = Blow n (h :: t)
h:bool
n:nat
t:Vector.t bool n

N.odd (Bv2N (h :: t)) = Vector.hd (h :: t)
h:bool
n:nat
t:Vector.t bool n

N.odd (if h then N.succ_double (Bv2N t) else N.double (Bv2N t)) = h
destruct (Bv2N n t); simpl; destruct h; auto. Qed. Notation Bnth := (@Vector.nth_order bool).

forall (n : nat) (bv : Bvector n) (p : nat) (H : p < n), Bnth bv H = N.testbit_nat (Bv2N bv) p

forall (n : nat) (bv : Bvector n) (p : nat) (H : p < n), Bnth bv H = N.testbit_nat (Bv2N bv) p
p:nat
H:p < 0

Bnth [] H = N.testbit_nat (Bv2N []) p
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:forall (p0 : nat) (H0 : p0 < n), Bnth bv H0 = N.testbit_nat (Bv2N bv) p0
p:nat
H:p < S n
Bnth (h :: bv) H = N.testbit_nat (Bv2N (h :: bv)) p
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:forall (p0 : nat) (H0 : p0 < n), Bnth bv H0 = N.testbit_nat (Bv2N bv) p0
p:nat
H:p < S n

Bnth (h :: bv) H = N.testbit_nat (Bv2N (h :: bv)) p
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:forall (p : nat) (H0 : p < n), Bnth bv H0 = N.testbit_nat (Bv2N bv) p
H:0 < S n

Bnth (h :: bv) H = N.testbit_nat (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) 0
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:forall (p0 : nat) (H0 : p0 < n), Bnth bv H0 = N.testbit_nat (Bv2N bv) p0
p:nat
H:S p < S n
Bnth (h :: bv) H = N.testbit_nat (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) (S p)
h:bool
n:nat
bv:VectorDef.t bool n
IHbv:forall (p0 : nat) (H0 : p0 < n), Bnth bv H0 = N.testbit_nat (Bv2N bv) p0
p:nat
H:S p < S n

Bnth (h :: bv) H = N.testbit_nat (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) (S p)
h:bool
n:nat
bv:VectorDef.t bool n
p:nat
H:S p < S n
IHbv:Bnth bv (Lt.lt_S_n p n H) = N.testbit_nat (Bv2N bv) p

Bnth (h :: bv) H = N.testbit_nat (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) (S p)
simpl in * ; destruct (Bv2N n bv); destruct h; simpl in *; auto. Qed.

forall (n : N) (p : nat), N.size_nat n <= p -> N.testbit_nat n p = false

forall (n : N) (p : nat), N.size_nat n <= p -> N.testbit_nat n p = false

forall p : nat, N.size_nat 0 <= p -> N.testbit_nat 0 p = false
n:positive
forall p : nat, N.size_nat (N.pos n) <= p -> N.testbit_nat (N.pos n) p = false
n:positive

forall p : nat, N.size_nat (N.pos n) <= p -> N.testbit_nat (N.pos n) p = false
n:positive
IHn:forall p : nat, Pos.size_nat n <= p -> Pos.testbit_nat n p = false
H:S (Pos.size_nat n) <= 0

true = false
H:1 <= 0
true = false
H:1 <= 0

true = false
inversion H. Qed.

forall (n : N) (p : nat) (H : p < N.size_nat n), N.testbit_nat n p = Bnth (N2Bv n) H

forall (n : N) (p : nat) (H : p < N.size_nat n), N.testbit_nat n p = Bnth (N2Bv n) H

forall (p : nat) (H : p < N.size_nat 0), N.testbit_nat 0 p = Bnth (N2Bv 0) H
n:positive
forall (p : nat) (H : p < N.size_nat (N.pos n)), N.testbit_nat (N.pos n) p = Bnth (N2Bv (N.pos n)) H
n:positive

forall (p : nat) (H : p < N.size_nat (N.pos n)), N.testbit_nat (N.pos n) p = Bnth (N2Bv (N.pos n)) H
p:nat

forall H : S p < 1, false = match Fin.of_nat_lt (Lt.lt_S_n p 0 H) in (Fin.t m') return (Vector.t bool m' -> bool) with | @Fin.F1 n => Vector.caseS (fun (n0 : nat) (_ : Vector.t bool (S n0)) => bool) (fun (h : bool) (n0 : nat) (_ : Vector.t bool n0) => h) | @Fin.FS n p' => fun v : Vector.t bool (S n) => Vector.caseS (fun (n0 : nat) (_ : Vector.t bool (S n0)) => Fin.t n0 -> bool) (fun (_ : bool) (n0 : nat) (t : Vector.t bool n0) (p0 : Fin.t n0) => t[@p0]) v p' end []
intros H ; destruct (Lt.lt_n_O _ (Lt.lt_S_n _ _ H)). Qed.
Binary bitwise operations are the same in the two worlds.

forall (n : nat) (bv bv' : Bvector n), Bv2N (BVxor n bv bv') = N.lxor (Bv2N bv) (Bv2N bv')

forall (n : nat) (bv bv' : Bvector n), Bv2N (BVxor n bv bv') = N.lxor (Bv2N bv) (Bv2N bv')

Bv2N (BVxor 0 [] []) = N.lxor (Bv2N []) (Bv2N [])
n:nat
v1, v2:Vector.t bool n
H:Bv2N (BVxor n v1 v2) = N.lxor (Bv2N v1) (Bv2N v2)
a, b:bool
Bv2N (BVxor (S n) (a :: v1) (b :: v2)) = N.lxor (Bv2N (a :: v1)) (Bv2N (b :: v2))
n:nat
v1, v2:Vector.t bool n
H:Bv2N (BVxor n v1 v2) = N.lxor (Bv2N v1) (Bv2N v2)
a, b:bool

Bv2N (BVxor (S n) (a :: v1) (b :: v2)) = N.lxor (Bv2N (a :: v1)) (Bv2N (b :: v2))
n:nat
v1, v2:Vector.t bool n
H:Bv2N (BVxor n v1 v2) = N.lxor (Bv2N v1) (Bv2N v2)
a, b:bool

(if xorb a b then N.succ_double (Bv2N (BVxor n v1 v2)) else N.double (Bv2N (BVxor n v1 v2))) = N.lxor (if a then N.succ_double (Bv2N v1) else N.double (Bv2N v1)) (if b then N.succ_double (Bv2N v2) else N.double (Bv2N v2))
destruct a, b, (Bv2N n v1), (Bv2N n v2); simpl in *; rewrite H ; now simpl. Qed.

forall (n : nat) (bv bv' : Bvector n), Bv2N (BVand n bv bv') = N.land (Bv2N bv) (Bv2N bv')

forall (n : nat) (bv bv' : Bvector n), Bv2N (BVand n bv bv') = N.land (Bv2N bv) (Bv2N bv')
n:nat
v1, v2:Vector.t bool n
H:Bv2N (BVand n v1 v2) = N.land (Bv2N v1) (Bv2N v2)
a, b:bool

(if a && b then N.succ_double (Bv2N (BVand n v1 v2)) else N.double (Bv2N (BVand n v1 v2))) = N.land (if a then N.succ_double (Bv2N v1) else N.double (Bv2N v1)) (if b then N.succ_double (Bv2N v2) else N.double (Bv2N v2))
n:nat
v1, v2:Vector.t bool n
H:Bv2N (BVand n v1 v2) = N.land (Bv2N v1) (Bv2N v2)
a, b:bool

(if a && b then N.succ_double (N.land (Bv2N v1) (Bv2N v2)) else N.double (N.land (Bv2N v1) (Bv2N v2))) = N.land (if a then N.succ_double (Bv2N v1) else N.double (Bv2N v1)) (if b then N.succ_double (Bv2N v2) else N.double (Bv2N v2))
destruct a, b, (Bv2N n v1), (Bv2N n v2); simpl; auto. Qed.
n:N

N2Bv_sized (N.size_nat n) n = N2Bv n
n:N

N2Bv_sized (N.size_nat n) n = N2Bv n
p:positive

P2Bv_sized (Pos.size_nat p) p = P2Bv p
p:positive
IHp:P2Bv_sized (Pos.size_nat p) p = P2Bv p

true :: P2Bv_sized (Pos.size_nat p) p = Bcons true (Pos.size_nat p) (P2Bv p)
p:positive
IHp:P2Bv_sized (Pos.size_nat p) p = P2Bv p
false :: P2Bv_sized (Pos.size_nat p) p = Bcons false (Pos.size_nat p) (P2Bv p)
all: rewrite IHp... Qed.
n:nat
v:Bvector n

N2Bv_sized n (Bv2N v) = v
n:nat
v:Bvector n

N2Bv_sized n (Bv2N v) = v
h:bool
n:nat
v:VectorDef.t bool n
IHv:N2Bv_sized n (Bv2N v) = v

N2Bv_sized (S n) (if h then N.succ_double (Bv2N v) else N.double (Bv2N v)) = h :: v
destruct h; unfold N2Bv_sized; destruct (Bv2N n v) as [|[]]; rewrite <- IHv... Qed.
a:N
k:nat

N2Bv_sized (N.size_nat a + k) a = N2Bv a ++ Bvect_false k
a:N
k:nat

N2Bv_sized (N.size_nat a + k) a = N2Bv a ++ Bvect_false k
p:positive
k:nat

N2Bv_sized (N.size_nat (N.pos p) + k) (N.pos p) = N2Bv (N.pos p) ++ Bvect_false k
induction p; simpl; f_equal... Qed.