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.
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2018 *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
Author: Arnaud Spiwack (+ Pierre Letouzey)
Require Import CyclicAxioms. Require Export ZArith. Require Export Int63. Import Zpow_facts. Import Utf8. Import Lia. Local Open Scope int63_scope.
{2 Operators }
Definition Pdigits := Eval compute in P_of_succ_nat (size - 1). Fixpoint positive_to_int_rec (n:nat) (p:positive) := match n, p with | O, _ => (Npos p, 0) | S n, xH => (0%N, 1) | S n, xO p => let (N,i) := positive_to_int_rec n p in (N, i << 1) | S n, xI p => let (N,i) := positive_to_int_rec n p in (N, (i << 1) + 1) end. Definition positive_to_int := positive_to_int_rec size. Definition mulc_WW x y := let (h, l) := mulc x y in if is_zero h then if is_zero l then W0 else WW h l else WW h l. Notation "n '*c' m" := (mulc_WW n m) (at level 40, no associativity) : int63_scope. Definition pos_mod p x := if p <= digits then let p := digits - p in (x << p) >> p else x. Notation pos_mod_int := pos_mod. Import ZnZ. Instance int_ops : ZnZ.Ops int := {| digits := Pdigits; (* number of digits *) zdigits := Int63.digits; (* number of digits *) to_Z := Int63.to_Z; (* conversion to Z *) of_pos := positive_to_int; (* positive -> N*int63 : p => N,i where p = N*2^31+phi i *) head0 := Int63.head0; (* number of head 0 *) tail0 := Int63.tail0; (* number of tail 0 *) zero := 0; one := 1; minus_one := Int63.max_int; compare := Int63.compare; eq0 := Int63.is_zero; opp_c := Int63.oppc; opp := Int63.opp; opp_carry := Int63.oppcarry; succ_c := Int63.succc; add_c := Int63.addc; add_carry_c := Int63.addcarryc; succ := Int63.succ; add := Int63.add; add_carry := Int63.addcarry; pred_c := Int63.predc; sub_c := Int63.subc; sub_carry_c := Int63.subcarryc; pred := Int63.pred; sub := Int63.sub; sub_carry := Int63.subcarry; mul_c := mulc_WW; mul := Int63.mul; square_c := fun x => mulc_WW x x; div21 := diveucl_21; div_gt := diveucl; (* this is supposed to be the special case of division a/b where a > b *) div := diveucl; modulo_gt := Int63.mod; modulo := Int63.mod; gcd_gt := Int63.gcd; gcd := Int63.gcd; add_mul_div := Int63.addmuldiv; pos_mod := pos_mod_int; is_even := Int63.is_even; sqrt2 := Int63.sqrt2; sqrt := Int63.sqrt; ZnZ.lor := Int63.lor; ZnZ.land := Int63.land; ZnZ.lxor := Int63.lxor |}. Local Open Scope Z_scope.∀ x : int, is_zero x = true → φ (x) = 0intros x;rewrite is_zero_spec;intros H;rewrite H;trivial. Qed.∀ x : int, is_zero x = true → φ (x) = 0∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int p)) * wB + to_Z (snd (positive_to_int p))∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int p)) * wB + to_Z (snd (positive_to_int p))wB <= wB → ∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int p)) * wB + φ (snd (positive_to_int p)) ∧ φ (snd (positive_to_int p)) < wBH:wB <= wB → ∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int p)) * wB + φ (snd (positive_to_int p)) ∧ φ (snd (positive_to_int p)) < wB∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int p)) * wB + to_Z (snd (positive_to_int p))wB <= wB → ∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int p)) * wB + φ (snd (positive_to_int p)) ∧ φ (snd (positive_to_int p)) < wB2 ^ Z.of_nat size <= wB → ∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int_rec size p)) * 2 ^ Z.of_nat size + φ (snd (positive_to_int_rec size p)) ∧ φ (snd (positive_to_int_rec size p)) < 2 ^ Z.of_nat size2 ^ Z.of_nat 0 <= wB → ∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int_rec 0 p)) * 2 ^ Z.of_nat 0 + φ (snd (positive_to_int_rec 0 p)) ∧ φ (snd (positive_to_int_rec 0 p)) < 2 ^ Z.of_nat 0∀ n : nat, (2 ^ Z.of_nat n <= wB → ∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int_rec n p)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p)) ∧ φ (snd (positive_to_int_rec n p)) < 2 ^ Z.of_nat n) → 2 ^ Z.of_nat (S n) <= wB → ∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int_rec (S n) p)) * 2 ^ Z.of_nat (S n) + φ (snd (positive_to_int_rec (S n) p)) ∧ φ (snd (positive_to_int_rec (S n) p)) < 2 ^ Z.of_nat (S n)∀ n : nat, (2 ^ Z.of_nat n <= wB → ∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int_rec n p)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p)) ∧ φ (snd (positive_to_int_rec n p)) < 2 ^ Z.of_nat n) → 2 ^ Z.of_nat (S n) <= wB → ∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int_rec (S n) p)) * 2 ^ Z.of_nat (S n) + φ (snd (positive_to_int_rec (S n) p)) ∧ φ (snd (positive_to_int_rec (S n) p)) < 2 ^ Z.of_nat (S n)n:nat(2 ^ Z.of_nat n <= wB → ∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int_rec n p)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p)) ∧ φ (snd (positive_to_int_rec n p)) < 2 ^ Z.of_nat n) → 2 ^ Z.of_nat n * 2 <= wB → ∀ p : positive, Z.pos p = Z.of_N (fst (positive_to_int_rec (S n) p)) * (2 ^ Z.of_nat n * 2) + φ (snd (positive_to_int_rec (S n) p)) ∧ φ (snd (positive_to_int_rec (S n) p)) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveZ.pos p = Z.of_N (fst (positive_to_int_rec (S n) p)) * (2 ^ Z.of_nat n * 2) + φ (snd (positive_to_int_rec (S n) p)) ∧ φ (snd (positive_to_int_rec (S n) p)) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positive2 ^ Z.of_nat n <= wBn:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBZ.pos p = Z.of_N (fst (positive_to_int_rec (S n) p)) * (2 ^ Z.of_nat n * 2) + φ (snd (positive_to_int_rec (S n) p)) ∧ φ (snd (positive_to_int_rec (S n) p)) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBZ.pos p = Z.of_N (fst (positive_to_int_rec (S n) p)) * (2 ^ Z.of_nat n * 2) + φ (snd (positive_to_int_rec (S n) p)) ∧ φ (snd (positive_to_int_rec (S n) p)) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB∀ p0 : positive, Z.pos p0~1 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p0 in (N, (i << 1 + 1)%int63))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, (i << 1 + 1)%int63))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, (i << 1 + 1)%int63))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB∀ p0 : positive, Z.pos p0~0 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiveZ.pos p1~1 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p1 in (N, (i << 1 + 1)%int63))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p1 in (N, (i << 1 + 1)%int63))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p1 in (N, (i << 1 + 1)%int63))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB∀ p0 : positive, Z.pos p0~0 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positive∀ (n0 : N) (i : int), Z.pos p1 = Z.of_N n0 * 2 ^ Z.of_nat n + φ (i) ∧ φ (i) < 2 ^ Z.of_nat n → Z.pos p1~1 = Z.of_N n0 * (2 ^ Z.of_nat n * 2) + φ (i << 1 + 1) ∧ φ (i << 1 + 1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB∀ p0 : positive, Z.pos p0~0 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat nZ.pos p1~1 = Z.of_N n1 * (2 ^ Z.of_nat n * 2) + φ (i << 1 + 1) ∧ φ (i << 1 + 1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB∀ p0 : positive, Z.pos p0~0 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat n2 * (Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)) + 1 = Z.of_N n1 * (2 ^ Z.of_nat n * 2) + φ (i << 1 + 1) ∧ φ (i << 1 + 1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB∀ p0 : positive, Z.pos p0~0 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat n2 * (Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)) + 1 = Z.of_N n1 * (2 ^ Z.of_nat n * 2) + (φ (i) * 2 + 1) ∧ φ (i) * 2 + 1 < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat nφ (i) * 2 + 1 = φ (i << 1 + 1)n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB∀ p0 : positive, Z.pos p0~0 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat nφ (i) * 2 + 1 = φ (i << 1 + 1)n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB∀ p0 : positive, Z.pos p0~0 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat n0 <= φ (i) * 2 + 1 ∧ φ (i) * 2 + 1 < wBn:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB∀ p0 : positive, Z.pos p0~0 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB∀ p0 : positive, Z.pos p0~0 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p0 in (N, i << 1))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiveZ.pos p1~0 = Z.of_N (fst (let (N, i) := positive_to_int_rec n p1 in (N, i << 1))) * (2 ^ Z.of_nat n * 2) + φ (snd (let (N, i) := positive_to_int_rec n p1 in (N, i << 1))) ∧ φ (snd (let (N, i) := positive_to_int_rec n p1 in (N, i << 1))) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positive∀ (n0 : N) (i : int), Z.pos p1 = Z.of_N n0 * 2 ^ Z.of_nat n + φ (i) ∧ φ (i) < 2 ^ Z.of_nat n → Z.pos p1~0 = Z.of_N n0 * (2 ^ Z.of_nat n * 2) + φ (i << 1) ∧ φ (i << 1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat nZ.pos p1~0 = Z.of_N n1 * (2 ^ Z.of_nat n * 2) + φ (i << 1) ∧ φ (i << 1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat n2 * (Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)) = Z.of_N n1 * (2 ^ Z.of_nat n * 2) + φ (i << 1) ∧ φ (i << 1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat n2 * (Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)) = Z.of_N n1 * (2 ^ Z.of_nat n * 2) + φ (i) * 2 ∧ φ (i) * 2 < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat nφ (i) * 2 = φ (i << 1)n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat nφ (i) * 2 = φ (i << 1)n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wBp1:positiven1:Ni:intH1:Z.pos p1 = Z.of_N n1 * 2 ^ Z.of_nat n + φ (i)H2:φ (i) < 2 ^ Z.of_nat n0 <= φ (i) * 2 ∧ φ (i) * 2 < wBn:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2rewrite to_Z_1; assert (0 < 2^ Z_of_nat n); auto with zarith. Qed.n:natIH:2 ^ Z.of_nat n <= wB → ∀ p0 : positive, Z.pos p0 = Z.of_N (fst (positive_to_int_rec n p0)) * 2 ^ Z.of_nat n + φ (snd (positive_to_int_rec n p0)) ∧ φ (snd (positive_to_int_rec n p0)) < 2 ^ Z.of_nat nHle:2 ^ Z.of_nat n * 2 <= wBp:positiveF1:2 ^ Z.of_nat n <= wB1 = φ (1) ∧ φ (1) < 2 ^ Z.of_nat n * 2∀ x y : int, [||x *c y||] = φ (x) * φ (y)∀ x y : int, [||x *c y||] = φ (x) * φ (y)x, y:int[||(let (h, l) := mulc x y in if is_zero h then if is_zero l then W0 else DoubleType.WW h l else DoubleType.WW h l)||] = φ (x) * φ (y)x, y, i, i0:intHeq:φ (x) * φ (y) = φ (i) * wB + φ (i0)[||(if is_zero i then if is_zero i0 then W0 else DoubleType.WW i i0 else DoubleType.WW i i0)||] = φ (i) * wB + φ (i0)x, y, i, i0:intHeq:φ (x) * φ (y) = φ (i) * wB + φ (i0)H:is_zero i = true[||(if is_zero i0 then W0 else DoubleType.WW i i0)||] = φ (i) * wB + φ (i0)x, y, i, i0:intHeq:φ (x) * φ (y) = φ (i) * wB + φ (i0)H:i = 0%int63[||(if is_zero i0 then W0 else DoubleType.WW 0%int63 i0)||] = 0 * wB + φ (i0)apply is_zero_spec in H0;rewrite H0, to_Z_0, Zmult_comm;trivial. Qed.x, y, i, i0:intHeq:φ (x) * φ (y) = φ (i) * wB + φ (i0)H:i = 0%int63H0:is_zero i0 = true[||W0||] = 0 * wB + φ (i0)Proof (fun x => mulc_WW_spec x x).∀ x : int, [||x *c x||] = φ (x) * φ (x)∀ a b : int, 0 < φ (b) → let (q, r) := diveucl a b in φ (a) = φ (q) * φ (b) + φ (r) ∧ 0 <= φ (r) ∧ φ (r) < φ (b)∀ a b : int, 0 < φ (b) → let (q, r) := diveucl a b in φ (a) = φ (q) * φ (b) + φ (r) ∧ 0 <= φ (r) ∧ φ (r) < φ (b)a, b:intH:0 < φ (b)W:let (q, r) := diveucl a b in (φ (q), φ (r)) = Z.div_eucl φ (a) φ (b)let (q, r) := diveucl a b in φ (a) = φ (q) * φ (b) + φ (r) ∧ 0 <= φ (r) ∧ φ (r) < φ (b)a, b:intH:0 < φ (b)W:let (q, r) := diveucl a b in (φ (q), φ (r)) = Z.div_eucl φ (a) φ (b)H0:φ (b) > 0let (q, r) := diveucl a b in φ (a) = φ (q) * φ (b) + φ (r) ∧ 0 <= φ (r) ∧ φ (r) < φ (b)a, b:intH:0 < φ (b)W:let (q, r) := diveucl a b in (φ (q), φ (r)) = Z.div_eucl φ (a) φ (b)H0:φ (b) > 0(let (q, r) := Z.div_eucl φ (a) φ (b) in φ (a) = φ (b) * q + r ∧ 0 <= r ∧ r < φ (b)) → let (q, r) := diveucl a b in φ (a) = φ (q) * φ (b) + φ (r) ∧ 0 <= φ (r) ∧ φ (r) < φ (b)inversion W;rewrite Zmult_comm;trivial. Qed.a, b:intH:0 < φ (b)i, i0:intz, z0:ZW:(φ (i), φ (i0)) = (z, z0)H0:φ (b) > 0φ (a) = φ (b) * z + z0 ∧ 0 <= z0 ∧ z0 < φ (b) → φ (a) = φ (i) * φ (b) + φ (i0) ∧ 0 <= φ (i0) ∧ φ (i0) < φ (b)∀ n p a : Z, 0 <= p ∧ p <= n → ((a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p)) mod 2 ^ n = a mod 2 ^ p∀ n p a : Z, 0 <= p ∧ p <= n → ((a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p)) mod 2 ^ n = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= n((a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p)) mod 2 ^ n = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= n(a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p) = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= n0 <= (a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p) ∧ (a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p) < 2 ^ nn, p, a:ZH:0 <= p ∧ p <= n(a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p) = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= n(a * 2 ^ (n - p) - a * 2 ^ (n - p) / 2 ^ n * 2 ^ n) / 2 ^ (n - p) = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= n(a * 2 ^ (n - p) + - (a * 2 ^ (n - p) / 2 ^ n * 2 ^ n)) / 2 ^ (n - p) = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= na + - (a * 2 ^ (n - p) / 2 ^ n * 2 ^ n) / 2 ^ (n - p) = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= na + - (a * 2 ^ (n - p) / (2 ^ (n - p) * 2 ^ p) * (2 ^ (n - p) * 2 ^ p)) / 2 ^ (n - p) = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= na + - (a / 2 ^ p * (2 ^ (n - p) * 2 ^ p)) / 2 ^ (n - p) = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= na + - (a / 2 ^ p * 2 ^ p * 2 ^ (n - p)) / 2 ^ (n - p) = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= na + - (a / 2 ^ p * 2 ^ p) * 2 ^ (n - p) / 2 ^ (n - p) = a mod 2 ^ psymmetry; apply Zmod_eq; auto with zarith.n, p, a:ZH:0 <= p ∧ p <= na + - (a / 2 ^ p * 2 ^ p) = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= n0 <= (a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p) ∧ (a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p) < 2 ^ nn, p, a:ZH:0 <= p ∧ p <= nb:ZHeqb:b = a * 2 ^ (n - p)0 <= b mod 2 ^ n / 2 ^ (n - p) ∧ b mod 2 ^ n / 2 ^ (n - p) < 2 ^ nn, p, a:ZH:0 <= p ∧ p <= nb:ZHeqb:b = a * 2 ^ (n - p)H0:0 <= b mod 2 ^ nH1:b mod 2 ^ n < 2 ^ n0 <= b mod 2 ^ n / 2 ^ (n - p) ∧ b mod 2 ^ n / 2 ^ (n - p) < 2 ^ nn, p, a:ZH:0 <= p ∧ p <= nb:ZHeqb:b = a * 2 ^ (n - p)H0:0 <= b mod 2 ^ nH1:b mod 2 ^ n < 2 ^ n0 <= b mod 2 ^ n / 2 ^ (n - p)n, p, a:ZH:0 <= p ∧ p <= nb:ZHeqb:b = a * 2 ^ (n - p)H0:0 <= b mod 2 ^ nH1:b mod 2 ^ n < 2 ^ nb mod 2 ^ n / 2 ^ (n - p) < 2 ^ nn, p, a:ZH:0 <= p ∧ p <= nb:ZHeqb:b = a * 2 ^ (n - p)H0:0 <= b mod 2 ^ nH1:b mod 2 ^ n < 2 ^ nb mod 2 ^ n / 2 ^ (n - p) < 2 ^ nn, p, a:ZH:0 <= p ∧ p <= nb:ZHeqb:b = a * 2 ^ (n - p)H0:0 <= b mod 2 ^ nH1:b mod 2 ^ n < 2 ^ nb mod 2 ^ n < 2 ^ n * 2 ^ (n - p)generalize (pow2_pos (n - p)); nia. Qed.n, p, a:ZH:0 <= p ∧ p <= nb:ZHeqb:b = a * 2 ^ (n - p)H0:0 <= b mod 2 ^ nH1:b mod 2 ^ n < 2 ^ n2 ^ n <= 2 ^ n * 2 ^ (n - p)∀ p x : Z, 0 <= x → 0 <= x / 2 ^ p∀ p x : Z, 0 <= x → 0 <= x / 2 ^ pp, x:ZHle:0 <= xl:0 <= p0 <= x / 2 ^ pp, x:ZHle:0 <= xg:0 > p0 <= x / 2 ^ pp, x:ZHle:0 <= xg:0 > p0 <= x / 2 ^ pp, x:ZHle:0 <= xg:0 > p0 <= x / 0p, x:ZHle:0 <= xg:0 > p0 = 2 ^ pdestruct p;trivial;discriminate. Qed.p, x:ZHle:0 <= xg:0 > p0 = 2 ^ p∀ p x y : Z, 0 <= x ∧ x < y → x / 2 ^ p < y∀ p x y : Z, 0 <= x ∧ x < y → x / 2 ^ p < yp, x, y:ZH:0 <= x ∧ x < yl:0 <= px / 2 ^ p < yp, x, y:ZH:0 <= x ∧ x < yg:0 > px / 2 ^ p < yp, x, y:ZH:0 <= x ∧ x < yl:0 <= px < y * 2 ^ pp, x, y:ZH:0 <= x ∧ x < yg:0 > px / 2 ^ p < yp, x, y:ZH:0 <= x ∧ x < yl:0 <= py <= y * 2 ^ pp, x, y:ZH:0 <= x ∧ x < yg:0 > px / 2 ^ p < yp, x, y:ZH:0 <= x ∧ x < yl:0 <= p1 <= 2 ^ pp, x, y:ZH:0 <= x ∧ x < yg:0 > px / 2 ^ p < yp, x, y:ZH:0 <= x ∧ x < yg:0 > px / 2 ^ p < yp, x, y:ZH:0 <= x ∧ x < yg:0 > px / 0 < yp, x, y:ZH:0 <= x ∧ x < yg:0 > p0 = 2 ^ pdestruct p;trivial;discriminate. Qed.p, x, y:ZH:0 <= x ∧ x < yg:0 > p0 = 2 ^ pA, B, C:PropA → (B → C) → (A → B) → Ctauto. Qed.A, B, C:PropA → (B → C) → (A → B) → C∀ n p a : Z, 0 <= p ∧ p <= n → (a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p) = a mod 2 ^ p∀ n p a : Z, 0 <= p ∧ p <= n → (a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p) = a mod 2 ^ pn, p, a:ZH:0 <= p ∧ p <= n(a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p) = ((a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p)) mod 2 ^ nn, p, a:ZH:0 <= p ∧ p <= n0 <= (a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p) ∧ (a * 2 ^ (n - p)) mod 2 ^ n / 2 ^ (n - p) < 2 ^ nn, p, a:ZH:0 <= p ∧ p <= nw:Z0 <= w mod 2 ^ n / 2 ^ (n - p) ∧ w mod 2 ^ n / 2 ^ (n - p) < 2 ^ nn, p, a:ZH:0 <= p ∧ p <= nw, x:Z0 <= n - pn, p, a:ZH:0 <= p ∧ p <= nw, x:Zx > 0 → 0 <= w mod 2 ^ n / x ∧ w mod 2 ^ n / x < 2 ^ nn, p, a:ZH:0 <= p ∧ p <= nw, x:Zx > 0 → 0 <= w mod 2 ^ n / x ∧ w mod 2 ^ n / x < 2 ^ nn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 00 <= w mod 2 ^ n / x ∧ w mod 2 ^ n / x < 2 ^ nn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Z0 <= nn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zy > 0 → 0 <= w mod y / x ∧ w mod y / x < yn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zy > 0 → 0 <= w mod y / x ∧ w mod y / x < yn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zhy:y > 00 <= w mod y / x ∧ w mod y / x < yn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zhy:y > 0∀ z z0 : Z, (x ≠ 0 → (let (_, r) := Z.div_eucl w y in r) = x * z + z0 ∧ (0 <= z0 ∧ z0 < x ∨ x < z0 ∧ z0 <= 0)) → 0 <= z ∧ z < yn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zhy:y > 0q, r:Z(x ≠ 0 → (let (_, r0) := Z.div_eucl w y in r0) = x * q + r ∧ (0 <= r ∧ r < x ∨ x < r ∧ r <= 0)) → 0 <= q ∧ q < yn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zhy:y > 0q, r:Zx ≠ 0n, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zhy:y > 0q, r:Z(let (_, r0) := Z.div_eucl w y in r0) = x * q + r ∧ (0 <= r ∧ r < x ∨ x < r ∧ r <= 0) → 0 <= q ∧ q < yn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zhy:y > 0q, r:Z(let (_, r0) := Z.div_eucl w y in r0) = x * q + r ∧ (0 <= r ∧ r < x ∨ x < r ∧ r <= 0) → 0 <= q ∧ q < yn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zhy:y > 0q, r:Z∀ z z0 : Z, (y ≠ 0 → w = y * z + z0 ∧ (0 <= z0 ∧ z0 < y ∨ y < z0 ∧ z0 <= 0)) → z0 = x * q + r ∧ (0 <= r ∧ r < x ∨ x < r ∧ r <= 0) → 0 <= q ∧ q < yn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zhy:y > 0q, r, z, t:Z(y ≠ 0 → w = y * z + t ∧ (0 <= t ∧ t < y ∨ y < t ∧ t <= 0)) → t = x * q + r ∧ (0 <= r ∧ r < x ∨ x < r ∧ r <= 0) → 0 <= q ∧ q < yn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zhy:y > 0q, r, z, t:Zy ≠ 0n, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zhy:y > 0q, r, z, t:Zw = y * z + t ∧ (0 <= t ∧ t < y ∨ y < t ∧ t <= 0) → t = x * q + r ∧ (0 <= r ∧ r < x ∨ x < r ∧ r <= 0) → 0 <= q ∧ q < yn, p, a:ZH:0 <= p ∧ p <= nw, x:Zhx:x > 0y:Zhy:y > 0q, r, z, t:Zw = y * z + t ∧ (0 <= t ∧ t < y ∨ y < t ∧ t <= 0) → t = x * q + r ∧ (0 <= r ∧ r < x ∨ x < r ∧ r <= 0) → 0 <= q ∧ q < yn, p, a:ZH:0 <= p ∧ p <= nx:Zhx:x > 0y:Zhy:y > 0q, r, z, t:Zht:0 <= t ∧ t < yt = x * q + r ∧ (0 <= r ∧ r < x ∨ x < r ∧ r <= 0) → 0 <= q ∧ q < ynia. Qed.n, p, a:ZH:0 <= p ∧ p <= nx:Zhx:x > 0y:Zhy:y > 0q, r, z:Zht:0 <= x * q + r ∧ x * q + r < yhr:0 <= r ∧ r < x0 <= q ∧ q < yw, p:intφ (pos_mod p w) = φ (w) mod 2 ^ φ (p)w, p:intφ (pos_mod p w) = φ (w) mod 2 ^ φ (p)w, p:intφ (pos_mod_int p w) = φ (w) mod 2 ^ φ (p)w, p:intφ (if p ≤ Int63.digits then (w << (Int63.digits - p)) >> (Int63.digits - p) else w) = φ (w) mod 2 ^ φ (p)w, p:intW:0 <= φ (p) ∧ φ (p) < wBW':0 <= φ (Int63.digits) ∧ φ (Int63.digits) < wBW'':0 <= φ (w) ∧ φ (w) < wBφ (if p ≤ Int63.digits then (w << (Int63.digits - p)) >> (Int63.digits - p) else w) = φ (w) mod 2 ^ φ (p)w, p:intW:0 <= φ (p) ∧ φ (p) < wBW':0 <= φ (Int63.digits) ∧ φ (Int63.digits) < wBW'':0 <= φ (w) ∧ φ (w) < wBhle:φ (p) <= φ (Int63.digits)φ ((w << (Int63.digits - p)) >> (Int63.digits - p)) = φ (w) mod 2 ^ φ (p)w, p:intW:0 <= φ (p) ∧ φ (p) < wBW':0 <= φ (Int63.digits) ∧ φ (Int63.digits) < wBW'':0 <= φ (w) ∧ φ (w) < wBhle:¬ φ (p) <= φ (Int63.digits)φ (w) = φ (w) mod 2 ^ φ (p)w, p:intW:0 <= φ (p) ∧ φ (p) < wBW':0 <= φ (Int63.digits) ∧ φ (Int63.digits) < wBW'':0 <= φ (w) ∧ φ (w) < wBhle:¬ φ (p) <= φ (Int63.digits)φ (w) = φ (w) mod 2 ^ φ (p)w, p:intW:0 <= φ (p) ∧ φ (p) < wBW':0 <= φ (Int63.digits) ∧ φ (Int63.digits) < wBW'':0 <= φ (w) ∧ φ (w) < wBhle:¬ φ (p) <= φ (Int63.digits)0 <= φ (w) ∧ φ (w) < 2 ^ φ (p)change wB with (2 ^ [|Int63.digits|]) in *; auto with zarith.w, p:intW:0 <= φ (p) ∧ φ (p) < wBW':0 <= φ (Int63.digits) ∧ φ (Int63.digits) < wBW'':0 <= φ (w) ∧ φ (w) < wBhle:¬ φ (p) <= φ (Int63.digits)H:2 ^ φ (Int63.digits) < 2 ^ φ (p)0 <= φ (w) ∧ φ (w) < 2 ^ φ (p)w, p:intW:0 <= φ (p) ∧ φ (p) < wBW':0 <= φ (Int63.digits) ∧ φ (Int63.digits) < wBW'':0 <= φ (w) ∧ φ (w) < wBhle:φ (p) <= φ (Int63.digits)φ ((w << (Int63.digits - p)) >> (Int63.digits - p)) = φ (w) mod 2 ^ φ (p)w, p:intW:0 <= φ (p) ∧ φ (p) < wBW':0 <= φ (Int63.digits) ∧ φ (Int63.digits) < wBW'':0 <= φ (w) ∧ φ (w) < wBhle:φ (p) <= φ (Int63.digits)φ ((w << (Int63.digits - p)) >> (Int63.digits - p)) = (φ (w) * 2 ^ (φ (Int63.digits) - φ (p))) mod 2 ^ φ (Int63.digits) / 2 ^ (φ (Int63.digits) - φ (p))rewrite lsr_spec, lsl_spec; reflexivity. Qed.w, p:intW:0 <= φ (p) ∧ φ (p) < wBW':0 <= φ (Int63.digits) ∧ φ (Int63.digits) < wBW'':0 <= φ (w) ∧ φ (w) < wBhle:φ (p) <= φ (Int63.digits)φ ((w << (Int63.digits - p)) >> (Int63.digits - p)) = (φ (w) * 2 ^ φ (Int63.digits - p)) mod 2 ^ φ (Int63.digits) / 2 ^ φ (Int63.digits - p)
{2 Specification and proof}
Instance int_specs : ZnZ.Specs int_ops := { spec_to_Z := to_Z_bounded; spec_of_pos := positive_to_int_spec; spec_zdigits := refl_equal _; spec_more_than_1_digit:= refl_equal _; spec_0 := to_Z_0; spec_1 := to_Z_1; spec_m1 := refl_equal _; spec_compare := compare_spec; spec_eq0 := is_zero_spec_aux; spec_opp_c := oppc_spec; spec_opp := opp_spec; spec_opp_carry := oppcarry_spec; spec_succ_c := succc_spec; spec_add_c := addc_spec; spec_add_carry_c := addcarryc_spec; spec_succ := succ_spec; spec_add := add_spec; spec_add_carry := addcarry_spec; spec_pred_c := predc_spec; spec_sub_c := subc_spec; spec_sub_carry_c := subcarryc_spec; spec_pred := pred_spec; spec_sub := sub_spec; spec_sub_carry := subcarry_spec; spec_mul_c := mulc_WW_spec; spec_mul := mul_spec; spec_square_c := squarec_spec; spec_div21 := diveucl_21_spec_aux; spec_div_gt := fun a b _ => diveucl_spec_aux a b; spec_div := diveucl_spec_aux; spec_modulo_gt := fun a b _ _ => mod_spec a b; spec_modulo := fun a b _ => mod_spec a b; spec_gcd_gt := fun a b _ => gcd_spec a b; spec_gcd := gcd_spec; spec_head00 := head00_spec; spec_head0 := head0_spec; spec_tail00 := tail00_spec; spec_tail0 := tail0_spec; spec_add_mul_div := addmuldiv_spec; spec_pos_mod := pos_mod_spec; spec_is_even := is_even_spec; spec_sqrt2 := sqrt2_spec; spec_sqrt := sqrt_spec; spec_land := land_spec'; spec_lor := lor_spec'; spec_lxor := lxor_spec' }. Module Int63Cyclic <: CyclicType. Definition t := int. Definition ops := int_ops. Definition specs := int_specs. End Int63Cyclic.