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 ninduction 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 (p : positive) (n : nat), Pos.testbit p (N.of_nat n) = Pos.testbit_nat p nforall (a : N) (n : nat), N.testbit a (N.of_nat n) = N.testbit_nat a nforall (a : N) (n : nat), N.testbit a (N.of_nat n) = N.testbit_nat a nforall n : nat, N.testbit 0 (N.of_nat n) = N.testbit_nat 0 np:positiveforall n : nat, N.testbit (N.pos p) (N.of_nat n) = N.testbit_nat (N.pos p) napply Ptestbit_Pbit. Qed.p:positiveforall n : nat, N.testbit (N.pos p) (N.of_nat n) = N.testbit_nat (N.pos p) nforall (p : positive) (n : N), Pos.testbit_nat p (N.to_nat n) = Pos.testbit p nintros; now rewrite <- Ptestbit_Pbit, N2Nat.id. Qed.forall (p : positive) (n : N), Pos.testbit_nat p (N.to_nat n) = Pos.testbit p nforall a n : N, N.testbit_nat a (N.to_nat n) = N.testbit a nforall a n : N, N.testbit_nat a (N.to_nat n) = N.testbit a nforall n : N, N.testbit_nat 0 (N.to_nat n) = N.testbit 0 np:positiveforall n : N, N.testbit_nat (N.pos p) (N.to_nat n) = N.testbit (N.pos p) napply Pbit_Ptestbit. Qed.p:positiveforall n : N, N.testbit_nat (N.pos p) (N.to_nat n) = N.testbit (N.pos p) n
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)reflexivity. Qed.forall (a : N) (n : nat), N.shiftr_nat a (S n) = N.div2 (N.shiftr_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 : nat), N.shiftl_nat a (S n) = N.double (N.shiftl_nat a n)forall a n : N, N.shiftr_nat a (N.to_nat n) = N.shiftr a nforall a n : N, N.shiftr_nat a (N.to_nat n) = N.shiftr a na:Na = aa:Nn:positiveN.shiftr_nat a (Pos.to_nat n) = Pos.iter N.div2 a na:Na = aa:Nn:positiveN.shiftr_nat a (Pos.to_nat n) = Pos.iter N.div2 a na:Nn:positiveN.shiftr_nat a (Pos.to_nat n) = Pos.iter N.div2 a napply Pos2Nat.inj_iter. Qed.a:Nn:positivePos.iter N.div2 a n = N.shiftr_nat a (Pos.to_nat n)forall (a : N) (n : nat), N.shiftr a (N.of_nat n) = N.shiftr_nat a nforall (a : N) (n : nat), N.shiftr a (N.of_nat n) = N.shiftr_nat a nnow rewrite <- Nshiftr_nat_equiv, Nat2N.id. Qed.a:Nn:natN.shiftr a (N.of_nat n) = N.shiftr_nat a nforall a n : N, N.shiftl_nat a (N.to_nat n) = N.shiftl a nforall a n : N, N.shiftl_nat a (N.to_nat n) = N.shiftl a nn:positivenat_rect (fun _ : nat => N) 0 (fun _ : nat => N.double) (Pos.to_nat n) = 0a, n:positivenat_rect (fun _ : nat => N) (N.pos a) (fun _ : nat => N.double) (Pos.to_nat n) = N.pos (Pos.iter xO a n)a, n:positivenat_rect (fun _ : nat => N) (N.pos a) (fun _ : nat => N.double) (Pos.to_nat n) = N.pos (Pos.iter xO a n)a, n:positivePos.iter N.double (N.pos a) n = N.pos (Pos.iter xO a n)now apply Pos.iter_swap_gen. Qed.a, n:positiveN.pos (Pos.iter xO a n) = Pos.iter N.double (N.pos a) nforall (a : N) (n : nat), N.shiftl a (N.of_nat n) = N.shiftl_nat a nforall (a : N) (n : nat), N.shiftl a (N.of_nat n) = N.shiftl_nat a nnow rewrite <- Nshiftl_nat_equiv, Nat2N.id. Qed.a:Nn:natN.shiftl a (N.of_nat n) = N.shiftl_nat a n
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:Nm:natN.testbit_nat (N.shiftr_nat a 0) m = N.testbit_nat a (m + 0)a:Nn:natIHn:forall m0 : nat, N.testbit_nat (N.shiftr_nat a n) m0 = N.testbit_nat a (m0 + n)m:natN.testbit_nat (N.shiftr_nat a (S n)) m = N.testbit_nat a (m + S n)a:Nn:natIHn:forall m0 : nat, N.testbit_nat (N.shiftr_nat a n) m0 = N.testbit_nat a (m0 + n)m:natN.testbit_nat (N.shiftr_nat a (S n)) m = N.testbit_nat a (m + S n)a:Nn:natIHn:forall m0 : nat, N.testbit_nat (N.shiftr_nat a n) m0 = N.testbit_nat a (m0 + n)m:natN.testbit_nat (N.div2 (N.shiftr_nat a n)) m = N.testbit_nat a (m + S n)destruct (N.shiftr_nat a n) as [|[p|p|]]; simpl; trivial. Qed.a:Nn:natIHn:forall m0 : nat, N.testbit_nat (N.shiftr_nat a n) m0 = N.testbit_nat a (m0 + n)m:natN.testbit_nat (N.div2 (N.shiftr_nat a n)) m = N.testbit_nat (N.shiftr_nat a n) (S m)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:Nm:natH:(0 <= m)%natN.testbit_nat (N.shiftl_nat a 0) m = N.testbit_nat a (m - 0)a:Nn:natIHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)m:natH:(S n <= m)%natN.testbit_nat (N.shiftl_nat a (S n)) m = N.testbit_nat a (m - S n)now rewrite Nat.sub_0_r.a:Nm:natH:(0 <= m)%natN.testbit_nat (N.shiftl_nat a 0) m = N.testbit_nat a (m - 0)a:Nn:natIHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)m:natH:(S n <= m)%natN.testbit_nat (N.shiftl_nat a (S n)) m = N.testbit_nat a (m - S n)a:Nn:natIHn: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)%natN.testbit_nat (N.shiftl_nat a (S n)) 0 = N.testbit_nat a (0 - S n)a:Nn:natIHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)m:natH:(S n <= S m)%natN.testbit_nat (N.shiftl_nat a (S n)) (S m) = N.testbit_nat a (S m - S n)inversion H.a:Nn:natIHn: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)%natN.testbit_nat (N.shiftl_nat a (S n)) 0 = N.testbit_nat a (0 - S n)a:Nn:natIHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)m:natH:(S n <= S m)%natN.testbit_nat (N.shiftl_nat a (S n)) (S m) = N.testbit_nat a (S m - S n)a:Nn:natIHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)m:natH:(n <= m)%natN.testbit_nat (N.shiftl_nat a (S n)) (S m) = N.testbit_nat a (S m - S n)a:Nn:natIHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)m:natH:(n <= m)%natN.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = N.testbit_nat a (m - n)destruct (N.shiftl_nat a n) as [|[p|p|]]; simpl; trivial. Qed.a:Nn:natIHn:forall m0 : nat, (n <= m0)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = N.testbit_nat a (m0 - n)m:natH:(n <= m)%natN.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = N.testbit_nat (N.shiftl_nat a n) mforall (a : N) (n m : nat), (m < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m = falseforall (a : N) (n m : nat), (m < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m = falsea:Nm:natH:(m < 0)%natN.testbit_nat (N.shiftl_nat a 0) m = falsea:Nn:natIHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = falsem:natH:(m < S n)%natN.testbit_nat (N.shiftl_nat a (S n)) m = falsea:Nn:natIHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = falsem:natH:(m < S n)%natN.testbit_nat (N.shiftl_nat a (S n)) m = falsea:Nn:natIHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = falsem:natH:(m < S n)%natN.testbit_nat (N.double (N.shiftl_nat a n)) m = falsea:Nn:natIHn:forall m : nat, (m < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m = falseH:(0 < S n)%natN.testbit_nat (N.double (N.shiftl_nat a n)) 0 = falsea:Nn:natIHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = falsem:natH:(S m < S n)%natN.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = falsedestruct (N.shiftl_nat a n); trivial.a:Nn:natIHn:forall m : nat, (m < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m = falseH:(0 < S n)%natN.testbit_nat (N.double (N.shiftl_nat a n)) 0 = falsea:Nn:natIHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = falsem:natH:(S m < S n)%natN.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = falsea:Nn:natIHn:forall m0 : nat, (m0 < n)%nat -> N.testbit_nat (N.shiftl_nat a n) m0 = falsem:natH:(m < n)%natN.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = falsedestruct (N.shiftl_nat a n); trivial. Qed.a:Nn, m:natIHn:N.testbit_nat (N.shiftl_nat a n) m = falseH:(m < n)%natN.testbit_nat (N.double (N.shiftl_nat a n)) (S m) = false
A left shift for positive numbers (used in BigN)
forall p : positive, Pos.shiftl_nat p 0 = preflexivity. Qed.forall p : positive, Pos.shiftl_nat p 0 = pforall (p : positive) (n : nat), Pos.shiftl_nat p (S n) = ((Pos.shiftl_nat p n)~0)%positivereflexivity. Qed.forall (p : positive) (n : nat), Pos.shiftl_nat p (S n) = ((Pos.shiftl_nat p n)~0)%positiveforall (p : positive) (n : nat), N.pos (Pos.shiftl_nat p n) = N.shiftl_nat (N.pos p) nforall (p : positive) (n : nat), N.pos (Pos.shiftl_nat p n) = N.shiftl_nat (N.pos p) nforall (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) nnow rewrite <- IHn. Qed.p:positiven:natIHn:N.pos (nat_rect (fun _ : nat => positive) p (fun _ : nat => xO) n) = nat_rect (fun _ : nat => N) (N.pos p) (fun _ : nat => N.double) nN.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)forall (n m : nat) (p : positive), Pos.shiftl_nat p (m + n) = Pos.shiftl_nat (Pos.shiftl_nat p n) mforall (n m : nat) (p : positive), Pos.shiftl_nat p (m + n) = Pos.shiftl_nat (Pos.shiftl_nat p n) mn:natp:positivePos.shiftl_nat p n = Pos.shiftl_nat p nn, m:natIHm:forall p0 : positive, Pos.shiftl_nat p0 (m + n) = Pos.shiftl_nat (Pos.shiftl_nat p0 n) mp:positive((Pos.shiftl_nat p (m + n))~0)%positive = ((Pos.shiftl_nat (Pos.shiftl_nat p n) m)~0)%positivenow f_equal. Qed.n, m:natIHm:forall p0 : positive, Pos.shiftl_nat p0 (m + n) = Pos.shiftl_nat (Pos.shiftl_nat p0 n) mp:positive((Pos.shiftl_nat p (m + n))~0)%positive = ((Pos.shiftl_nat (Pos.shiftl_nat p n) m)~0)%positive
Semantics of bitwise operations with respect to N.testbit_nat
p, p':positiven:natN.testbit_nat (Pos.lxor p p') n = xorb (Pos.testbit_nat p n) (Pos.testbit_nat p' n)p, p':positiven:natN.testbit_nat (Pos.lxor p p') n = xorb (Pos.testbit_nat p n) (Pos.testbit_nat p' n)apply N.pos_lxor_spec. Qed.p, p':positiven:natN.testbit (Pos.lxor p p') (N.of_nat n) = xorb (Pos.testbit p (N.of_nat n)) (Pos.testbit p' (N.of_nat n))a, a':Nn:natN.testbit_nat (N.lxor a a') n = xorb (N.testbit_nat a n) (N.testbit_nat a' n)a, a':Nn:natN.testbit_nat (N.lxor a a') n = xorb (N.testbit_nat a n) (N.testbit_nat a' n)apply N.lxor_spec. Qed.a, a':Nn:natN.testbit (N.lxor a a') (N.of_nat n) = xorb (N.testbit a (N.of_nat n)) (N.testbit a' (N.of_nat n))p, p':positiven:natPos.testbit_nat (Pos.lor p p') n = Pos.testbit_nat p n || Pos.testbit_nat p' np, p':positiven:natPos.testbit_nat (Pos.lor p p') n = Pos.testbit_nat p n || Pos.testbit_nat p' napply N.pos_lor_spec. Qed.p, p':positiven:natPos.testbit (Pos.lor p p') (N.of_nat n) = Pos.testbit p (N.of_nat n) || Pos.testbit p' (N.of_nat n)a, a':Nn:natN.testbit_nat (N.lor a a') n = N.testbit_nat a n || N.testbit_nat a' na, a':Nn:natN.testbit_nat (N.lor a a') n = N.testbit_nat a n || N.testbit_nat a' napply N.lor_spec. Qed.a, a':Nn:natN.testbit (N.lor a a') (N.of_nat n) = N.testbit a (N.of_nat n) || N.testbit a' (N.of_nat n)p, p':positiven:natN.testbit_nat (Pos.land p p') n = Pos.testbit_nat p n && Pos.testbit_nat p' np, p':positiven:natN.testbit_nat (Pos.land p p') n = Pos.testbit_nat p n && Pos.testbit_nat p' napply N.pos_land_spec. Qed.p, p':positiven:natN.testbit (Pos.land p p') (N.of_nat n) = Pos.testbit p (N.of_nat n) && Pos.testbit p' (N.of_nat n)a, a':Nn:natN.testbit_nat (N.land a a') n = N.testbit_nat a n && N.testbit_nat a' na, a':Nn:natN.testbit_nat (N.land a a') n = N.testbit_nat a n && N.testbit_nat a' napply N.land_spec. Qed.a, a':Nn:natN.testbit (N.land a a') (N.of_nat n) = N.testbit a (N.of_nat n) && N.testbit a' (N.of_nat n)p, p':positiven:natN.testbit_nat (Pos.ldiff p p') n = Pos.testbit_nat p n && negb (Pos.testbit_nat p' n)p, p':positiven:natN.testbit_nat (Pos.ldiff p p') n = Pos.testbit_nat p n && negb (Pos.testbit_nat p' n)apply N.pos_ldiff_spec. Qed.p, p':positiven:natN.testbit (Pos.ldiff p p') (N.of_nat n) = Pos.testbit p (N.of_nat n) && negb (Pos.testbit p' (N.of_nat n))a, a':Nn:natN.testbit_nat (N.ldiff a a') n = N.testbit_nat a n && negb (N.testbit_nat a' n)a, a':Nn:natN.testbit_nat (N.ldiff a a') n = N.testbit_nat a n && negb (N.testbit_nat a' n)apply N.ldiff_spec. Qed.a, a':Nn:natN.testbit (N.ldiff a a') (N.of_nat n) = N.testbit a (N.of_nat n) && negb (N.testbit a' (N.of_nat n))
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)apply (IHp (Step H)). Qed.p:positiveIHp:~ Pos.testbit_nat p == (fun _ : nat => false)H:Pos.testbit_nat p~0 == (fun _ : nat => false)Falseforall 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:positiveIHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0p':positiveH:Pos.testbit_nat p~1 == Pos.testbit_nat p'~1(p~1)%positive = (p'~1)%positivep:positiveIHp: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%positivep:positiveIHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0p':positiveH:Pos.testbit_nat p~0 == Pos.testbit_nat p'~0(p~0)%positive = (p'~0)%positivep':positiveH:Pos.testbit_nat 1 == Pos.testbit_nat p'~11%positive = (p'~1)%positivep:positiveIHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0p':positiveH:Pos.testbit_nat p~1 == Pos.testbit_nat p'~1p = p'p:positiveIHp: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%positivep:positiveIHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0p':positiveH:Pos.testbit_nat p~0 == Pos.testbit_nat p'~0(p~0)%positive = (p'~0)%positivep':positiveH:Pos.testbit_nat 1 == Pos.testbit_nat p'~11%positive = (p'~1)%positivep:positiveIHp: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%positivep:positiveIHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0p':positiveH:Pos.testbit_nat p~0 == Pos.testbit_nat p'~0(p~0)%positive = (p'~0)%positivep':positiveH:Pos.testbit_nat 1 == Pos.testbit_nat p'~11%positive = (p'~1)%positivep:positiveIHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0p':positiveH:Pos.testbit_nat p~0 == Pos.testbit_nat p'~0(p~0)%positive = (p'~0)%positivep':positiveH:Pos.testbit_nat 1 == Pos.testbit_nat p'~11%positive = (p'~1)%positivep:positiveIHp:forall p'0 : positive, Pos.testbit_nat p == Pos.testbit_nat p'0 -> p = p'0p':positiveH:Pos.testbit_nat p~0 == Pos.testbit_nat p'~0p = p'p':positiveH:Pos.testbit_nat 1 == Pos.testbit_nat p'~11%positive = (p'~1)%positivep':positiveH:Pos.testbit_nat 1 == Pos.testbit_nat p'~11%positive = (p'~1)%positivedestruct (Pbit_faithful_0 _ (Step H)). Qed.p':positiveH:Pos.testbit_nat p'~1 == Pos.testbit_nat 11%positive = (p'~1)%positiveforall 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':positiveH:N.testbit_nat 0 == N.testbit_nat (N.pos p')0 = N.pos p'p:positiveH:N.testbit_nat (N.pos p) == N.testbit_nat 0N.pos p = 0p, p':positiveH:N.testbit_nat (N.pos p) == N.testbit_nat (N.pos p')N.pos p = N.pos p'p':positiveH:N.testbit_nat (N.pos p') == N.testbit_nat 00 = N.pos p'p:positiveH:N.testbit_nat (N.pos p) == N.testbit_nat 0N.pos p = 0p, p':positiveH:N.testbit_nat (N.pos p) == N.testbit_nat (N.pos p')N.pos p = N.pos p'p:positiveH:N.testbit_nat (N.pos p) == N.testbit_nat 0N.pos p = 0p, p':positiveH:N.testbit_nat (N.pos p) == N.testbit_nat (N.pos p')N.pos p = N.pos p'p, p':positiveH:N.testbit_nat (N.pos p) == N.testbit_nat (N.pos p')N.pos p = N.pos p'apply Pbit_faithful, H. Qed.p, p':positiveH:N.testbit_nat (N.pos p) == N.testbit_nat (N.pos p')p = p'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':NN.testbit_nat n == N.testbit_nat n' -> n = n'n, n':Nn = n' -> N.testbit_nat n == N.testbit_nat n'intros; now subst. Qed. Local Close Scope N_scope.n, n':Nn = n' -> N.testbit_nat n == N.testbit_nat n'
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 nforall n : N, N.testbit_nat n 0 = N.odd ndestruct p; trivial. Qed.p:positiveN.testbit_nat (N.pos p) 0 = N.odd (N.pos p)forall n : N, N.odd (N.double n) = falsedestruct n; trivial. Qed.forall n : N, N.odd (N.double n) = falseforall n : N, N.odd (N.succ_double n) = truedestruct n; trivial. Qed.forall n : N, N.odd (N.succ_double n) = trueforall n : N, Neven n -> N.double (N.div2 n) = nforall n : N, Neven n -> N.double (N.div2 n) = nNeven 0 -> N.double (N.div2 0) = 0%Np:positiveNeven (N.pos p) -> N.double (N.div2 (N.pos p)) = N.pos pp:positiveNeven (N.pos p) -> N.double (N.div2 (N.pos p)) = N.pos pp:positiveNeven (N.pos p~1) -> N.double (N.div2 (N.pos p~1)) = N.pos p~1p:positiveNeven (N.pos p~0) -> N.double (N.div2 (N.pos p~0)) = N.pos p~0Neven 1 -> N.double (N.div2 1) = 1%Np:positiveH:Neven (N.pos p~1)N.double (N.div2 (N.pos p~1)) = N.pos p~1p:positiveNeven (N.pos p~0) -> N.double (N.div2 (N.pos p~0)) = N.pos p~0Neven 1 -> N.double (N.div2 1) = 1%Np:positiveNeven (N.pos p~0) -> N.double (N.div2 (N.pos p~0)) = N.pos p~0Neven 1 -> N.double (N.div2 1) = 1%Np:positiveH:Neven (N.pos p~0)N.double (N.div2 (N.pos p~0)) = N.pos p~0Neven 1 -> N.double (N.div2 1) = 1%NNeven 1 -> N.double (N.div2 1) = 1%Ndiscriminate H. Qed.H:Neven 1N.double (N.div2 1) = 1%Nforall n : N, Nodd n -> N.succ_double (N.div2 n) = nforall n : N, Nodd n -> N.succ_double (N.div2 n) = nNodd 0 -> N.succ_double (N.div2 0) = 0%Np:positiveNodd (N.pos p) -> N.succ_double (N.div2 (N.pos p)) = N.pos pH:Nodd 0N.succ_double (N.div2 0) = 0%Np:positiveNodd (N.pos p) -> N.succ_double (N.div2 (N.pos p)) = N.pos pp:positiveNodd (N.pos p) -> N.succ_double (N.div2 (N.pos p)) = N.pos pp:positiveNodd (N.pos p~1) -> N.succ_double (N.div2 (N.pos p~1)) = N.pos p~1p:positiveNodd (N.pos p~0) -> N.succ_double (N.div2 (N.pos p~0)) = N.pos p~0Nodd 1 -> N.succ_double (N.div2 1) = 1%Np:positiveH:Nodd (N.pos p~1)N.succ_double (N.div2 (N.pos p~1)) = N.pos p~1p:positiveNodd (N.pos p~0) -> N.succ_double (N.div2 (N.pos p~0)) = N.pos p~0Nodd 1 -> N.succ_double (N.div2 1) = 1%Np:positiveNodd (N.pos p~0) -> N.succ_double (N.div2 (N.pos p~0)) = N.pos p~0Nodd 1 -> N.succ_double (N.div2 1) = 1%Np:positiveH:Nodd (N.pos p~0)N.succ_double (N.div2 (N.pos p~0)) = N.pos p~0Nodd 1 -> N.succ_double (N.div2 1) = 1%NNodd 1 -> N.succ_double (N.div2 1) = 1%Nreflexivity. Qed.H:Nodd 1N.succ_double (N.div2 1) = 1%Nforall (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)destruct p; trivial. Qed.p:positiveforall n : nat, N.testbit_nat (N.div2 (N.pos p)) n = N.testbit_nat (N.pos p) (S n)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':NN.odd (N.lxor a a') = xorb (N.odd a) (N.odd a')a, a':Nxorb (N.testbit_nat a 0) (N.testbit_nat a' 0) = xorb (N.odd a) (N.odd a')reflexivity. Qed.a, a':Nxorb (N.odd a) (N.odd a') = xorb (N.odd a) (N.odd a')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':NN.div2 (N.lxor a a') = N.lxor (N.div2 a) (N.div2 a')a, a':NN.testbit_nat (N.div2 (N.lxor a a')) == N.testbit_nat (N.lxor (N.div2 a) (N.div2 a'))a, a':Nforall n : nat, N.testbit_nat (N.div2 (N.lxor a a')) n = N.testbit_nat (N.lxor (N.div2 a) (N.div2 a')) na, a':Nn:natN.testbit_nat (N.div2 (N.lxor a a')) n = N.testbit_nat (N.lxor (N.div2 a) (N.div2 a')) na, a':Nn:natxorb (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)reflexivity. Qed.a, a':Nn:natxorb (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))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':NH:N.odd (N.lxor a a') = trueN.odd a = negb (N.odd a')reflexivity. Qed.a, a':NH:N.odd (N.lxor a a') = trueN.odd a = N.odd aforall 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':NH:N.lxor a a' = 1%NN.odd a = negb (N.odd a')a, a':NH:N.lxor a a' = 1%NN.odd (N.lxor a a') = truereflexivity. Qed.a, a':NH:N.lxor a a' = 1%NN.odd 1 = trueforall (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':Np:positiveH:N.lxor a a' = N.pos p~1N.odd a = negb (N.odd a')a, a':Np:positiveH:N.lxor a a' = N.pos p~1N.odd (N.lxor a a') = truereflexivity. Qed.a, a':Np:positiveH:N.lxor a a' = N.pos p~1N.odd (N.pos p~1) = trueforall (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':Np:positiveH:N.lxor a a' = N.pos p~0N.odd a = N.odd a'a, a':Np:positiveH:N.lxor a a' = N.pos p~0xorb (N.odd a) false = N.odd a'a, a':Np:positiveH:N.lxor a a' = N.pos p~0H0:N.odd (N.pos p~0) = falsexorb (N.odd a) false = N.odd a'reflexivity. Qed.a, a':Np:positiveH:N.lxor a a' = N.pos p~0H0:N.odd (N.pos p~0) = falseN.odd a' = N.odd a'
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' = trueforall a a' : N, N.odd a = false -> N.odd a' = true -> Nless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = trueNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos pNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos pmatch N.lxor a a' with | 0%N => false | N.pos p0 => Nless_aux a a' p0 end = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos pNless_aux a a' p = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos p~1Nless_aux a a' p~1 = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos p~0Nless_aux a a' p~0 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH2:N.lxor a a' = 1%NNless_aux a a' 1 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos p~1negb (N.odd a) && N.odd a' = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos p~0Nless_aux a a' p~0 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH2:N.lxor a a' = 1%NNless_aux a a' 1 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos p~1negb false && true = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos p~0Nless_aux a a' p~0 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH2:N.lxor a a' = 1%NNless_aux a a' 1 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos p~0Nless_aux a a' p~0 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH2:N.lxor a a' = 1%NNless_aux a a' 1 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos p~0H1:N.odd (N.lxor a a') = falseNless_aux a a' p~0 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH2:N.lxor a a' = 1%NNless_aux a a' 1 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = truep:positiveH2:N.lxor a a' = N.pos p~0H1:xorb false true = falseNless_aux a a' p~0 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH2:N.lxor a a' = 1%NNless_aux a a' 1 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH2:N.lxor a a' = 1%NNless_aux a a' 1 = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH2:N.lxor a a' = 1%Nnegb (N.odd a) && N.odd a' = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH2:N.lxor a a' = 1%Nnegb false && true = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NNless a a' = truea, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NH2:N.odd (N.lxor a a') = falseNless a a' = truediscriminate H2. Qed.a, a':NH:N.odd a = falseH0:N.odd a' = trueH1:N.lxor a a' = 0%NH2:xorb false true = falseNless a a' = trueforall a a' : N, N.odd a = true -> N.odd a' = false -> Nless a a' = falseforall a a' : N, N.odd a = true -> N.odd a' = false -> Nless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos pNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos pmatch N.lxor a a' with | 0%N => false | N.pos p0 => Nless_aux a a' p0 end = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos pNless_aux a a' p = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos p~1Nless_aux a a' p~1 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos p~0Nless_aux a a' p~0 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH2:N.lxor a a' = 1%NNless_aux a a' 1 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos p~1negb (N.odd a) && N.odd a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos p~0Nless_aux a a' p~0 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH2:N.lxor a a' = 1%NNless_aux a a' 1 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos p~1negb true && false = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos p~0Nless_aux a a' p~0 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH2:N.lxor a a' = 1%NNless_aux a a' 1 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos p~0Nless_aux a a' p~0 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH2:N.lxor a a' = 1%NNless_aux a a' 1 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos p~0H1:N.odd (N.lxor a a') = falseNless_aux a a' p~0 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH2:N.lxor a a' = 1%NNless_aux a a' 1 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falsep:positiveH2:N.lxor a a' = N.pos p~0H1:xorb true false = falseNless_aux a a' p~0 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH2:N.lxor a a' = 1%NNless_aux a a' 1 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH2:N.lxor a a' = 1%NNless_aux a a' 1 = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH2:N.lxor a a' = 1%Nnegb (N.odd a) && N.odd a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH2:N.lxor a a' = 1%Nnegb true && false = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NNless a a' = falsea, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NH2:N.odd (N.lxor a a') = falseNless a a' = falsediscriminate H2. Qed.a, a':NH:N.odd a = trueH0:N.odd a' = falseH1:N.lxor a a' = 0%NH2:xorb true false = falseNless a a' = falseforall a : N, Nless a a = falseforall a : N, Nless a a = falsea:NNless a a = falsea:Nmatch N.lxor a a with | 0%N => false | N.pos p => Nless_aux a a p end = falsereflexivity. Qed.a:Nfalse = falseforall 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 0p:positiveNless (N.double 0) (N.double (N.pos p)) = Nless 0 (N.pos p)p:positiveNless (N.double (N.pos p)) (N.double 0) = Nless (N.pos p) 0p, p0:positiveNless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p:positiveNless (N.double 0) (N.double (N.pos p)) = Nless 0 (N.pos p)p:positiveNless (N.double (N.pos p)) (N.double 0) = Nless (N.pos p) 0p, p0:positiveNless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p:positiveNless (N.double (N.pos p)) (N.double 0) = Nless (N.pos p) 0p, p0:positiveNless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p:positivematch 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 endp, p0:positiveNless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p:positiveNless_aux (N.pos p) 0 p = Nless_aux (N.pos p) 0 pp, p0:positiveNless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p, p0:positiveNless (N.double (N.pos p)) (N.double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p, p0:positivematch 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 endp, p0:positivematch 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 endp, p0:positivematch Pos.Ndouble 0 with | 0%N => false | N.pos p1 => Nless_aux (N.pos p~0) (N.pos p0~0) p1 end = falsep, p0, p1:positivematch 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) p1trivial. Qed.p, p0, p1:positivematch 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) p1forall 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 0p:positiveNless (N.succ_double 0) (N.succ_double (N.pos p)) = Nless 0 (N.pos p)p:positiveNless (N.succ_double (N.pos p)) (N.succ_double 0) = Nless (N.pos p) 0p, p0:positiveNless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p:positiveNless (N.succ_double 0) (N.succ_double (N.pos p)) = Nless 0 (N.pos p)p:positiveNless (N.succ_double (N.pos p)) (N.succ_double 0) = Nless (N.pos p) 0p, p0:positiveNless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p:positiveNless (N.succ_double (N.pos p)) (N.succ_double 0) = Nless (N.pos p) 0p, p0:positiveNless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p:positivematch 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 endp, p0:positiveNless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p:positiveNless_aux (N.pos p) 0 p = Nless_aux (N.pos p) 0 pp, p0:positiveNless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p, p0:positiveNless (N.succ_double (N.pos p)) (N.succ_double (N.pos p0)) = Nless (N.pos p) (N.pos p0)p, p0:positivematch 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 endp, p0:positivematch 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 endp, p0:positivematch Pos.Ndouble 0 with | 0%N => false | N.pos p1 => Nless_aux (N.pos p~1) (N.pos p0~1) p1 end = falsep, p0, p1:positivematch 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) p1trivial. Qed.p, p0, p1:positivematch 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) p1forall a a' : N, Nless (N.double a) (N.succ_double a') = trueforall a a' : N, Nless (N.double a) (N.succ_double a') = truea, a':NNless (N.double a) (N.succ_double a') = truea, a':NN.odd (N.double a) = falsea, a':NN.odd (N.succ_double a') = trueapply Ndouble_plus_one_bit0. Qed.a, a':NN.odd (N.succ_double a') = trueforall a a' : N, Nless (N.succ_double a) (N.double a') = falseforall a a' : N, Nless (N.succ_double a) (N.double a') = falsea, a':NNless (N.succ_double a) (N.double a') = falsea, a':NN.odd (N.succ_double a) = truea, a':NN.odd (N.double a') = falseapply Ndouble_bit0. Qed.a, a':NN.odd (N.double a') = falseforall a : N, Nless a 0 = falseforall a : N, Nless a 0 = falseNless 0 0 = falsep:positiveNless (N.pos p) 0 = falsep:positiveNless (N.pos p) 0 = falsep:positivematch N.lxor (N.pos p) 0 with | 0%N => false | N.pos p0 => Nless_aux (N.pos p) 0 p0 end = falseinduction p; trivial. Qed.p:positiveNless_aux (N.pos p) 0 p = falseforall 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:positiveNless 0 (N.pos p) = true -> {p0 : positive | N.pos p = N.pos p0}p:positiveNless 0 (N.pos p) = true -> {p0 : positive | N.pos p = N.pos p0}p:positiveH:Nless 0 (N.pos p) = true{p0 : positive | N.pos p = N.pos p0}reflexivity. Qed.p:positiveH:Nless 0 (N.pos p) = trueN.pos p = N.pos pforall a : N, Nless 0 a = false -> a = 0%Nforall a : N, Nless 0 a = false -> a = 0%NH:Nless 0 0 = false0%N = 0%Np:positiveH:Nless 0 (N.pos p) = falseN.pos p = 0%Np:positiveH:Nless 0 (N.pos p) = falseN.pos p = 0%Ninduction p as [|p IHp|]; discriminate || simpl; auto using IHp. Qed.p:positiveH:Nless 0 (N.pos p) = falseFalseforall a a' a'' : N, Nless a a' = true -> Nless a' a'' = true -> Nless a a'' = trueforall a a' a'' : N, Nless a a' = true -> Nless a' a'' = true -> Nless a a'' = truea', a'':NH:Nless 0 a' = trueH0:Nless a' a'' = trueNless 0 a'' = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.double a) a' = trueH0:Nless a' a'' = trueNless (N.double a) a'' = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) a' = trueH0:Nless a' a'' = trueNless (N.succ_double a) a'' = truea', a'':NH:Nless 0 a' = trueH0:Nless a' a'' = trueNless 0 a'' = truea', a'':NH:Nless 0 a' = trueH0:Nless a' a'' = trueHeqn:Nless 0 a'' = truetrue = truea', a'':NH:Nless 0 a' = trueH0:Nless a' a'' = trueHeqn:Nless 0 a'' = falsefalse = truetrivial.a', a'':NH:Nless 0 a' = trueH0:Nless a' a'' = trueHeqn:Nless 0 a'' = truetrue = truea', a'':NH:Nless 0 a' = trueH0:Nless a' a'' = trueHeqn:Nless 0 a'' = falsefalse = truediscriminate H0.a', a'':NH:Nless 0 a' = trueH0:false = trueHeqn:Nless 0 a'' = falsefalse = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.double a) a' = trueH0:Nless a' a'' = trueNless (N.double a) a'' = truea:NIHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = truea'':NH:Nless (N.double a) 0 = trueH0:Nless 0 a'' = trueNless (N.double a) a'' = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.double a) (N.double a') = trueH0:Nless (N.double a') a'' = trueNless (N.double a) a'' = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') a'' = trueNless (N.double a) a'' = truea:NIHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = truea'':NH:Nless (N.double a) 0 = trueH0:Nless 0 a'' = trueNless (N.double a) a'' = truediscriminate H.a:NIHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = truea'':NH:false = trueH0:Nless 0 a'' = trueNless (N.double a) a'' = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.double a) (N.double a') = trueH0:Nless (N.double a') a'' = trueNless (N.double a) a'' = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless a a' = trueH0:Nless (N.double a') a'' = trueNless (N.double a) a'' = truea:NIHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = truea':NH:Nless a a' = trueH0:Nless (N.double a') 0 = trueNless (N.double a) 0 = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless a a' = trueH0:Nless (N.double a') (N.double a'') = trueIHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = trueNless (N.double a) (N.double a'') = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless a a' = trueH0:Nless (N.double a') (N.succ_double a'') = trueIHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = trueNless (N.double a) (N.succ_double a'') = truea:NIHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = truea':NH:Nless a a' = trueH0:Nless (N.double a') 0 = trueNless (N.double a) 0 = truediscriminate H0.a:NIHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = truea':NH:Nless a a' = trueH0:false = trueNless (N.double a) 0 = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless a a' = trueH0:Nless (N.double a') (N.double a'') = trueIHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = trueNless (N.double a) (N.double a'') = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless a a' = trueH0:Nless a' a'' = trueIHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = trueNless (N.double a) (N.double a'') = trueexact (IHa _ _ H H0).a:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless a a' = trueH0:Nless a' a'' = trueIHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = trueNless a a'' = trueapply Nless_def_3.a:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless a a' = trueH0:Nless (N.double a') (N.succ_double a'') = trueIHa'':Nless (N.double a') a'' = true -> Nless (N.double a) a'' = trueNless (N.double a) (N.succ_double a'') = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') a'' = trueNless (N.double a) a'' = truea:NIHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = truea':NH:Nless (N.double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') 0 = trueNless (N.double a) 0 = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') (N.double a'') = trueNless (N.double a) (N.double a'') = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') (N.succ_double a'') = trueNless (N.double a) (N.succ_double a'') = truea:NIHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = truea':NH:Nless (N.double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') 0 = trueNless (N.double a) 0 = truediscriminate H0.a:NIHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = truea':NH:Nless (N.double a) (N.succ_double a') = trueH0:false = trueNless (N.double a) 0 = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') (N.double a'') = trueNless (N.double a) (N.double a'') = truediscriminate H0.a:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.double a) (N.succ_double a') = trueH0:false = trueNless (N.double a) (N.double a'') = trueapply Nless_def_3.a:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') (N.succ_double a'') = trueNless (N.double a) (N.succ_double a'') = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) a' = trueH0:Nless a' a'' = trueNless (N.succ_double a) a'' = truea:NIHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = truea'':NH:Nless (N.succ_double a) 0 = trueH0:Nless 0 a'' = trueNless (N.succ_double a) a'' = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) (N.double a') = trueH0:Nless (N.double a') a'' = trueNless (N.succ_double a) a'' = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') a'' = trueNless (N.succ_double a) a'' = truea:NIHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = truea'':NH:Nless (N.succ_double a) 0 = trueH0:Nless 0 a'' = trueNless (N.succ_double a) a'' = truediscriminate H.a:NIHa:forall a' a''0 : N, Nless a a' = true -> Nless a' a''0 = true -> Nless a a''0 = truea'':NH:false = trueH0:Nless 0 a'' = trueNless (N.succ_double a) a'' = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) (N.double a') = trueH0:Nless (N.double a') a'' = trueNless (N.succ_double a) a'' = truediscriminate H.a:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:false = trueH0:Nless (N.double a') a'' = trueNless (N.succ_double a) a'' = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') a'' = trueNless (N.succ_double a) a'' = truea:NIHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = truea':NH:Nless (N.succ_double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') 0 = trueNless (N.succ_double a) 0 = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') (N.double a'') = trueIHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = trueNless (N.succ_double a) (N.double a'') = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') (N.succ_double a'') = trueIHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = trueNless (N.succ_double a) (N.succ_double a'') = truea:NIHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = truea':NH:Nless (N.succ_double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') 0 = trueNless (N.succ_double a) 0 = truediscriminate H0.a:NIHa:forall a'0 a'' : N, Nless a a'0 = true -> Nless a'0 a'' = true -> Nless a a'' = truea':NH:Nless (N.succ_double a) (N.succ_double a') = trueH0:false = trueNless (N.succ_double a) 0 = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') (N.double a'') = trueIHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = trueNless (N.succ_double a) (N.double a'') = truediscriminate H0.a:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) (N.succ_double a') = trueH0:false = trueIHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = trueNless (N.succ_double a) (N.double a'') = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) (N.succ_double a') = trueH0:Nless (N.succ_double a') (N.succ_double a'') = trueIHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = trueNless (N.succ_double a) (N.succ_double a'') = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless (N.succ_double a) (N.succ_double a') = trueH0:Nless a' a'' = trueIHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = trueNless (N.succ_double a) (N.succ_double a'') = truea:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless a a' = trueH0:Nless a' a'' = trueIHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = trueNless (N.succ_double a) (N.succ_double a'') = trueexact (IHa _ _ H H0). Qed.a:NIHa:forall a'0 a''0 : N, Nless a a'0 = true -> Nless a'0 a''0 = true -> Nless a a''0 = truea', a'':NH:Nless a a' = trueH0:Nless a' a'' = trueIHa'':Nless (N.succ_double a') a'' = true -> Nless (N.succ_double a) a'' = trueNless a a'' = trueforall 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:NIHa: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:NIHa: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':NHeqb:Nless 0 a' = true{true = true} + {Nless a' 0 = true} + {0%N = a'}a':NHeqb:Nless 0 a' = false{false = true} + {Nless a' 0 = true} + {0%N = a'}a':NHeqb:Nless 0 a' = true{true = true} + {Nless a' 0 = true} + {0%N = a'}a':NHeqb:Nless 0 a' = true{true = true} + {Nless a' 0 = true}auto.a':NHeqb:Nless 0 a' = truetrue = truea':NHeqb:Nless 0 a' = false{false = true} + {Nless a' 0 = true} + {0%N = a'}a':NHeqb:Nless 0 a' = false0%N = a'reflexivity.a':NHeqb:Nless 0 a' = false0%N = 0%Na:NIHa: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:NIHa: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:NIHa: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:NIHa: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:NIHa: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:NIHa: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:NIHa: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:NIHa: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:NIHa: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}auto.a:NIHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}Heqb:Nless 0 (N.double a) = truetrue = truea:NIHa: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}exact (N0_less_2 _ Heqb).a:NIHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}Heqb:Nless 0 (N.double a) = falseN.double a = 0%Na:NIHa: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:NIHa: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:NIHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}a':Ns:{Nless a a' = true} + {Nless a' a = true}{Nless a a' = true} + {Nless a' a = true} + {N.double a = N.double a'}a':NIHa: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:NIHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}a':Ns:{Nless a a' = true} + {Nless a' a = true}{Nless a a' = true} + {Nless a' a = true} + {N.double a = N.double a'}assumption.a:NIHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}a':Ns:{Nless a a' = true} + {Nless a' a = true}{Nless a a' = true} + {Nless a' a = true}a':NIHa: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'}reflexivity.a':NIHa:forall a'0 : N, {Nless a' a'0 = true} + {Nless a'0 a' = true} + {a' = a'0}N.double a' = N.double a'a:NIHa: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:NIHa: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}apply Nless_def_3.a:NIHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}a':NNless (N.double a) (N.succ_double a') = truea:NIHa: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:NIHa: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:NIHa: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:NIHa: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:NIHa: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:NIHa: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}destruct a; reflexivity.a:NIHa:forall a' : N, {Nless a a' = true} + {Nless a' a = true} + {a = a'}Nless 0 (N.succ_double a) = truea:NIHa: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:NIHa: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}apply Nless_def_3.a:NIHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}a':NNless (N.double a') (N.succ_double a) = truea:NIHa: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:NIHa: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:NIHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}a':Ns:{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':NIHa: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:NIHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}a':Ns:{Nless a a' = true} + {Nless a' a = true}{Nless a a' = true} + {Nless a' a = true} + {N.succ_double a = N.succ_double a'}assumption.a:NIHa:forall a'0 : N, {Nless a a'0 = true} + {Nless a'0 a = true} + {a = a'0}a':Ns:{Nless a a' = true} + {Nless a' a = true}{Nless a a' = true} + {Nless a' a = true}a':NIHa: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'}reflexivity. Qed.a':NIHa: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'
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) = nforall n : N, Bv2N (N2Bv n) = nBv2N (N2Bv 0) = 0%Np:positiveBv2N (N2Bv (N.pos p)) = N.pos pinduction p; simpl in *; auto; rewrite IHp; simpl; auto. Qed.p:positiveBv2N (N2Bv (N.pos p)) = N.pos p
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) <= nforall (n : nat) (bv : Bvector n), N.size_nat (Bv2N bv) <= nN.size_nat (Bv2N []) <= 0h:booln:natbv:VectorDef.t bool nIHbv:N.size_nat (Bv2N bv) <= nN.size_nat (Bv2N (h :: bv)) <= S nh:booln:natbv:VectorDef.t bool nIHbv:N.size_nat (Bv2N bv) <= nN.size_nat (Bv2N (h :: bv)) <= S ndestruct h; destruct (Bv2N n bv); simpl ; auto with arith. Qed.h:booln:natbv:VectorDef.t bool nIHbv:N.size_nat (Bv2N bv) <= nN.size_nat (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) <= S n
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 nforall (n : nat) (bv : Bvector (S n)), Bsign n bv = true <-> N.size_nat (Bv2N bv) = S na:boola = true <-> N.size_nat (if a then 1%N else 0%N) = 1a:booln:natv:Vector.t bool (S n)H:Bsign n v = true <-> N.size_nat (Bv2N v) = S nBsign 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.a:booln:natv:Vector.t bool (S n)H:Bsign n v = true <-> N.size_nat (Bv2N v) = S nBsign n v = true <-> N.size_nat (if a then N.succ_double (Bv2N v) else N.double (Bv2N v)) = S (S n)n:natbv:Bvector n(Bv2N bv < N.shiftl_nat 1 n)%Nn:natbv:Bvector n(Bv2N bv < N.shiftl_nat 1 n)%N(0 < 1)%Nh:booln:natbv:VectorDef.t bool nIHbv:(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))%Nconstructor.(0 < 1)%Nh:booln:natbv:VectorDef.t bool nIHbv:(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))%Nn:natbv:VectorDef.t bool nIHbv:(Bv2N bv < N.shiftl_nat 1 n)%N(N.succ_double (Bv2N bv) < N.double (N.shiftl_nat 1 n))%Nn:natbv:VectorDef.t bool nIHbv:(Bv2N bv < N.shiftl_nat 1 n)%N(N.double (Bv2N bv) < N.double (N.shiftl_nat 1 n))%Napply N.succ_double_lt...n:natbv:VectorDef.t bool nIHbv:(Bv2N bv < N.shiftl_nat 1 n)%N(N.succ_double (Bv2N bv) < N.double (N.shiftl_nat 1 n))%Napply N.double_lt_mono... Qed.n:natbv:VectorDef.t bool nIHbv:(Bv2N bv < N.shiftl_nat 1 n)%N(N.double (Bv2N bv) < N.double (N.shiftl_nat 1 n))%Nn:natv:ByteVector n(ByteV2N v < N.shiftl_nat 1 (n * 8))%Nn:natv:ByteVector n(ByteV2N v < N.shiftl_nat 1 (n * 8))%Napply Bv2N_upper_bound. Qed.n:natv:ByteVector n(Bv2N (to_Bvector v) < N.shiftl_nat 1 (n * 8))%N
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) aforall a : N, N2Bv a = N2Bv_gen (N.size_nat a) aBnil = Bnilp:positiveP2Bv p = N2Bv_gen (Pos.size_nat p) (N.pos p)induction p; simpl; intros; auto; congruence. Qed.p:positiveP2Bv p = N2Bv_gen (Pos.size_nat p) (N.pos p)
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 kforall (a : N) (k : nat), N2Bv_gen (N.size_nat a + k) a = N2Bv a ++ Bvect_false kforall k : nat, N2Bv_gen k 0 = Bvect_false kp:positiveforall k : nat, N2Bv_gen (Pos.size_nat p + k) (N.pos p) = P2Bv p ++ Bvect_false kinduction p; simpl; intros;unfold Bcons; f_equal; auto. Qed.p:positiveforall k : nat, N2Bv_gen (Pos.size_nat p + k) (N.pos p) = P2Bv p ++ Bvect_false k
Here comes now the second composition result.
forall (n : nat) (bv : Bvector n), N2Bv_gen n (Bv2N bv) = bvforall (n : nat) (bv : Bvector n), N2Bv_gen n (Bv2N bv) = bvN2Bv_gen 0 (Bv2N []) = []h:booln:natbv:VectorDef.t bool nIHbv:N2Bv_gen n (Bv2N bv) = bvN2Bv_gen (S n) (Bv2N (h :: bv)) = h :: bvh:booln:natbv:VectorDef.t bool nIHbv:N2Bv_gen n (Bv2N bv) = bvN2Bv_gen (S n) (Bv2N (h :: bv)) = h :: bvh:booln:natbv:VectorDef.t bool nIHbv:N2Bv_gen n (Bv2N bv) = bvmatch (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 :: bvh:booln:natbv:VectorDef.t bool nN2Bv_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 :: bvdestruct (Bv2N _ bv); destruct h; intro H; rewrite <- H; simpl; trivial; induction n; simpl; auto. Qed.h:booln:natbv:VectorDef.t bool nN2Bv_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
accessing some precise bits.
forall (n : nat) (bv : Bvector (S n)), N.odd (Bv2N bv) = Blow n bvforall (n : nat) (bv : Bvector (S n)), N.odd (Bv2N bv) = Blow n bvforall (h : bool) (n : nat) (t : Vector.t bool n), N.odd (Bv2N (h :: t)) = Blow n (h :: t)h:booln:natt:Vector.t bool nN.odd (Bv2N (h :: t)) = Blow n (h :: t)h:booln:natt:Vector.t bool nN.odd (Bv2N (h :: t)) = Vector.hd (h :: t)destruct (Bv2N n t); simpl; destruct h; auto. Qed. Notation Bnth := (@Vector.nth_order bool).h:booln:natt:Vector.t bool nN.odd (if h then N.succ_double (Bv2N t) else N.double (Bv2N t)) = hforall (n : nat) (bv : Bvector n) (p : nat) (H : p < n), Bnth bv H = N.testbit_nat (Bv2N bv) pforall (n : nat) (bv : Bvector n) (p : nat) (H : p < n), Bnth bv H = N.testbit_nat (Bv2N bv) pp:natH:p < 0Bnth [] H = N.testbit_nat (Bv2N []) ph:booln:natbv:VectorDef.t bool nIHbv:forall (p0 : nat) (H0 : p0 < n), Bnth bv H0 = N.testbit_nat (Bv2N bv) p0p:natH:p < S nBnth (h :: bv) H = N.testbit_nat (Bv2N (h :: bv)) ph:booln:natbv:VectorDef.t bool nIHbv:forall (p0 : nat) (H0 : p0 < n), Bnth bv H0 = N.testbit_nat (Bv2N bv) p0p:natH:p < S nBnth (h :: bv) H = N.testbit_nat (Bv2N (h :: bv)) ph:booln:natbv:VectorDef.t bool nIHbv:forall (p : nat) (H0 : p < n), Bnth bv H0 = N.testbit_nat (Bv2N bv) pH:0 < S nBnth (h :: bv) H = N.testbit_nat (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) 0h:booln:natbv:VectorDef.t bool nIHbv:forall (p0 : nat) (H0 : p0 < n), Bnth bv H0 = N.testbit_nat (Bv2N bv) p0p:natH:S p < S nBnth (h :: bv) H = N.testbit_nat (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) (S p)h:booln:natbv:VectorDef.t bool nIHbv:forall (p0 : nat) (H0 : p0 < n), Bnth bv H0 = N.testbit_nat (Bv2N bv) p0p:natH:S p < S nBnth (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.h:booln:natbv:VectorDef.t bool np:natH:S p < S nIHbv:Bnth bv (Lt.lt_S_n p n H) = N.testbit_nat (Bv2N bv) pBnth (h :: bv) H = N.testbit_nat (if h then N.succ_double (Bv2N bv) else N.double (Bv2N bv)) (S p)forall (n : N) (p : nat), N.size_nat n <= p -> N.testbit_nat n p = falseforall (n : N) (p : nat), N.size_nat n <= p -> N.testbit_nat n p = falseforall p : nat, N.size_nat 0 <= p -> N.testbit_nat 0 p = falsen:positiveforall p : nat, N.size_nat (N.pos n) <= p -> N.testbit_nat (N.pos n) p = falsen:positiveforall p : nat, N.size_nat (N.pos n) <= p -> N.testbit_nat (N.pos n) p = falsen:positiveIHn:forall p : nat, Pos.size_nat n <= p -> Pos.testbit_nat n p = falseH:S (Pos.size_nat n) <= 0true = falseH:1 <= 0true = falseinversion H. Qed.H:1 <= 0true = falseforall (n : N) (p : nat) (H : p < N.size_nat n), N.testbit_nat n p = Bnth (N2Bv n) Hforall (n : N) (p : nat) (H : p < N.size_nat n), N.testbit_nat n p = Bnth (N2Bv n) Hforall (p : nat) (H : p < N.size_nat 0), N.testbit_nat 0 p = Bnth (N2Bv 0) Hn:positiveforall (p : nat) (H : p < N.size_nat (N.pos n)), N.testbit_nat (N.pos n) p = Bnth (N2Bv (N.pos n)) Hn:positiveforall (p : nat) (H : p < N.size_nat (N.pos n)), N.testbit_nat (N.pos n) p = Bnth (N2Bv (N.pos n)) Hintros H ; destruct (Lt.lt_n_O _ (Lt.lt_S_n _ _ H)). Qed.p:natforall 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 []
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:natv1, v2:Vector.t bool nH:Bv2N (BVxor n v1 v2) = N.lxor (Bv2N v1) (Bv2N v2)a, b:boolBv2N (BVxor (S n) (a :: v1) (b :: v2)) = N.lxor (Bv2N (a :: v1)) (Bv2N (b :: v2))n:natv1, v2:Vector.t bool nH:Bv2N (BVxor n v1 v2) = N.lxor (Bv2N v1) (Bv2N v2)a, b:boolBv2N (BVxor (S n) (a :: v1) (b :: v2)) = N.lxor (Bv2N (a :: v1)) (Bv2N (b :: v2))destruct a, b, (Bv2N n v1), (Bv2N n v2); simpl in *; rewrite H ; now simpl. Qed.n:natv1, v2:Vector.t bool nH: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))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:natv1, v2:Vector.t bool nH: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))destruct a, b, (Bv2N n v1), (Bv2N n v2); simpl; auto. Qed.n:natv1, v2:Vector.t bool nH: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))n:NN2Bv_sized (N.size_nat n) n = N2Bv nn:NN2Bv_sized (N.size_nat n) n = N2Bv np:positiveP2Bv_sized (Pos.size_nat p) p = P2Bv pall: rewrite IHp... Qed.p:positiveIHp:P2Bv_sized (Pos.size_nat p) p = P2Bv ptrue :: P2Bv_sized (Pos.size_nat p) p = Bcons true (Pos.size_nat p) (P2Bv p)p:positiveIHp:P2Bv_sized (Pos.size_nat p) p = P2Bv pfalse :: P2Bv_sized (Pos.size_nat p) p = Bcons false (Pos.size_nat p) (P2Bv p)n:natv:Bvector nN2Bv_sized n (Bv2N v) = vn:natv:Bvector nN2Bv_sized n (Bv2N v) = vdestruct h; unfold N2Bv_sized; destruct (Bv2N n v) as [|[]]; rewrite <- IHv... Qed.h:booln:natv:VectorDef.t bool nIHv:N2Bv_sized n (Bv2N v) = vN2Bv_sized (S n) (if h then N.succ_double (Bv2N v) else N.double (Bv2N v)) = h :: va:Nk:natN2Bv_sized (N.size_nat a + k) a = N2Bv a ++ Bvect_false ka:Nk:natN2Bv_sized (N.size_nat a + k) a = N2Bv a ++ Bvect_false kinduction p; simpl; f_equal... Qed.p:positivek:natN2Bv_sized (N.size_nat (N.pos p) + k) (N.pos p) = N2Bv (N.pos p) ++ Bvect_false k