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.
(* -*- coding: utf-8 -*- *) (************************************************************************) (* * 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 Export BinNums BinPos Pnat. Require Import BinNat Bool Equalities GenericMinMax OrdersFacts ZAxioms ZProperties. Require BinIntDef. (***********************************************************)
(***********************************************************)
Initial author: Pierre Crégut, CNET, Lannion, France
The type Z and its constructors Z0 and Zpos and Zneg
are now defined in BinNums.v
Local Open Scope Z_scope.
Every definitions and early properties about binary integers
are placed in a module Z for qualification purpose.
Module Z
<: ZAxiomsSig
<: UsualOrderedTypeFull
<: UsualDecidableTypeFull
<: TotalOrder.
Include BinIntDef.Z. Register add as num.Z.add. Register opp as num.Z.opp. Register succ as num.Z.succ. Register pred as num.Z.pred. Register sub as num.Z.sub. Register mul as num.Z.mul. Register of_nat as num.Z.of_nat.
When including property functors, only inline t eq zero one two
Set Inline Level 30.
Definition eq := @Logic.eq Z. Definition eq_equiv := @eq_equivalence Z. Definition lt x y := (x ?= y) = Lt. Definition gt x y := (x ?= y) = Gt. Definition le x y := (x ?= y) <> Gt. Definition ge x y := (x ?= y) <> Lt. Infix "<=" := le : Z_scope. Infix "<" := lt : Z_scope. Infix ">=" := ge : Z_scope. Infix ">" := gt : Z_scope. Notation "x <= y <= z" := (x <= y /\ y <= z) : Z_scope. Notation "x <= y < z" := (x <= y /\ y < z) : Z_scope. Notation "x < y < z" := (x < y /\ y < z) : Z_scope. Notation "x < y <= z" := (x < y /\ y <= z) : Z_scope. Definition divide x y := exists z, y = z*x. Notation "( x | y )" := (divide x y) (at level 0). Definition Even a := exists b, a = 2*b. Definition Odd a := exists b, a = 2*b+1. Register le as num.Z.le. Register lt as num.Z.lt. Register ge as num.Z.ge. Register gt as num.Z.gt.
x, y:Z{x = y} + {x <> y}decide equality; apply Pos.eq_dec. Defined.x, y:Z{x = y} + {x <> y}
Local Obligation Tactic := simpl_relation. Definition succ_wd : Proper (eq==>eq) succ := _. Definition pred_wd : Proper (eq==>eq) pred := _. Definition opp_wd : Proper (eq==>eq) opp := _. Definition add_wd : Proper (eq==>eq==>eq) add := _. Definition sub_wd : Proper (eq==>eq==>eq) sub := _. Definition mul_wd : Proper (eq==>eq==>eq) mul := _. Definition lt_wd : Proper (eq==>eq==>iff) lt := _. Definition div_wd : Proper (eq==>eq==>eq) div := _. Definition mod_wd : Proper (eq==>eq==>eq) modulo := _. Definition quot_wd : Proper (eq==>eq==>eq) quot := _. Definition rem_wd : Proper (eq==>eq==>eq) rem := _. Definition pow_wd : Proper (eq==>eq==>eq) pow := _. Definition testbit_wd : Proper (eq==>eq==>Logic.eq) testbit := _.
pos_sub can be written in term of positive comparison
and subtraction (cf. earlier definition of addition of Z)
p, q:positivepos_sub p q = match (p ?= q)%positive with | Eq => 0 | Lt => neg (q - p) | Gt => pos (p - q) endp, q:positivepos_sub p q = match (p ?= q)%positive with | Eq => 0 | Lt => neg (q - p) | Gt => pos (p - q) endinduction p; destruct q; simpl; trivial; rewrite ?Pos.compare_xI_xI, ?Pos.compare_xO_xI, ?Pos.compare_xI_xO, ?Pos.compare_xO_xO, IHp; simpl; case Pos.compare_spec; intros; simpl; trivial; (now rewrite Pos.sub_xI_xI) || (now rewrite Pos.sub_xO_xO) || (now rewrite Pos.sub_xO_xI) || (now rewrite Pos.sub_xI_xO) || subst; unfold Pos.sub; simpl; now rewrite Pos.sub_mask_diag. Qed.p:positiveforall q : positive, pos_sub p q = match (p ?= q)%positive with | Eq => 0 | Lt => neg (q - p) | Gt => pos (p - q) endp, q:positivematch pos_sub p q with | 0 => p = q | pos k => p = (q + k)%positive | neg k => q = (p + k)%positive endp, q:positivematch pos_sub p q with | 0 => p = q | pos k => p = (q + k)%positive | neg k => q = (p + k)%positive endcase Pos.compare_spec; auto; intros; now rewrite Pos.add_comm, Pos.sub_add. Qed.p, q:positivematch match (p ?= q)%positive with | Eq => 0 | Lt => neg (q - p) | Gt => pos (p - q) end with | 0 => p = q | pos k => p = (q + k)%positive | neg k => q = (p + k)%positive end
Particular cases of the previous result
p:positivepos_sub p p = 0now rewrite pos_sub_spec, Pos.compare_refl. Qed.p:positivepos_sub p p = 0p, q:positive(p < q)%positive -> pos_sub p q = neg (q - p)p, q:positive(p < q)%positive -> pos_sub p q = neg (q - p)now rewrite pos_sub_spec, H. Qed.p, q:positiveH:(p < q)%positivepos_sub p q = neg (q - p)p, q:positive(q < p)%positive -> pos_sub p q = pos (p - q)p, q:positive(q < p)%positive -> pos_sub p q = pos (p - q)now rewrite pos_sub_spec, Pos.compare_antisym, H. Qed.p, q:positiveH:(q < p)%positivepos_sub p q = pos (p - q)
The opposite of pos_sub is pos_sub with reversed arguments
p, q:positive- pos_sub p q = pos_sub q prevert q; induction p; destruct q; simpl; trivial; rewrite <- IHp; now destruct pos_sub. Qed.p, q:positive- pos_sub p q = pos_sub q p
In the following module, we group results that are needed now
to prove specifications of operations, but will also be provided
later by the generic functor of properties.
Module Import Private_BootStrap.
n:Zn + 0 = nnow destruct n. Qed.n:Zn + 0 = nn:Zn * 0 = 0now destruct n. Qed.n:Zn * 0 = 0n:Z1 * n = nnow destruct n. Qed.n:Z1 * n = n
n, m:Zn + m = m + ndestruct n, m; simpl; trivial; now rewrite Pos.add_comm. Qed.n, m:Zn + m = m + n
n, m:Z- (n + m) = - n + - mdestruct n, m; simpl; trivial using pos_sub_opp. Qed.n, m:Z- (n + m) = - n + - m
n, m:Z- n = - m -> n = mdestruct n, m; simpl; intros H; destr_eq H; now f_equal. Qed.n, m:Z- n = - m -> n = m
p, q, r:positivepos_sub (p + q) r = pos p + pos_sub q rp, q, r:positivepos_sub (p + q) r = pos p + pos_sub q rp, q, r:positivepos_sub (p + q) r = match pos_sub q r with | 0 => pos p | pos y' => pos (p + y') | neg y' => pos_sub p y' endp, q, r:positivematch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = match match (q ?= r)%positive with | Eq => 0 | Lt => neg (r - q) | Gt => pos (q - r) end with | 0 => pos p | pos y' => pos (p + y') | neg y' => pos_sub p y' endp, q, r:positiveE0:q = rmatch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = pos pp, q, r:positiveE0:(q < r)%positivematch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = pos_sub p (r - q)p, q, r:positiveE0:(r < q)%positivematch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = pos (p + (q - r))p, q, r:positiveE0:q = rmatch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = pos pp, r:positivematch (p + r ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + r)) | Gt => pos (p + r - r) end = pos pp, r:positiveH:(r < r + p)%positivematch (p + r ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + r)) | Gt => pos (p + r - r) end = pos pp, r:positiveH:(r < p + r)%positivematch (p + r ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + r)) | Gt => pos (p + r - r) end = pos pnow rewrite H, Pos.add_sub.p, r:positiveH:(p + r > r)%positivematch (p + r ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + r)) | Gt => pos (p + r - r) end = pos pp, q, r:positiveE0:(q < r)%positivematch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = pos_sub p (r - q)p, q, r:positiveE0:(q < r)%positivematch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = match (p ?= r - q)%positive with | Eq => 0 | Lt => neg (r - q - p) | Gt => pos (p - (r - q)) endp, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positivematch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = match (p ?= r - q)%positive with | Eq => 0 | Lt => neg (r - q - p) | Gt => pos (p - (r - q)) endp, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positivematch (p + q ?= r - q + q)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = match (p ?= r - q)%positive with | Eq => 0 | Lt => neg (r - q - p) | Gt => pos (p - (r - q)) endp, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positivematch (p ?= r - q)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = match (p ?= r - q)%positive with | Eq => 0 | Lt => neg (r - q - p) | Gt => pos (p - (r - q)) endp, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positiveE1:(p < r - q)%positive(r - (p + q))%positive = (r - q - p)%positivep, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positiveE1:(r - q < p)%positive(p + q - r)%positive = (p - (r - q))%positivep, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positiveE1:(p < r - q)%positive(r - (q + p))%positive = (r - q - p)%positivep, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positiveE1:(r - q < p)%positive(p + q - r)%positive = (p - (r - q))%positivep, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positiveE1:(p < r - q)%positive(q + p < r)%positivep, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positiveE1:(r - q < p)%positive(p + q - r)%positive = (p - (r - q))%positivep, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positiveE1:(p < r - q)%positive(p + q < r - q + q)%positivep, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positiveE1:(r - q < p)%positive(p + q - r)%positive = (p - (r - q))%positivep, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positiveE1:(r - q < p)%positive(p + q - r)%positive = (p - (r - q))%positiveapply Pos.sub_sub_distr; trivial.p, q, r:positiveE0:(q < r)%positiveHr:r = (r - q + q)%positiveE1:(r - q < p)%positive(p - (r - q))%positive = (p + q - r)%positivep, q, r:positiveE0:(r < q)%positivematch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = pos (p + (q - r))p, q, r:positiveE0:(r < q)%positive(r < p + q)%positivep, q, r:positiveE0:(r < q)%positiveLT:(r < p + q)%positivematch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = pos (p + (q - r))p, q, r:positiveE0:(r < q)%positive(r < p + q)%positivep, q, r:positiveE0:(r < q)%positive(q < p + q)%positiveapply Pos.lt_add_r.p, q, r:positiveE0:(r < q)%positive(q < q + p)%positivep, q, r:positiveE0:(r < q)%positiveLT:(r < p + q)%positivematch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = pos (p + (q - r))p, q, r:positiveE0:(r < q)%positiveLT:(p + q > r)%positivematch (p + q ?= r)%positive with | Eq => 0 | Lt => neg (r - (p + q)) | Gt => pos (p + q - r) end = pos (p + (q - r))p, q, r:positiveE0:(r < q)%positiveLT:(p + q > r)%positivepos (p + q - r) = pos (p + (q - r))p, q, r:positiveE0:(r < q)%positiveLT:(p + q > r)%positive(p + q - r)%positive = (p + (q - r))%positivenow apply Pos.add_sub_assoc. Qed. Local Arguments add !x !y.p, q, r:positiveE0:(r < q)%positiveLT:(p + q > r)%positive(p + (q - r))%positive = (p + q - r)%positivep:positiven, m:Zpos p + (n + m) = pos p + n + mp:positiven, m:Zpos p + (n + m) = pos p + n + mp, n, m:positivepos (p + (n + m)) = pos (p + n + m)p, n, m:positivepos p + pos_sub n m = pos_sub (p + n) mp, n:positivepos_sub p n = pos_sub p n + 0p, n, m:positivepos p + pos_sub m n = pos_sub p n + pos mp, n, m:positivepos_sub p (n + m) = pos_sub p n + neg mnow rewrite Pos.add_assoc.p, n, m:positivepos (p + (n + m)) = pos (p + n + m)p, n, m:positivepos p + pos_sub n m = pos_sub (p + n) mapply pos_sub_add.p, n, m:positivepos_sub (p + n) m = pos p + pos_sub n mp, n:positivepos_sub p n = pos_sub p n + 0apply add_0_r.p, n:positivepos_sub p n + 0 = pos_sub p nnow rewrite <- pos_sub_add, add_comm, <- pos_sub_add, Pos.add_comm.p, n, m:positivepos p + pos_sub m n = pos_sub p n + pos mp, n, m:positivepos_sub p (n + m) = pos_sub p n + neg mp, n, m:positive- pos_sub p (n + m) = - (pos_sub p n + neg m)p, n, m:positivepos_sub (n + m) p = pos_sub n p + - neg mapply pos_sub_add. Qed.p, n, m:positivepos_sub (m + n) p = - neg m + pos_sub n pn, m, p:Zn + (m + p) = n + m + pn, m, p:Zn + (m + p) = n + m + pm, p:Z0 + (m + p) = 0 + m + pp0:positivem, p:Zpos p0 + (m + p) = pos p0 + m + pp0:positivem, p:Zneg p0 + (m + p) = neg p0 + m + ptrivial.m, p:Z0 + (m + p) = 0 + m + papply add_assoc_pos.p0:positivem, p:Zpos p0 + (m + p) = pos p0 + m + pp0:positivem, p:Zneg p0 + (m + p) = neg p0 + m + pp0:positivem, p:Z- (neg p0 + (m + p)) = - (neg p0 + m + p)p0:positivem, p:Z- neg p0 + (- m + - p) = - neg p0 + - m + - papply add_assoc_pos. Qed.p0:positivem, p:Zpos p0 + (- m + - p) = pos p0 + - m + - p
n:Zn + - n = 0destruct n; simpl; trivial; now rewrite pos_sub_diag. Qed.n:Zn + - n = 0
n, m:Zn * - m = - (n * m)now destruct n, m. Qed.n, m:Zn * - m = - (n * m)
p:positiven, m:Z(n + m) * pos p = n * pos p + m * pos pp:positiven, m:Z(n + m) * pos p = n * pos p + m * pos pp, n, m:positivepos ((n + m) * p) = pos (n * p + m * p)p, n, m:positivepos_sub n m * pos p = pos_sub (n * p) (m * p)p, n, m:positivepos_sub m n * pos p = pos_sub (m * p) (n * p)p, n, m:positiveneg ((n + m) * p) = neg (n * p + m * p)now rewrite Pos.mul_add_distr_r.p, n, m:positivepos ((n + m) * p) = pos (n * p + m * p)rewrite ?pos_sub_spec, ?Pos.mul_compare_mono_r; case Pos.compare_spec; simpl; trivial; intros; now rewrite Pos.mul_sub_distr_r.p, n, m:positivepos_sub n m * pos p = pos_sub (n * p) (m * p)rewrite ?pos_sub_spec, ?Pos.mul_compare_mono_r; case Pos.compare_spec; simpl; trivial; intros; now rewrite Pos.mul_sub_distr_r.p, n, m:positivepos_sub m n * pos p = pos_sub (m * p) (n * p)now rewrite Pos.mul_add_distr_r. Qed.p, n, m:positiveneg ((n + m) * p) = neg (n * p + m * p)n, m, p:Z(n + m) * p = n * p + m * pn, m, p:Z(n + m) * p = n * p + m * pn, m:Z(n + m) * 0 = n * 0 + m * 0n, m:Zp:positive(n + m) * pos p = n * pos p + m * pos pn, m:Zp:positive(n + m) * neg p = n * neg p + m * neg pnow rewrite !mul_0_r.n, m:Z(n + m) * 0 = n * 0 + m * 0apply mul_add_distr_pos.n, m:Zp:positive(n + m) * pos p = n * pos p + m * pos pn, m:Zp:positive(n + m) * neg p = n * neg p + m * neg pn, m:Zp:positive- ((n + m) * neg p) = - (n * neg p + m * neg p)apply mul_add_distr_pos. Qed. End Private_BootStrap.n, m:Zp:positive(n + m) * - neg p = n * - neg p + m * - neg p
1 = succ 0reflexivity. Qed.1 = succ 02 = succ 1reflexivity. Qed.2 = succ 1
n:Z0 + n = nnow destruct n. Qed.n:Z0 + n = nn, m:Zsucc n + m = succ (n + m)n, m:Zsucc n + m = succ (n + m)now rewrite 2 (add_comm _ 1), add_assoc. Qed.n, m:Zn + 1 + m = n + m + 1
- 0 = 0reflexivity. Qed.- 0 = 0n:Z- succ n = pred (- n)n:Z- succ n = pred (- n)apply opp_add_distr. Qed.n:Z- (n + 1) = - n + -1
Local Arguments pos_sub : simpl nomatch.n:Zsucc (pred n) = nn:Zsucc (pred n) = nnow rewrite <- add_assoc, add_opp_diag_r, add_0_r. Qed.n:Zn + -1 + 1 = nn:Zpred (succ n) = nn:Zpred (succ n) = nnow rewrite <- add_assoc, add_opp_diag_r, add_0_r. Qed.n:Zn + 1 + -1 = n
n:Zn - 0 = napply add_0_r. Qed.n:Zn - 0 = nn, m:Zn - succ m = pred (n - m)n, m:Zn - succ m = pred (n - m)now rewrite opp_add_distr, add_assoc. Qed.n, m:Zn + - (m + 1) = n + - m + -1
n:Z0 * n = 0reflexivity. Qed.n:Z0 * n = 0n, m:Zsucc n * m = n * m + mn, m:Zsucc n * m = n * m + mnow rewrite mul_add_distr_r, mul_1_l. Qed.n, m:Z(n + 1) * m = n * m + m
n, m:Z(n =? m) = true <-> n = mdestruct n, m; simpl; try (now split); rewrite Pos.eqb_eq; split; (now injection 1) || (intros; now f_equal). Qed.n, m:Z(n =? m) = true <-> n = mn, m:Z(n <? m) = true <-> n < mn, m:Z(n <? m) = true <-> n < mdestruct compare; easy'. Qed.n, m:Zmatch n ?= m with | Lt => true | _ => false end = true <-> (n ?= m) = Ltn, m:Z(n <=? m) = true <-> n <= mn, m:Z(n <=? m) = true <-> n <= mdestruct compare; easy'. Qed.n, m:Zmatch n ?= m with | Gt => false | _ => true end = true <-> (n ?= m) <> Gtn, m:Z(n ?= m) = Eq <-> n = mdestruct n, m; simpl; rewrite ?CompOpp_iff, ?Pos.compare_eq_iff; split; congruence. Qed.n, m:Z(n ?= m) = Eq <-> n = mn, m:Z(n ?= m) = (n - m ?= 0)destruct n as [|n|n], m as [|m|m]; simpl; trivial; rewrite <- ? Pos.compare_antisym, ?pos_sub_spec; case Pos.compare_spec; trivial. Qed.n, m:Z(n ?= m) = (n - m ?= 0)n, m:Z(m ?= n) = CompOpp (n ?= m)destruct n, m; simpl; trivial; now rewrite <- ?Pos.compare_antisym. Qed.n, m:Z(m ?= n) = CompOpp (n ?= m)n, m:Z(n ?= m) = Lt <-> n < mreflexivity. Qed.n, m:Z(n ?= m) = Lt <-> n < mn, m:Z(n ?= m) <> Gt <-> n <= mreflexivity. Qed.n, m:Z(n ?= m) <> Gt <-> n <= m
Some more advanced properties of comparison and orders,
including compare_spec and lt_irrefl and lt_eq_cases.
Include BoolOrderFacts.
Remaining specification of lt and le
n, m:Zn < succ m <-> n <= mn, m:Zn < succ m <-> n <= mn, m:Z(n ?= succ m) = Lt <-> (n ?= m) <> Gtn, m:Z(pred (n - m) ?= 0) = Lt <-> (n ?= m) <> Gtdestruct (n-m) as [|[ | | ]|]; easy'. Qed.n, m:Z(pred (n - m) ?= 0) = Lt <-> (n - m ?= 0) <> Gt
n, m:Zm <= n -> max n m = nn, m:Zm <= n -> max n m = nn, m:Z(m ?= n) <> Gt -> match n ?= m with | Lt => m | _ => n end = ncase compare; intuition. Qed.n, m:ZCompOpp (n ?= m) <> Gt -> match n ?= m with | Lt => m | _ => n end = nn, m:Zn <= m -> max n m = mn, m:Zn <= m -> max n m = mcase compare_spec; intuition. Qed.n, m:Z(n ?= m) <> Gt -> match n ?= m with | Lt => m | _ => n end = mn, m:Zn <= m -> min n m = nn, m:Zn <= m -> min n m = ncase compare_spec; intuition. Qed.n, m:Z(n ?= m) <> Gt -> match n ?= m with | Gt => m | _ => n end = nn, m:Zm <= n -> min n m = mn, m:Zm <= n -> min n m = mn, m:Z(m ?= n) <> Gt -> match n ?= m with | Gt => m | _ => n end = mcase compare_spec; intuition. Qed.n, m:ZCompOpp (n ?= m) <> Gt -> match n ?= m with | Gt => m | _ => n end = m
P:Z -> PropP 0 -> (forall x : Z, P x -> P (succ x)) -> (forall x : Z, P x -> P (pred x)) -> forall z : Z, P zP:Z -> PropP 0 -> (forall x : Z, P x -> P (succ x)) -> (forall x : Z, P x -> P (pred x)) -> forall z : Z, P zP:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)P 0P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveP (pos p)P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveP (neg p)P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveP (pos p)P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveP (neg p)P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)P 1P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveIHp:P (pos p)P (pos (Pos.succ p))P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveP (neg p)P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveIHp:P (pos p)P (pos (Pos.succ p))P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveP (neg p)P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveIHp:P (pos p)P (pos (p + 1))P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveP (neg p)P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveP (neg p)P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)P (-1)P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveIHp:P (neg p)P (neg (Pos.succ p))P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveIHp:P (neg p)P (neg (Pos.succ p))now apply (Hp (neg p)). Qed.P:Z -> PropH0:P 0Hs:forall x : Z, P x -> P (succ x)Hp:forall x : Z, P x -> P (pred x)p:positiveIHp:P (neg p)P (neg (p + 1))P:Z -> PropProper (eq ==> iff) P -> P 0 -> (forall x : Z, P x <-> P (succ x)) -> forall z : Z, P zP:Z -> PropProper (eq ==> iff) P -> P 0 -> (forall x : Z, P x <-> P (succ x)) -> forall z : Z, P zP:Z -> PropH0:P 0Hs:forall x : Z, P x <-> P (succ x)forall z : Z, P zP:Z -> PropH0:P 0Hs:forall x : Z, P x <-> P (succ x)P 0P:Z -> PropH0:P 0Hs:forall x : Z, P x <-> P (succ x)z:ZIHz:P zP (succ z)P:Z -> PropH0:P 0Hs:forall x : Z, P x <-> P (succ x)z:ZIHz:P zP (pred z)P:Z -> PropH0:P 0Hs:forall x : Z, P x <-> P (succ x)z:ZIHz:P zP (succ z)P:Z -> PropH0:P 0Hs:forall x : Z, P x <-> P (succ x)z:ZIHz:P zP (pred z)P:Z -> PropH0:P 0Hs:forall x : Z, P x <-> P (succ x)z:ZIHz:P zP (pred z)now rewrite succ_pred. Qed.P:Z -> PropH0:P 0Hs:forall x : Z, P x <-> P (succ x)z:ZIHz:P zP (succ (pred z))
We can now derive all properties of basic functions and orders,
and use these properties for proving the specs of more advanced
functions.
Include ZBasicProp <+ UsualMinMaxLogicalProperties <+ UsualMinMaxDecProperties. Register eq_decidable as num.Z.eq_decidable. Register le_decidable as num.Z.le_decidable. Register lt_decidable as num.Z.lt_decidable.
n:Z0 <= n -> abs n = nn:Z0 <= n -> abs n = nnow destruct 1. Qed.p:positive0 <= neg p -> abs (neg p) = neg pn:Zn <= 0 -> abs n = - nn:Zn <= 0 -> abs n = - nnow destruct 1. Qed.p:positivepos p <= 0 -> abs (pos p) = - pos p
n:Zn = 0 -> sgn n = 0n:Zn = 0 -> sgn n = 0now subst. Qed.n:ZH:n = 0sgn n = 0n:Z0 < n -> sgn n = 1now destruct n. Qed.n:Z0 < n -> sgn n = 1n:Zn < 0 -> sgn n = -1now destruct n. Qed.n:Zn < 0 -> sgn n = -1
n:Zn ^ 0 = 1reflexivity. Qed.n:Zn ^ 0 = 1n, m:Z0 <= m -> n ^ succ m = n * n ^ mn, m:Z0 <= m -> n ^ succ m = n * n ^ mn:Zm:positivepow_pos n (m + 1) = n * pow_pos n mnow rewrite Pos.add_comm, Pos.iter_add. Qed.n:Zm:positivePos.iter (mul n) 1 (m + 1) = n * Pos.iter (mul n) 1 mn, m:Zm < 0 -> n ^ m = 0now destruct m. Qed.n, m:Zm < 0 -> n ^ m = 0
For folding back a pow_pos into a pow
n:Zp:positivepow_pos n p = n ^ pos preflexivity. Qed.n:Zp:positivepow_pos n p = n ^ pos p
n:Zsquare n = n * ndestruct n; trivial; simpl; f_equal; apply Pos.square_spec. Qed.n:Zsquare n = n * n
n:Z0 <= n -> let (s, r) := sqrtrem n in n = s * s + r /\ 0 <= r <= 2 * sn:Z0 <= n -> let (s, r) := sqrtrem n in n = s * s + r /\ 0 <= r <= 2 * s0 <= 0 -> let (s, r) := sqrtrem 0 in 0 = s * s + r /\ 0 <= r <= 2 * sp:positive0 <= pos p -> let (s, r) := sqrtrem (pos p) in pos p = s * s + r /\ 0 <= r <= 2 * sp:positive0 <= neg p -> let (s, r) := sqrtrem (neg p) in neg p = s * s + r /\ 0 <= r <= 2 * sp:positive0 <= pos p -> let (s, r) := sqrtrem (pos p) in pos p = s * s + r /\ 0 <= r <= 2 * sp:positive0 <= neg p -> let (s, r) := sqrtrem (neg p) in neg p = s * s + r /\ 0 <= r <= 2 * sp:positivePos.SqrtSpec (Pos.sqrtrem p) p -> 0 <= pos p -> let (s, r) := sqrtrem (pos p) in pos p = s * s + r /\ 0 <= r <= 2 * sp:positive0 <= neg p -> let (s, r) := sqrtrem (neg p) in neg p = s * s + r /\ 0 <= r <= 2 * sp:positivePos.SqrtSpec (Pos.sqrtrem p) p -> 0 <= pos p -> let (s, r) := let (s, m) := Pos.sqrtrem p in match m with | Pos.IsPos r => (pos s, pos r) | _ => (pos s, 0) end in pos p = s * s + r /\ 0 <= r <= match s with | 0 => 0 | pos y' => pos y'~0 | neg y' => neg y'~0 endp:positive0 <= neg p -> let (s, r) := sqrtrem (neg p) in neg p = s * s + r /\ 0 <= r <= 2 * snow destruct 1. Qed.p:positive0 <= neg p -> let (s, r) := sqrtrem (neg p) in neg p = s * s + r /\ 0 <= r <= 2 * sn:Z0 <= n -> let s := sqrt n in s * s <= n < succ s * succ sn:Z0 <= n -> let s := sqrt n in s * s <= n < succ s * succ s0 <= 0 -> let s := sqrt 0 in s * s <= 0 < succ s * succ sp:positive0 <= pos p -> let s := sqrt (pos p) in s * s <= pos p < succ s * succ sp:positive0 <= neg p -> let s := sqrt (neg p) in s * s <= neg p < succ s * succ sp:positive0 <= pos p -> let s := sqrt (pos p) in s * s <= pos p < succ s * succ sp:positive0 <= neg p -> let s := sqrt (neg p) in s * s <= neg p < succ s * succ sp:positive0 <= pos p -> pos (Pos.sqrt p) * pos (Pos.sqrt p) <= pos p < succ (pos (Pos.sqrt p)) * succ (pos (Pos.sqrt p))p:positive0 <= neg p -> let s := sqrt (neg p) in s * s <= neg p < succ s * succ sp:positivepos (Pos.sqrt p) * pos (Pos.sqrt p) <= pos p < succ (pos (Pos.sqrt p)) * succ (pos (Pos.sqrt p))p:positive0 <= neg p -> let s := sqrt (neg p) in s * s <= neg p < succ s * succ sp:positivepos (Pos.sqrt p) * pos (Pos.sqrt p) <= pos p < pos (Pos.sqrt p + 1) * pos (Pos.sqrt p + 1)p:positive0 <= neg p -> let s := sqrt (neg p) in s * s <= neg p < succ s * succ sp:positivepos (Pos.sqrt p) * pos (Pos.sqrt p) <= pos p < pos (Pos.succ (Pos.sqrt p)) * pos (Pos.succ (Pos.sqrt p))p:positive0 <= neg p -> let s := sqrt (neg p) in s * s <= neg p < succ s * succ snow destruct 1. Qed.p:positive0 <= neg p -> let s := sqrt (neg p) in s * s <= neg p < succ s * succ sn:Zn < 0 -> sqrt n = 0now destruct n. Qed.n:Zn < 0 -> sqrt n = 0n:Zfst (sqrtrem n) = sqrt nn:Zfst (sqrtrem n) = sqrt np:positivefst (sqrtrem (pos p)) = sqrt (pos p)p:positivefst (let (s, m) := Pos.sqrtrem p in match m with | Pos.IsPos r => (pos s, pos r) | _ => (pos s, 0) end) = pos (fst (Pos.sqrtrem p))now destruct r. Qed.p, s:positiver:Pos.maskfst match r with | Pos.IsPos r0 => (pos s, pos r0) | _ => (pos s, 0) end = pos (fst (s, r))
n:Z0 < n -> 2 ^ log2 n <= n < 2 ^ succ (log2 n)n:Z0 < n -> 2 ^ log2 n <= n < 2 ^ succ (log2 n)n:Zforall p q : positive, pos (p ^ q) = pos p ^ pos qn:ZPow:forall p q : positive, pos (p ^ q) = pos p ^ pos q0 < n -> 2 ^ log2 n <= n < 2 ^ succ (log2 n)n:Zforall p q : positive, pos (p ^ q) = pos p ^ pos qnow apply Pos.iter_swap_gen.n:Zp, q:positivepos (p ^ q) = pos p ^ pos qn:ZPow:forall p q : positive, pos (p ^ q) = pos p ^ pos q0 < n -> 2 ^ log2 n <= n < 2 ^ succ (log2 n)p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~1pos (2 ^ Pos.size p) <= pos p~1p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~1pos p~1 < pos (2 ^ Pos.succ (Pos.size p))p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~0pos (2 ^ Pos.size p) <= pos p~0p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~0pos p~0 < pos (2 ^ Pos.succ (Pos.size p))p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~1(2 ^ Pos.size p <= Pos.succ p~0)%positivep:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~1pos p~1 < pos (2 ^ Pos.succ (Pos.size p))p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~0pos (2 ^ Pos.size p) <= pos p~0p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~0pos p~0 < pos (2 ^ Pos.succ (Pos.size p))p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~1pos p~1 < pos (2 ^ Pos.succ (Pos.size p))p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~0pos (2 ^ Pos.size p) <= pos p~0p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~0pos p~0 < pos (2 ^ Pos.succ (Pos.size p))p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~0pos (2 ^ Pos.size p) <= pos p~0p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~0pos p~0 < pos (2 ^ Pos.succ (Pos.size p))apply Pos.size_gt. Qed.p:positivePow:forall p0 q : positive, pos (p0 ^ q) = pos p0 ^ pos qHn:0 < pos p~0pos p~0 < pos (2 ^ Pos.succ (Pos.size p))n:Zn <= 0 -> log2 n = 0destruct n as [|p|p]; trivial; now destruct 1. Qed.n:Zn <= 0 -> log2 n = 0
Specification of parity functions
n:Zeven n = true <-> Even nn:Zeven n = true <-> Even nn:Zeven n = true -> Even nn:ZEven n -> even n = truen:ZH:even n = truen = 2 * div2 nn:ZEven n -> even n = truen:ZEven n -> even n = truenow destruct m. Qed.m:Zeven (2 * m) = truen:Zodd n = true <-> Odd nn:Zodd n = true <-> Odd nn:Zodd n = true -> Odd nn:ZOdd n -> odd n = truen:ZH:odd n = truen = 2 * div2 n + 1n:ZOdd n -> odd n = truep:positiveH:odd (neg p~1) = trueneg p~1 = neg (Pos.pred_double (Pos.succ p))n:ZOdd n -> odd n = truen:ZOdd n -> odd n = truenow destruct m as [|[ | | ]|[ | | ]]. Qed.m:Zodd (2 * m + 1) = true
n:Zdouble n = 2 * nreflexivity. Qed.n:Zdouble n = 2 * nn:Zsucc_double n = 2 * n + 1now destruct n. Qed.n:Zsucc_double n = 2 * n + 1n:Zpred_double n = 2 * n - 1now destruct n. Qed.n:Zpred_double n = 2 * n - 1
a:positiveb:Z0 < b -> let (q, r) := pos_div_eucl a b in pos a = q * b + ra:positiveb:Z0 < b -> let (q, r) := pos_div_eucl a b in pos a = q * b + ra:positiveb:ZHb:0 < blet (q, r) := pos_div_eucl a b in pos a = q * b + ra:positiveb:ZHb:0 < bIHa:let (q, r) := pos_div_eucl a b in pos a = q * b + rlet (q, r) := let (q, r) := pos_div_eucl a b in if 2 * r + 1 <? b then (2 * q, 2 * r + 1) else (2 * q + 1, 2 * r + 1 - b) in pos a~1 = q * b + ra:positiveb:ZHb:0 < bIHa:let (q, r) := pos_div_eucl a b in pos a = q * b + rlet (q, r) := let (q, r) := pos_div_eucl a b in if 2 * r <? b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - b) in pos a~0 = q * b + rb:ZHb:0 < blet (q, r) := if 2 <=? b then (0, 1) else (1, 0) in 1 = q * b + ra:positiveb:ZHb:0 < bIHa:let (q, r) := pos_div_eucl a b in pos a = q * b + rlet (q, r) := let (q, r) := pos_div_eucl a b in if 2 * r + 1 <? b then (2 * q, 2 * r + 1) else (2 * q + 1, 2 * r + 1 - b) in pos a~1 = q * b + ra:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + rlet (q0, r0) := if 2 * r + 1 <? b then (2 * q, 2 * r + 1) else (2 * q + 1, 2 * r + 1 - b) in pos a~1 = q0 * b + r0a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + rlet (q0, r0) := if 2 * r + 1 <? b then (2 * q, 2 * r + 1) else (2 * q + 1, 2 * r + 1 - b) in 2 * pos a + 1 = q0 * b + r0a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + rlet (q0, r0) := if 2 * r + 1 <? b then (2 * q, 2 * r + 1) else (2 * q + 1, 2 * r + 1 - b) in 2 * q * b + 2 * r + 1 = q0 * b + r0a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * q * b + 2 * r + 1 = 2 * q * b + (2 * r + 1)a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * q * b + 2 * r + 1 = (2 * q + 1) * b + (2 * r + 1 - b)a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * q * b + 2 * r + 1 = (2 * q + 1) * b + (2 * r + 1 - b)a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * q * b + (2 * r + 1) = 2 * q * b + (b + (2 * r + 1 - b))a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * r + 1 = b + (2 * r + 1 - b)now rewrite (add_comm _ (-b)), add_assoc, add_opp_diag_r.a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * r + 1 = b + (2 * r + 1 + - b)a:positiveb:ZHb:0 < bIHa:let (q, r) := pos_div_eucl a b in pos a = q * b + rlet (q, r) := let (q, r) := pos_div_eucl a b in if 2 * r <? b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - b) in pos a~0 = q * b + ra:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + rlet (q0, r0) := if 2 * r <? b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - b) in pos a~0 = q0 * b + r0a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + rlet (q0, r0) := if 2 * r <? b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - b) in 2 * pos a = q0 * b + r0a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + rlet (q0, r0) := if 2 * r <? b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - b) in 2 * q * b + 2 * r = q0 * b + r0a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * q * b + 2 * r = 2 * q * b + 2 * ra:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * q * b + 2 * r = (2 * q + 1) * b + (2 * r - b)a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * q * b + 2 * r = (2 * q + 1) * b + (2 * r - b)a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * q * b + 2 * r = 2 * q * b + (b + (2 * r - b))a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * r = b + (2 * r - b)now rewrite (add_comm _ (-b)), add_assoc, add_opp_diag_r.a:positiveb:ZHb:0 < bq, r:ZIHa:pos a = q * b + r2 * r = b + (2 * r + - b)b:ZHb:0 < blet (q, r) := if 2 <=? b then (0, 1) else (1, 0) in 1 = q * b + rb:ZHb:0 < bb < 2 -> 1 = 1 * b + 0b:ZHb:0 < bHb':b < 21 = 1 * b + 0b:positiveHb':pos b < 21 = 1 * pos b + 0b:positiveHb':pos b < 21%positive = bb:positiveHb':pos b < 2(1 <= b)%positiveb:positiveHb':pos b < 2(b <= 1)%positivenow apply Pos.lt_succ_r. Qed.b:positiveHb':pos b < 2(b <= 1)%positivea, b:Zb <> 0 -> let (q, r) := div_eucl a b in a = b * q + ra, b:Zb <> 0 -> let (q, r) := div_eucl a b in a = b * q + ra, b:positiveq, r:Zpos a = pos b * q + r -> pos a = pos b * q + ra, b:positiveq, r:Zpos a = pos b * q + r -> let (q0, r0) := match r with | 0 => (- q, 0) | _ => (- (q + 1), neg b + r) end in pos a = neg b * q0 + r0a, b:positiveq, r:Zpos a = pos b * q + r -> let (q0, r0) := match r with | 0 => (- q, 0) | _ => (- (q + 1), pos b - r) end in neg a = pos b * q0 + r0a, b:positiveq, r:Zpos a = pos b * q + r -> neg a = neg b * q + - rtrivial.a, b:positiveq, r:Zpos a = pos b * q + r -> pos a = pos b * q + ra, b:positiveq, r:Zpos a = pos b * q + r -> let (q0, r0) := match r with | 0 => (- q, 0) | _ => (- (q + 1), neg b + r) end in pos a = neg b * q0 + r0destruct r as [ |r|r]; rewrite <- !mul_opp_comm; trivial; rewrite mul_add_distr_l, mul_1_r, <- add_assoc; f_equal; now rewrite add_assoc, add_opp_diag_r.a, b:positiveq, r:Zlet (q0, r0) := match r with | 0 => (- q, 0) | _ => (- (q + 1), neg b + r) end in pos b * q + r = neg b * q0 + r0a, b:positiveq, r:Zpos a = pos b * q + r -> let (q0, r0) := match r with | 0 => (- q, 0) | _ => (- (q + 1), pos b - r) end in neg a = pos b * q0 + r0a, b:positiveq, r:Zpos a = pos b * q + r -> let (q0, r0) := match r with | 0 => (- q, 0) | _ => (- (q + 1), pos b - r) end in - pos a = pos b * q0 + r0a, b:positiveq, r:Zlet (q0, r0) := match r with | 0 => (- q, 0) | _ => (- (q + 1), pos b - r) end in - (pos b * q + r) = pos b * q0 + r0destruct r as [ |r|r]; trivial; rewrite opp_add_distr, mul_add_distr_l, <- add_assoc; f_equal; unfold sub; now rewrite add_assoc, mul_opp_r, mul_1_r, add_opp_diag_l.a, b:positiveq, r:Zlet (q0, r0) := match r with | 0 => (- q, 0) | _ => (- (q + 1), pos b - r) end in pos b * - q + - r = pos b * q0 + r0a, b:positiveq, r:Zpos a = pos b * q + r -> neg a = neg b * q + - ra, b:positiveq, r:Zpos a = pos b * q + r -> - pos a = neg b * q + - rnow rewrite opp_add_distr, <- mul_opp_l. Qed.a, b:positiveq, r:Z- (pos b * q + r) = neg b * q + - ra, b:Zb <> 0 -> a = b * (a / b) + a mod ba, b:Zb <> 0 -> a = b * (a / b) + a mod ba, b:ZHb:b <> 0a = b * (a / b) + a mod ba, b:ZHb:b <> 0(let (q, r) := div_eucl a b in a = b * q + r) -> a = b * (a / b) + a mod bnow destruct div_eucl. Qed.a, b:ZHb:b <> 0(let (q, r) := div_eucl a b in a = b * q + r) -> a = b * (let (q, _) := div_eucl a b in q) + (let (_, r) := div_eucl a b in r)a:positiveb:Z0 < b -> 0 <= snd (pos_div_eucl a b) < ba:positiveb:Z0 < b -> 0 <= snd (pos_div_eucl a b) < ba:positiveb:Zforall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pa:positiveb:ZAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 < b -> 0 <= snd (pos_div_eucl a b) < ba:positiveb, m:Zp:positivem < pos p~0 -> m - pos p < pos pa:positiveb:ZAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 < b -> 0 <= snd (pos_div_eucl a b) < ba:positiveb, m:Zp:positive(m ?= pos p~0) = Lt -> (m - pos p ?= pos p) = Lta:positiveb:ZAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 < b -> 0 <= snd (pos_div_eucl a b) < ba:positiveb, m:Zp:positive(m - pos p~0 ?= 0) = Lt -> (m - pos p - pos p ?= 0) = Lta:positiveb:ZAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 < b -> 0 <= snd (pos_div_eucl a b) < ba:positiveb, m:Zp:positive(m + - pos p~0 ?= 0) = Lt -> (m + - pos p + - pos p ?= 0) = Lta:positiveb:ZAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 < b -> 0 <= snd (pos_div_eucl a b) < ba:positiveb, m:Zp:positive(m + - pos p~0 ?= 0) = Lt -> (m + (- pos p + - pos p) ?= 0) = Lta:positiveb:ZAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 < b -> 0 <= snd (pos_div_eucl a b) < ba:positiveb, m:Zp:positive(m + neg p~0 ?= 0) = Lt -> (m + neg (p + p) ?= 0) = Lta:positiveb:ZAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 < b -> 0 <= snd (pos_div_eucl a b) < ba:positiveb:ZAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 < b -> 0 <= snd (pos_div_eucl a b) < ba:positiveb:ZAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pHb:0 < b0 <= snd (pos_div_eucl a b) < ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (pos_div_eucl a (pos b)) < pos b(* ~1 *)a, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r + 1 <? pos b then (2 * q, 2 * r + 1) else (2 * q + 1, 2 * r + 1 - pos b)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZIHa:0 <= snd (q, r) < pos b0 <= snd (if 2 * r + 1 <? pos b then (2 * q, 2 * r + 1) else (2 * q + 1, 2 * r + 1 - pos b)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos b0 <= snd (if 2 * r + 1 <? pos b then (2 * q, 2 * r + 1) else (2 * q + 1, 2 * r + 1 - pos b)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:2 * r + 1 < pos b0 <= 2 * r + 1 < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r + 10 <= 2 * r + 1 - pos b < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:2 * r + 1 < pos b0 <= 2 * r + 1a, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r + 10 <= 2 * r + 1 - pos b < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r + 10 <= 2 * r + 1 - pos b < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r + 10 <= 2 * r + 1 - pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r + 12 * r + 1 - pos b < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r + 1(0 ?= 2 * r + 1 - pos b) <> Gta, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r + 12 * r + 1 - pos b < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r + 12 * r + 1 - pos b < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r + 12 * r + 1 < pos b~0a, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r + 1succ_double r < pos b~0a, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p0 : positive), m < pos p0~0 -> m - pos p0 < pos p0q:Zp:positiveHr:0 <= pos pHr':pos p < pos bH:pos b <= 2 * pos p + 1succ_double (pos p) < pos b~0a, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p0 : positive), (m ?= pos p0~0) = Lt -> (m - pos p0 ?= pos p0) = Ltq:Zp:positiveHr:0 <= pos pHr':(p ?= b)%positive = LtH:pos b <= pos p~1(p~1 ?= b~0)%positive = Lta, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos b(* ~0 *)a, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pIHa:0 <= snd (pos_div_eucl a (pos b)) < pos b0 <= snd (let (q, r) := pos_div_eucl a (pos b) in if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZIHa:0 <= snd (q, r) < pos b0 <= snd (if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos b0 <= snd (if 2 * r <? pos b then (2 * q, 2 * r) else (2 * q + 1, 2 * r - pos b)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:2 * r < pos b0 <= 2 * r < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r0 <= 2 * r - pos b < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:2 * r < pos b0 <= 2 * ra, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r0 <= 2 * r - pos b < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r0 <= 2 * r - pos b < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r0 <= 2 * r - pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r2 * r - pos b < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r(0 ?= 2 * r - pos b) <> Gta, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r2 * r - pos b < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r2 * r - pos b < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos ba, b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pq, r:ZHr:0 <= rHr':r < pos bH:pos b <= 2 * r2 * r < pos b~0b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos b(* 1 *)b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos p0 <= snd (if 2 <=? pos b then (0, 1) else (1, 0)) < pos bb:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pH:2 <= pos b1 < pos bnow apply Pos.le_succ_l. Qed.b:positiveAUX:forall (m : Z) (p : positive), m < pos p~0 -> m - pos p < pos pH:2 <= pos b(1 ?= b)%positive = Lta, b:Z0 < b -> 0 <= a mod b < ba, b:Z0 < b -> 0 <= a mod b < ba:Zb:positive0 <= a mod pos b < pos bb:positive0 <= 0 < pos ba, b:positive0 <= (let (_, r) := pos_div_eucl a (pos b) in r) < pos ba, b:positive0 <= (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in match r with | 0 => (- q, 0) | _ => (- (q + 1), pos b - r) end in r) < pos ba, b:positive0 <= (let (_, r) := pos_div_eucl a (pos b) in r) < pos ba, b:positive0 <= (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in match r with | 0 => (- q, 0) | _ => (- (q + 1), pos b - r) end in r) < pos ba, b:positive0 <= (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in match r with | 0 => (- q, 0) | _ => (- (q + 1), pos b - r) end in r) < pos ba, b:positive0 <= snd (pos_div_eucl a (pos b)) < pos b -> 0 <= (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in match r with | 0 => (- q, 0) | _ => (- (q + 1), pos b - r) end in r) < pos ba, b:positiveq, r:ZHr:0 <= rHr':r < pos b0 <= (let (_, r0) := match r with | 0 => (- q, 0) | _ => (- (q + 1), pos b - r) end in r0) < pos ba, b:positiveq:ZHr':0 < pos b0 <= 0 < pos ba, b:positiveq:Zr:positiveHr':pos r < pos b0 <= pos b - pos r < pos ba, b:positiveq:Zr:positiveHr':pos r < pos b0 <= pos b - pos r < pos ba, b:positiveq:Zr:positiveHr':pos r < pos b0 <= pos b - pos ra, b:positiveq:Zr:positiveHr':pos r < pos bpos b - pos r < pos ba, b:positiveq:Zr:positiveHr':pos r < pos b(0 ?= pos b - pos r) <> Gta, b:positiveq:Zr:positiveHr':pos r < pos bpos b - pos r < pos ba, b:positiveq:Zr:positiveHr':pos r < pos bpos b - pos r < pos ba, b:positiveq:Zr:positiveHr':(r ?= b)%positive = Lt(pos_sub b r ?= pos b) = Lta, b:positiveq:Zr:positiveHr':(r ?= b)%positive = Lt(pos (b - r) ?= pos b) = Ltnow apply Pos.sub_decr. Qed. Definition mod_bound_pos a b (_:0<=a) := mod_pos_bound a b.a, b:positiveq:Zr:positiveHr':(r ?= b)%positive = Lt(b - r ?= b)%positive = Lta, b:Zb < 0 -> b < a mod b <= 0a, b:Zb < 0 -> b < a mod b <= 0a:Zb:positiveneg b < a mod neg b <= 0b:positiveneg b < 0 <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in match r with | 0 => (- q, 0) | _ => (- (q + 1), neg b + r) end in r) <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in match r with | 0 => (- q, 0) | _ => (- (q + 1), neg b + r) end in r) <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positive0 <= snd (pos_div_eucl a (pos b)) < pos b -> neg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in match r with | 0 => (- q, 0) | _ => (- (q + 1), neg b + r) end in r) <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq, r:ZHr:0 <= rHr':r < pos bneg b < (let (_, r0) := match r with | 0 => (- q, 0) | _ => (- (q + 1), neg b + r) end in r0) <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq:ZHr':0 < pos bneg b < 0 <= 0a, b:positiveq:Zr:positiveHr':pos r < pos bneg b < neg b + pos r <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq:Zr:positiveHr':pos r < pos bneg b < neg b + pos r <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq:Zr:positiveHr':pos r < pos bneg b < neg b + pos ra, b:positiveq:Zr:positiveHr':pos r < pos bneg b + pos r <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq:Zr:positiveHr':(r ?= b)%positive = Ltmatch pos_sub r b with | neg y' => CompOpp (b ?= y')%positive | _ => Lt end = Lta, b:positiveq:Zr:positiveHr':pos r < pos bneg b + pos r <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq:Zr:positiveHr':(r ?= b)%positive = LtCompOpp (b ?= b - r)%positive = Lta, b:positiveq:Zr:positiveHr':pos r < pos bneg b + pos r <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq:Zr:positiveHr':(r ?= b)%positive = Lt(b - r ?= b)%positive = Lta, b:positiveq:Zr:positiveHr':pos r < pos bneg b + pos r <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq:Zr:positiveHr':pos r < pos bneg b + pos r <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq:Zr:positiveHr':pos r < pos bneg b - neg r <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq:Zr:positiveHr':(pos r ?= pos b) = Lt(neg b - neg r ?= 0) <> Gta, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq:Zr:positiveHr':(pos r ?= pos b) = Lt(neg b ?= neg r) <> Gta, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq:Zr:positiveHr':(r ?= b)%positive = LtCompOpp (b ?= r)%positive <> Gta, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveneg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positive0 <= snd (pos_div_eucl a (pos b)) < pos b -> neg b < (let (_, r) := let (q, r) := pos_div_eucl a (pos b) in (q, - r) in r) <= 0a, b:positiveq, r:ZHr:0 <= rHr':r < pos bneg b < - r <= 0red; simpl; now rewrite <- Pos.compare_antisym. Qed.a, b:positiveq:Zp:positiveHr:0 <= pos pHr':pos p < pos bneg b < - pos p
a, b:Zlet (q, r) := quotrem a b in a = q * b + rdestruct a as [|a|a], b as [|b|b]; simpl; trivial; generalize (N.pos_div_eucl_spec a (N.pos b)); case N.pos_div_eucl; trivial; intros q r; try change (neg a) with (-pos a); change (pos a) with (of_N (N.pos a)); intros ->; now destruct q, r. Qed.a, b:Zlet (q, r) := quotrem a b in a = q * b + ra, b:Za = b * (a ÷ b) + rem a ba, b:Za = b * (a ÷ b) + rem a ba, b:Za = a ÷ b * b + rem a ba, b:Z(let (q, r) := quotrem a b in a = q * b + r) -> a = a ÷ b * b + rem a bnow destruct quotrem. Qed.a, b:Z(let (q, r) := quotrem a b in a = q * b + r) -> a = fst (quotrem a b) * b + snd (quotrem a b)a, b:Zb <> 0 -> a = b * (a ÷ b) + rem a ba, b:Zb <> 0 -> a = b * (a ÷ b) + rem a bapply quot_rem'. Qed.a, b:Za = b * (a ÷ b) + rem a ba, b:Z0 <= a -> 0 < b -> 0 <= rem a b < ba, b:Z0 <= a -> 0 < b -> 0 <= rem a b < ba, b:ZHa:0 <= aHb:0 < b0 <= rem a b < bb:positive0 <= rem 0 (pos b) < pos ba, b:positive0 <= rem (pos a) (pos b) < pos bb:positive(Eq = Gt -> False) /\ Lt = Lta, b:positive0 <= rem (pos a) (pos b) < pos ba, b:positive0 <= rem (pos a) (pos b) < pos ba, b:positive0 <= snd (let (q, r) := N.pos_div_eucl a (N.pos b) in (of_N q, of_N r)) < pos ba, b:positiveH:N.pos b <> 0%N -> (snd (N.pos_div_eucl a (N.pos b)) < N.pos b)%N0 <= snd (let (q, r) := N.pos_div_eucl a (N.pos b) in (of_N q, of_N r)) < pos bnow apply H. Qed.a, b:positiveq:Nr:positiveH:N.pos b <> 0%N -> (snd (q, N.pos r) < N.pos b)%Npos r < pos ba, b:Zrem (- a) b = - rem a bdestruct a, b; trivial; unfold rem; simpl; now destruct N.pos_div_eucl as (q,[|r]). Qed.a, b:Zrem (- a) b = - rem a ba, b:Zrem a (- b) = rem a bdestruct a, b; trivial; unfold rem; simpl; now destruct N.pos_div_eucl as (q,[|r]). Qed.a, b:Zrem a (- b) = rem a ba, b:Zb <> 0 -> rem (- a) b = - rem a ba, b:Zb <> 0 -> rem (- a) b = - rem a bapply rem_opp_l'. Qed.a, b:Zrem (- a) b = - rem a ba, b:Zb <> 0 -> rem a (- b) = rem a ba, b:Zb <> 0 -> rem a (- b) = rem a bapply rem_opp_r'. Qed.a, b:Zrem a (- b) = rem a b
p, q:positive(pos p | pos q) <-> (p | q)%positivep, q:positive(pos p | pos q) <-> (p | q)%positivep, q:positive(pos p | pos q) -> (p | q)%positivep, q:positive(p | q)%positive -> (pos p | pos q)p, q, r:positiveH:q = (r * p)%positive(p | q)%positivep, q:positive(p | q)%positive -> (pos p | pos q)p, q:positive(p | q)%positive -> (pos p | pos q)exists (pos r); simpl; now f_equal. Qed.p, q, r:positiveH:q = (r * p)%positive(pos p | pos q)n:Zp:positive(n | pos p) <-> (n | neg p)split; intros (m,H); exists (-m); now rewrite mul_opp_l, <- H. Qed.n:Zp:positive(n | pos p) <-> (n | neg p)n:Zp:positive(pos p | n) <-> (neg p | n)split; intros (m,H); exists (-m); now rewrite mul_opp_l, <- mul_opp_r. Qed.n:Zp:positive(pos p | n) <-> (neg p | n)
a, b:Zfst (ggcd a b) = gcd a bdestruct a as [ |p|p], b as [ |q|q]; simpl; auto; generalize (Pos.ggcd_gcd p q); destruct Pos.ggcd as (g,(aa,bb)); simpl; congruence. Qed.a, b:Zfst (ggcd a b) = gcd a ba, b:Zlet '(g, (aa, bb)) := ggcd a b in a = g * aa /\ b = g * bbdestruct a as [ |p|p], b as [ |q|q]; simpl; rewrite ?Pos.mul_1_r; auto; generalize (Pos.ggcd_correct_divisors p q); destruct Pos.ggcd as (g,(aa,bb)); simpl; destruct 1; now subst. Qed.a, b:Zlet '(g, (aa, bb)) := ggcd a b in a = g * aa /\ b = g * bba, b:Z(gcd a b | a)a, b:Z(gcd a b | a)a, b:Z(fst (ggcd a b) | a)a, b:Z(let '(g, (aa, bb)) := ggcd a b in a = g * aa /\ b = g * bb) -> (fst (ggcd a b) | a)a, b, g, aa, bb:Za = g * aa /\ b = g * bb -> (g | a)a, b, g, aa, bb:ZH:a = g * aa(g | a)now rewrite mul_comm. Qed.a, b, g, aa, bb:ZH:a = g * aaa = aa * ga, b:Z(gcd a b | b)a, b:Z(gcd a b | b)a, b:Z(fst (ggcd a b) | b)a, b:Z(let '(g, (aa, bb)) := ggcd a b in a = g * aa /\ b = g * bb) -> (fst (ggcd a b) | b)a, b, g, aa, bb:Za = g * aa /\ b = g * bb -> (g | b)a, b, g, aa, bb:ZH:b = g * bb(g | b)now rewrite mul_comm. Qed.a, b, g, aa, bb:ZH:b = g * bbb = bb * ga, b, c:Z(c | a) -> (c | b) -> (c | gcd a b)a, b, c:Z(c | a) -> (c | b) -> (c | gcd a b)a, b, c:Zforall (p q : positive) (r : Z), (r | pos p) -> (r | pos q) -> (r | pos (Pos.gcd p q))a, b, c:ZH:forall (p q : positive) (r : Z), (r | pos p) -> (r | pos q) -> (r | pos (Pos.gcd p q))(c | a) -> (c | b) -> (c | gcd a b)a, b, c:Zforall (p q : positive) (r : Z), (r | pos p) -> (r | pos q) -> (r | pos (Pos.gcd p q))a, b, c:Zp, q:positiveH:(0 | pos p)H':(0 | pos q)(0 | pos (Pos.gcd p q))a, b, c:Zp, q, r:positiveH:(pos r | pos p)H':(pos r | pos q)(pos r | pos (Pos.gcd p q))a, b, c:Zp, q, r:positiveH:(neg r | pos p)H':(neg r | pos q)(neg r | pos (Pos.gcd p q))a, b, c:Zp, q, r:positiveH:(pos r | pos p)H':(pos r | pos q)(pos r | pos (Pos.gcd p q))a, b, c:Zp, q, r:positiveH:(neg r | pos p)H':(neg r | pos q)(neg r | pos (Pos.gcd p q))apply divide_Zpos_Zneg_l, divide_Zpos, Pos.gcd_greatest; now apply divide_Zpos, divide_Zpos_Zneg_l.a, b, c:Zp, q, r:positiveH:(neg r | pos p)H':(neg r | pos q)(neg r | pos (Pos.gcd p q))destruct a, b; simpl; auto; intros; try apply H; trivial; now apply divide_Zpos_Zneg_r. Qed.a, b, c:ZH:forall (p q : positive) (r : Z), (r | pos p) -> (r | pos q) -> (r | pos (Pos.gcd p q))(c | a) -> (c | b) -> (c | gcd a b)a, b:Z0 <= gcd a bnow destruct a, b. Qed.a, b:Z0 <= gcd a b
ggcd and opp : an auxiliary result used in QArith
a, b:Zggcd (- a) b = (let '(g, (aa, bb)) := ggcd a b in (g, (- aa, bb)))destruct a as [|a|a], b as [|b|b]; unfold ggcd, opp; auto; destruct (Pos.ggcd a b) as (g,(aa,bb)); auto. Qed.a, b:Zggcd (- a) b = (let '(g, (aa, bb)) := ggcd a b in (g, (- aa, bb)))
a, n:Ntestbit (of_N a) (of_N n) = N.testbit a na, n:Ntestbit (of_N a) (of_N n) = N.testbit a nnow destruct a. Qed.a:positivematch a with | (_~0)%positive => false | _ => true end = Pos.testbit a 0a:Nn:Z0 <= n -> testbit (of_N a) n = N.testbit a (to_N n)a:Nn:Z0 <= n -> testbit (of_N a) n = N.testbit a (to_N n)a:Nn:ZHn:0 <= ntestbit (of_N a) n = N.testbit a (to_N n)a:Nn:ZHn:0 <= ntestbit (of_N a) n = testbit (of_N a) (of_N (to_N n))destruct n; trivial; now destruct Hn. Qed.a:Nn:ZHn:0 <= nn = of_N (to_N n)a:positiven:Z0 <= n -> testbit (pos a) n = N.testbit (N.pos a) (to_N n)a:positiven:Z0 <= n -> testbit (pos a) n = N.testbit (N.pos a) (to_N n)now rewrite <- testbit_of_N'. Qed.a:positiven:ZHn:0 <= ntestbit (pos a) n = N.testbit (N.pos a) (to_N n)a:positiven:Z0 <= n -> testbit (neg a) n = negb (N.testbit (Pos.pred_N a) (to_N n))a:positiven:Z0 <= n -> testbit (neg a) n = negb (N.testbit (Pos.pred_N a) (to_N n))a:positiven:ZHn:0 <= ntestbit (neg a) n = negb (N.testbit (Pos.pred_N a) (to_N n))a:positiven:ZHn:0 <= ntestbit (neg a) n = negb (testbit (of_N (Pos.pred_N a)) n)a:positiveHn:0 <= 0testbit (neg a) 0 = negb (testbit (of_N (Pos.pred_N a)) 0)now destruct a as [|[ | | ]| ]. Qed.a:positiveHn:0 <= 0odd (neg a) = negb (odd (of_N (Pos.pred_N a)))
a:Zdiv2 a = shiftr a 1reflexivity. Qed.a:Zdiv2 a = shiftr a 1n:Ztestbit 0 n = falsenow destruct n. Qed.n:Ztestbit 0 n = falsea, n:Zn < 0 -> testbit a n = falsenow destruct n. Qed.a, n:Zn < 0 -> testbit a n = falsea:Ztestbit (2 * a + 1) 0 = truenow destruct a as [|a|[a|a|]]. Qed.a:Ztestbit (2 * a + 1) 0 = truea:Ztestbit (2 * a) 0 = falsenow destruct a. Qed.a:Ztestbit (2 * a) 0 = falsea, n:Z0 <= n -> testbit (2 * a + 1) (succ n) = testbit a na, n:Z0 <= n -> testbit (2 * a + 1) (succ n) = testbit a na:Ztestbit (2 * a + 1) (succ 0) = testbit a 0a:Zn:positivetestbit (2 * a + 1) (succ (pos n)) = testbit a (pos n)a:positivenegb (Pos.testbit (Pos.pred_double a) 0) = falsea:Zn:positivetestbit (2 * a + 1) (succ (pos n)) = testbit a (pos n)a:Zn:positivetestbit (2 * a + 1) (succ (pos n)) = testbit a (pos n)destruct a as [|a|[a|a|]]; simpl; trivial; rewrite ?Pos.add_1_r, ?Pos.pred_N_succ; now destruct n. Qed.a:Zn:positivematch match a with | 0 => 0 | pos y' => pos y'~0 | neg y' => neg y'~0 end + 1 with | 0 => false | pos a0 => Pos.testbit a0 (N.pos (n + 1)) | neg a0 => negb (N.testbit (Pos.pred_N a0) (N.pos (n + 1))) end = match a with | 0 => false | pos a0 => Pos.testbit a0 (N.pos n) | neg a0 => negb (N.testbit (Pos.pred_N a0) (N.pos n)) enda, n:Z0 <= n -> testbit (2 * a) (succ n) = testbit a na, n:Z0 <= n -> testbit (2 * a) (succ n) = testbit a na:Ztestbit (2 * a) (succ 0) = testbit a 0a:Zn:positivetestbit (2 * a) (succ (pos n)) = testbit a (pos n)a:positivenegb (Pos.testbit (Pos.pred_double a) 0) = falsea:Zn:positivetestbit (2 * a) (succ (pos n)) = testbit a (pos n)a:Zn:positivetestbit (2 * a) (succ (pos n)) = testbit a (pos n)destruct a as [|a|[a|a|]]; simpl; trivial; rewrite ?Pos.add_1_r, ?Pos.pred_N_succ; now destruct n. Qed.a:Zn:positivematch match a with | 0 => 0 | pos y' => pos y'~0 | neg y' => neg y'~0 end with | 0 => false | pos a0 => Pos.testbit a0 (N.pos (n + 1)) | neg a0 => negb (N.testbit (Pos.pred_N a0) (N.pos (n + 1))) end = match a with | 0 => false | pos a0 => Pos.testbit a0 (N.pos n) | neg a0 => negb (N.testbit (Pos.pred_N a0) (N.pos n)) end
Correctness proofs about Z.shiftr and Z.shiftl
a, n, m:Z0 <= n -> 0 <= m -> testbit (shiftr a n) m = testbit a (m + n)a, n, m:Z0 <= n -> 0 <= m -> testbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHn:0 <= nHm:0 <= mtestbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHn:0 <= nHm:0 <= mtestbit (shiftl a (- n)) m = testbit a (m + n)a, m:ZHm:0 <= mtestbit a m = testbit a (m + 0)a:Zn:positivem:ZHm:0 <= mtestbit (Pos.iter div2 a n) m = testbit a (m + pos n)a:Zn:positivem:ZHm:0 <= mtestbit (Pos.iter div2 a n) m = testbit a (m + pos n)a:Zn:positivem:ZHm:0 <= mforall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%Na:Zn:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%Ntestbit (Pos.iter div2 a n) m = testbit a (m + pos n)a:Zn:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%Ntestbit (Pos.iter div2 a n) m = testbit a (m + pos n)a:Zn:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%Nforall p : positive, 0 <= m + pos pa:Zn:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 a n) m = testbit a (m + pos n)a:Zn:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 a n) m = testbit a (m + pos n)(* a = 0 *)n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 0 n) m = testbit 0 (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 (pos a) n) m = testbit (pos a) (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 (neg a) n) m = testbit (neg a) (m + pos n)n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit 0 m = testbit 0 (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 (pos a) n) m = testbit (pos a) (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 (neg a) n) m = testbit (neg a) (m + pos n)(* a > 0 *)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 (pos a) n) m = testbit (pos a) (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 (neg a) n) m = testbit (neg a) (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 (of_N (N.pos a)) n) m = testbit (pos a) (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 (neg a) n) m = testbit (neg a) (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (of_N (Pos.iter N.div2 (N.pos a) n)) m = testbit (pos a) (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 (neg a) n) m = testbit (neg a) (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos pN.testbit (Pos.iter N.div2 (N.pos a) n) (to_N m) = N.testbit (N.pos a) (to_N m + N.pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 (neg a) n) m = testbit (neg a) (m + pos n)(* a < 0 *)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (Pos.iter div2 (neg a) n) m = testbit (neg a) (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos ptestbit (neg (Pos.iter Pos.div2_up a n)) m = testbit (neg a) (m + pos n)a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos pnegb (N.testbit (Pos.pred_N (Pos.iter Pos.div2_up a n)) (to_N m)) = negb (N.testbit (Pos.pred_N a) (to_N m + N.pos n))a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos pN.testbit (Pos.pred_N (Pos.iter Pos.div2_up a n)) (to_N m) = N.testbit (Pos.pred_N a) (to_N m + N.pos n)exact (N.shiftr_spec' (Pos.pred_N a) (N.pos n) (to_N m)). Qed.a, n:positivem:ZHm:0 <= mH:forall p : positive, to_N (m + pos p) = (to_N m + N.pos p)%NH0:forall p : positive, 0 <= m + pos pN.testbit (Pos.iter N.div2 (Pos.pred_N a) n) (to_N m) = N.testbit (Pos.pred_N a) (to_N m + N.pos n)a, n, m:Zm < n -> testbit (shiftl a n) m = falsea, n, m:Zm < n -> testbit (shiftl a n) m = falsea, n, m:ZH:m < ntestbit (shiftl a n) m = falsea:Zn:positiveH:0 < pos ntestbit (Pos.iter (mul 2) a n) 0 = falsea:Zn, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) a n) (pos m) = falsea:Zn, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) a n) (pos m) = false(* a = 0 *)n, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) 0 n) (pos m) = falsea, n, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) (pos a) n) (pos m) = falsea, n, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) (neg a) n) (pos m) = falsen, m:positiveH:pos m < pos ntestbit 0 (pos m) = falsea, n, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) (pos a) n) (pos m) = falsea, n, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) (neg a) n) (pos m) = false(* a > 0 *)a, n, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) (pos a) n) (pos m) = falsea, n, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) (neg a) n) (pos m) = falsea, n, m:positiveH:pos m < pos ntestbit (pos (Pos.iter xO a n)) (pos m) = falsea, n, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) (neg a) n) (pos m) = falsea, n, m:positiveH:pos m < pos nN.testbit (N.pos (Pos.iter xO a n)) (to_N (pos m)) = falsea, n, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) (neg a) n) (pos m) = false(* a < 0 *)a, n, m:positiveH:pos m < pos ntestbit (Pos.iter (mul 2) (neg a) n) (pos m) = falsea, n, m:positiveH:pos m < pos ntestbit (neg (Pos.iter xO a n)) (pos m) = falsenow rewrite (N.pos_pred_shiftl_low a (N.pos n)). Qed.a, n, m:positiveH:pos m < pos nnegb (N.testbit (Pos.pred_N (Pos.iter xO a n)) (to_N (pos m))) = falsea, n, m:Z0 <= m -> n <= m -> testbit (shiftl a n) m = testbit a (m - n)a, n, m:Z0 <= m -> n <= m -> testbit (shiftl a n) m = testbit a (m - n)a, n, m:ZHm:0 <= mH:n <= mtestbit (shiftl a n) m = testbit a (m - n)a, m:ZHm, H:0 <= mtestbit (shiftl a 0) m = testbit a (m - 0)a:Zn:positivem:ZHm:0 <= mH:pos n <= mtestbit (shiftl a (pos n)) m = testbit a (m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a, m:ZHm, H:0 <= mtestbit a m = testbit a (m - 0)a:Zn:positivem:ZHm:0 <= mH:pos n <= mtestbit (shiftl a (pos n)) m = testbit a (m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)(* n > 0 *)a:Zn:positivem:ZHm:0 <= mH:pos n <= mtestbit (shiftl a (pos n)) m = testbit a (m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mtestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:pos n <= pos m0 <= pos m - pos na:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:pos n <= pos m(0 ?= pos m - pos n) <> Gta:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nto_N (pos m - pos n) = (N.pos m - N.pos n)%Na:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:(pos n ?= pos m) <> GtH0:0 <= pos m - pos nto_N (pos m - pos n) = (N.pos m - N.pos n)%Na:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:(n ?= m)%positive <> GtH0:0 <= pos m - pos nto_N (pos m - pos n) = (N.pos m - N.pos n)%Na:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:(n ?= m)%positive <> GtH0:0 <= pos m - pos nto_N (pos_sub m n) = (N.pos m - N.pos n)%Na:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:(n ?= m)%positive <> GtH0:0 <= pos m - pos nto_N match CompOpp (n ?= m)%positive with | Eq => 0 | Lt => neg (n - m) | Gt => pos (m - n) end = (N.pos m - N.pos n)%Na:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:Eq <> GtH0:0 <= pos m - pos nH':n = mto_N match CompOpp Eq with | Eq => 0 | Lt => neg (n - m) | Gt => pos (m - n) end = (N.pos m - N.pos n)%Na:Zn, m:positiveHm:0 <= pos mH:Lt <> GtH0:0 <= pos m - pos nH':(n < m)%positiveto_N match CompOpp Lt with | Eq => 0 | Lt => neg (n - m) | Gt => pos (m - n) end = (N.pos m - N.pos n)%Na:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zm:positiveHm:0 <= pos mH:Eq <> GtH0:0 <= pos m - pos mto_N match CompOpp Eq with | Eq => 0 | Lt => neg (m - m) | Gt => pos (m - m) end = (N.pos m - N.pos m)%Na:Zn, m:positiveHm:0 <= pos mH:Lt <> GtH0:0 <= pos m - pos nH':(n < m)%positiveto_N match CompOpp Lt with | Eq => 0 | Lt => neg (n - m) | Gt => pos (m - n) end = (N.pos m - N.pos n)%Na:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:Lt <> GtH0:0 <= pos m - pos nH':(n < m)%positiveto_N match CompOpp Lt with | Eq => 0 | Lt => neg (n - m) | Gt => pos (m - n) end = (N.pos m - N.pos n)%Na:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:Lt <> GtH0:0 <= pos m - pos nH':(n < m)%positiveN.pos (m - n) = match Pos.sub_mask m n with | Pos.IsPos p => N.pos p | _ => 0%N enda:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, p:positiveHm:0 <= pos (n + p)H:Lt <> GtH':(n < n + p)%positiveH0:0 <= pos (n + p) - pos nN.pos (n + p - n) = N.pos pa:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, p:positiveHm:0 <= pos (n + p)H:Lt <> GtH':(n < n + p)%positiveH0:0 <= pos (n + p) - pos n(n + p - n)%positive = pa:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (shiftl a (pos n)) (pos m) = testbit a (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)(* ... a = 0 *)n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (Pos.iter (mul 2) 0 n) (pos m) = testbit 0 (pos m - pos n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (Pos.iter (mul 2) (pos p) n) (pos m) = testbit (pos p) (pos m - pos n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (Pos.iter (mul 2) (neg p) n) (pos m) = testbit (neg p) (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit 0 (pos m) = testbit 0 (pos m - pos n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (Pos.iter (mul 2) (pos p) n) (pos m) = testbit (pos p) (pos m - pos n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (Pos.iter (mul 2) (neg p) n) (pos m) = testbit (neg p) (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)(* ... a > 0 *)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (Pos.iter (mul 2) (pos p) n) (pos m) = testbit (pos p) (pos m - pos n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (Pos.iter (mul 2) (neg p) n) (pos m) = testbit (neg p) (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (pos (Pos.iter xO p n)) (pos m) = testbit (pos p) (pos m - pos n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (Pos.iter (mul 2) (neg p) n) (pos m) = testbit (neg p) (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%NN.testbit (N.pos (Pos.iter xO p n)) (to_N (pos m)) = N.testbit (N.pos p) (N.pos m - N.pos n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (Pos.iter (mul 2) (neg p) n) (pos m) = testbit (neg p) (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)(* ... a < 0 *)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (Pos.iter (mul 2) (neg p) n) (pos m) = testbit (neg p) (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Ntestbit (neg (Pos.iter xO p n)) (pos m) = testbit (neg p) (pos m - pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%Nnegb (N.testbit (Pos.pred_N (Pos.iter xO p n)) (to_N (pos m))) = negb (N.testbit (Pos.pred_N p) (N.pos m - N.pos n))a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%NN.testbit (Pos.pred_N (Pos.iter xO p n)) (to_N (pos m)) = N.testbit (Pos.pred_N p) (N.pos m - N.pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%NN.testbit (Pos.pred_N (Pos.iter xO p n)) (N.pos m) = N.testbit (Pos.pred_N p) (N.pos m - N.pos n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)p, n, m:positiveHm:0 <= pos mH:pos n <= pos mH0:0 <= pos m - pos nEQ:to_N (pos m - pos n) = (N.pos m - N.pos n)%NN.testbit (Pos.pred_N (Pos.iter xO p n)) (N.pos m) = N.testbit (N.shiftl (Pos.pred_N p) (N.pos n)) (N.pos m)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)(* n < 0 *)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m - neg n)a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (shiftl a (neg n)) m = testbit a (m + - neg n)now apply (shiftr_spec_aux a (pos n) m). Qed.a:Zn:positivem:ZHm:0 <= mH:neg n <= mtestbit (Pos.iter div2 a n) m = testbit a (m + pos n)a, n, m:Z0 <= m -> testbit (shiftr a n) m = testbit a (m + n)a, n, m:Z0 <= m -> testbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHm:0 <= mtestbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHm:0 <= mH:0 <= ntestbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0testbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0testbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0LE:- n <= mtestbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0GT:m < - ntestbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0LE:- n <= mtestbit (shiftl a (- n)) m = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0GT:m < - ntestbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0LE:- n <= mtestbit a (m - - n) = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0GT:m < - ntestbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0GT:m < - ntestbit (shiftr a n) m = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0GT:m < - ntestbit (shiftl a (- n)) m = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0GT:m < - nfalse = testbit a (m + n)a, n, m:ZHm:0 <= mH:n < 0GT:m < - nm + n < 0a, n, m:ZHm:0 <= mH:n < 0GT:(m ?= - n) = Ltm + n < 0now destruct n. Qed.a, n, m:ZHm:0 <= mH:n < 0GT:(m - - n ?= 0) = Ltm + n < 0
Correctness proofs for bitwise operations
a, b, n:Ztestbit (lor a b) n = testbit a n || testbit b na, b, n:Ztestbit (lor a b) n = testbit a n || testbit b na, b, n:ZHn:0 <= ntestbit (lor a b) n = testbit a n || testbit b na, b:positiven:ZHn:0 <= nN.testbit (N.pos (Pos.lor a b)) (to_N n) = N.testbit (N.pos a) (to_N n) || N.testbit (N.pos b) (to_N n)a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.ldiff (Pos.pred_N b) (N.pos a)) (to_N n)) = N.testbit (N.pos a) (to_N n) || negb (N.testbit (Pos.pred_N b) (to_N n))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.ldiff (Pos.pred_N a) (N.pos b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) || N.testbit (N.pos b) (to_N n)a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.land (Pos.pred_N a) (Pos.pred_N b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) || negb (N.testbit (Pos.pred_N b) (to_N n))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.ldiff (Pos.pred_N b) (N.pos a)) (to_N n)) = N.testbit (N.pos a) (to_N n) || negb (N.testbit (Pos.pred_N b) (to_N n))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.ldiff (Pos.pred_N a) (N.pos b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) || N.testbit (N.pos b) (to_N n)a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.land (Pos.pred_N a) (Pos.pred_N b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) || negb (N.testbit (Pos.pred_N b) (to_N n))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.ldiff (Pos.pred_N a) (N.pos b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) || N.testbit (N.pos b) (to_N n)a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.land (Pos.pred_N a) (Pos.pred_N b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) || negb (N.testbit (Pos.pred_N b) (to_N n))now rewrite N.land_spec, negb_andb. Qed.a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.land (Pos.pred_N a) (Pos.pred_N b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) || negb (N.testbit (Pos.pred_N b) (to_N n))a, b, n:Ztestbit (land a b) n = testbit a n && testbit b na, b, n:Ztestbit (land a b) n = testbit a n && testbit b na, b, n:ZHn:0 <= ntestbit (land a b) n = testbit a n && testbit b na, b:positiven:ZHn:0 <= nN.testbit (Pos.land a b) (to_N n) = N.testbit (N.pos a) (to_N n) && N.testbit (N.pos b) (to_N n)a, b:positiven:ZHn:0 <= nN.testbit (N.ldiff (N.pos a) (Pos.pred_N b)) (to_N n) = N.testbit (N.pos a) (to_N n) && negb (N.testbit (Pos.pred_N b) (to_N n))a, b:positiven:ZHn:0 <= nN.testbit (N.ldiff (N.pos b) (Pos.pred_N a)) (to_N n) = negb (N.testbit (Pos.pred_N a) (to_N n)) && N.testbit (N.pos b) (to_N n)a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lor (Pos.pred_N a) (Pos.pred_N b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) && negb (N.testbit (Pos.pred_N b) (to_N n))a, b:positiven:ZHn:0 <= nN.testbit (N.ldiff (N.pos a) (Pos.pred_N b)) (to_N n) = N.testbit (N.pos a) (to_N n) && negb (N.testbit (Pos.pred_N b) (to_N n))a, b:positiven:ZHn:0 <= nN.testbit (N.ldiff (N.pos b) (Pos.pred_N a)) (to_N n) = negb (N.testbit (Pos.pred_N a) (to_N n)) && N.testbit (N.pos b) (to_N n)a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lor (Pos.pred_N a) (Pos.pred_N b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) && negb (N.testbit (Pos.pred_N b) (to_N n))a, b:positiven:ZHn:0 <= nN.testbit (N.ldiff (N.pos b) (Pos.pred_N a)) (to_N n) = negb (N.testbit (Pos.pred_N a) (to_N n)) && N.testbit (N.pos b) (to_N n)a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lor (Pos.pred_N a) (Pos.pred_N b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) && negb (N.testbit (Pos.pred_N b) (to_N n))now rewrite N.lor_spec, negb_orb. Qed.a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lor (Pos.pred_N a) (Pos.pred_N b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) && negb (N.testbit (Pos.pred_N b) (to_N n))a, b, n:Ztestbit (ldiff a b) n = testbit a n && negb (testbit b n)a, b, n:Ztestbit (ldiff a b) n = testbit a n && negb (testbit b n)a, b, n:ZHn:0 <= ntestbit (ldiff a b) n = testbit a n && negb (testbit b n)a, b:positiven:ZHn:0 <= nN.testbit (Pos.ldiff a b) (to_N n) = N.testbit (N.pos a) (to_N n) && negb (N.testbit (N.pos b) (to_N n))a, b:positiven:ZHn:0 <= nN.testbit (N.land (N.pos a) (Pos.pred_N b)) (to_N n) = N.testbit (N.pos a) (to_N n) && negb (negb (N.testbit (Pos.pred_N b) (to_N n)))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lor (Pos.pred_N a) (N.pos b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) && negb (N.testbit (N.pos b) (to_N n))a, b:positiven:ZHn:0 <= nN.testbit (N.ldiff (Pos.pred_N b) (Pos.pred_N a)) (to_N n) = negb (N.testbit (Pos.pred_N a) (to_N n)) && negb (negb (N.testbit (Pos.pred_N b) (to_N n)))a, b:positiven:ZHn:0 <= nN.testbit (N.land (N.pos a) (Pos.pred_N b)) (to_N n) = N.testbit (N.pos a) (to_N n) && negb (negb (N.testbit (Pos.pred_N b) (to_N n)))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lor (Pos.pred_N a) (N.pos b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) && negb (N.testbit (N.pos b) (to_N n))a, b:positiven:ZHn:0 <= nN.testbit (N.ldiff (Pos.pred_N b) (Pos.pred_N a)) (to_N n) = negb (N.testbit (Pos.pred_N a) (to_N n)) && negb (negb (N.testbit (Pos.pred_N b) (to_N n)))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lor (Pos.pred_N a) (N.pos b)) (to_N n)) = negb (N.testbit (Pos.pred_N a) (to_N n)) && negb (N.testbit (N.pos b) (to_N n))a, b:positiven:ZHn:0 <= nN.testbit (N.ldiff (Pos.pred_N b) (Pos.pred_N a)) (to_N n) = negb (N.testbit (Pos.pred_N a) (to_N n)) && negb (negb (N.testbit (Pos.pred_N b) (to_N n)))now rewrite N.ldiff_spec, negb_involutive, andb_comm. Qed.a, b:positiven:ZHn:0 <= nN.testbit (N.ldiff (Pos.pred_N b) (Pos.pred_N a)) (to_N n) = negb (N.testbit (Pos.pred_N a) (to_N n)) && negb (negb (N.testbit (Pos.pred_N b) (to_N n)))a, b, n:Ztestbit (lxor a b) n = xorb (testbit a n) (testbit b n)a, b, n:Ztestbit (lxor a b) n = xorb (testbit a n) (testbit b n)a, b, n:ZHn:0 <= ntestbit (lxor a b) n = xorb (testbit a n) (testbit b n)a, b:positiven:ZHn:0 <= nN.testbit (Pos.lxor a b) (to_N n) = xorb (N.testbit (N.pos a) (to_N n)) (N.testbit (N.pos b) (to_N n))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lxor (N.pos a) (Pos.pred_N b)) (to_N n)) = xorb (N.testbit (N.pos a) (to_N n)) (negb (N.testbit (Pos.pred_N b) (to_N n)))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lxor (Pos.pred_N a) (N.pos b)) (to_N n)) = xorb (negb (N.testbit (Pos.pred_N a) (to_N n))) (N.testbit (N.pos b) (to_N n))a, b:positiven:ZHn:0 <= nN.testbit (N.lxor (Pos.pred_N a) (Pos.pred_N b)) (to_N n) = xorb (negb (N.testbit (Pos.pred_N a) (to_N n))) (negb (N.testbit (Pos.pred_N b) (to_N n)))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lxor (N.pos a) (Pos.pred_N b)) (to_N n)) = xorb (N.testbit (N.pos a) (to_N n)) (negb (N.testbit (Pos.pred_N b) (to_N n)))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lxor (Pos.pred_N a) (N.pos b)) (to_N n)) = xorb (negb (N.testbit (Pos.pred_N a) (to_N n))) (N.testbit (N.pos b) (to_N n))a, b:positiven:ZHn:0 <= nN.testbit (N.lxor (Pos.pred_N a) (Pos.pred_N b)) (to_N n) = xorb (negb (N.testbit (Pos.pred_N a) (to_N n))) (negb (N.testbit (Pos.pred_N b) (to_N n)))a, b:positiven:ZHn:0 <= nnegb (N.testbit (N.lxor (Pos.pred_N a) (N.pos b)) (to_N n)) = xorb (negb (N.testbit (Pos.pred_N a) (to_N n))) (N.testbit (N.pos b) (to_N n))a, b:positiven:ZHn:0 <= nN.testbit (N.lxor (Pos.pred_N a) (Pos.pred_N b)) (to_N n) = xorb (negb (N.testbit (Pos.pred_N a) (to_N n))) (negb (N.testbit (Pos.pred_N b) (to_N n)))now rewrite N.lxor_spec, xorb_negb_negb. Qed.a, b:positiven:ZHn:0 <= nN.testbit (N.lxor (Pos.pred_N a) (Pos.pred_N b)) (to_N n) = xorb (negb (N.testbit (Pos.pred_N a) (to_N n))) (negb (N.testbit (Pos.pred_N b) (to_N n)))
Generic properties of advanced functions.
Include ZExtraProp.
In generic statements, the predicates lt and le have been
favored, whereas gt and ge don't even exist in the abstract
layers. The use of gt and ge is hence not recommended. We provide
here the bare minimal results to related them with lt and le.
n, m:Zn > m <-> m < nn, m:Zn > m <-> m < nnow rewrite compare_antisym, CompOpp_iff. Qed.n, m:Z(n ?= m) = Gt <-> (m ?= n) = Ltn, m:Zn > m -> m < napply gt_lt_iff. Qed.n, m:Zn > m -> m < nn, m:Zn < m -> m > napply gt_lt_iff. Qed.n, m:Zn < m -> m > nn, m:Zn >= m <-> m <= nn, m:Zn >= m <-> m <= nnow rewrite compare_antisym, CompOpp_iff. Qed.n, m:Z(n ?= m) <> Lt <-> (m ?= n) <> Gtn, m:Zn >= m -> m <= napply ge_le_iff. Qed.n, m:Zn >= m -> m <= nn, m:Zn <= m -> m >= napply ge_le_iff. Qed.n, m:Zn <= m -> m >= n
We provide a tactic converting from one style to the other.
Ltac swap_greater := rewrite ?gt_lt_iff in *; rewrite ?ge_le_iff in *.
Similarly, the boolean comparisons ltb and leb are favored
over their dual gtb and geb. We prove here the equivalence
and a few minimal results.
n, m:Z(n >? m) = (m <? n)n, m:Z(n >? m) = (m <? n)n, m:Zmatch n ?= m with | Gt => true | _ => false end = match m ?= n with | Lt => true | _ => false endnow case compare. Qed.n, m:Zmatch CompOpp (m ?= n) with | Gt => true | _ => false end = match m ?= n with | Lt => true | _ => false endn, m:Z(n >=? m) = (m <=? n)n, m:Z(n >=? m) = (m <=? n)n, m:Zmatch n ?= m with | Lt => false | _ => true end = match m ?= n with | Gt => false | _ => true endnow case compare. Qed.n, m:Zmatch CompOpp (m ?= n) with | Lt => false | _ => true end = match m ?= n with | Gt => false | _ => true endn, m:Z(n >? m) = true <-> m < nn, m:Z(n >? m) = true <-> m < napply ltb_lt. Qed.n, m:Z(m <? n) = true <-> m < nn, m:Z(n >=? m) = true <-> m <= nn, m:Z(n >=? m) = true <-> m <= napply leb_le. Qed.n, m:Z(m <=? n) = true <-> m <= nn, m:ZBoolSpec (m < n) (n <= m) (n >? m)n, m:ZBoolSpec (m < n) (n <= m) (n >? m)apply ltb_spec. Qed.n, m:ZBoolSpec (m < n) (n <= m) (m <? n)n, m:ZBoolSpec (m <= n) (n < m) (n >=? m)n, m:ZBoolSpec (m <= n) (n < m) (n >=? m)apply leb_spec. Qed.n, m:ZBoolSpec (m <= n) (n < m) (m <=? n)
TODO : to add in Numbers ?
n, m, p:Zn + m = n + p -> m = pexact (proj1 (add_cancel_l m p n)). Qed.n, m, p:Zn + m = n + p -> m = pn, m, p:Zp <> 0 -> p * n = p * m -> n = mexact (fun Hp => proj1 (mul_cancel_l n m p Hp)). Qed.n, m, p:Zp <> 0 -> p * n = p * m -> n = mn, m, p:Zp <> 0 -> n * p = m * p -> n = mexact (fun Hp => proj1 (mul_cancel_r n m p Hp)). Qed.n, m, p:Zp <> 0 -> n * p = m * p -> n = mn:Z- n = n * -1n:Z- n = n * -1now destruct n. Qed.n:Z- n = -1 * nn:Zn + n = 2 * nn:Zn + n = 2 * nnow rewrite mul_add_distr_r, !mul_1_l. Qed.n:Zn + n = (1 + 1) * n
n, m:Z(- n ?= - m) = (m ?= n)destruct n, m; simpl; trivial; intros; now rewrite <- Pos.compare_antisym. Qed.n, m:Z(- n ?= - m) = (m ?= n)
n, m, p:Z(n + m ?= n + p) = (m ?= p)n, m, p:Z(n + m ?= n + p) = (m ?= p)n, m, p:Z(n + m - (n + p) ?= 0) = (m - p ?= 0)n, m, p:Zn + m - (n + p) = m - pn, m, p:Zn + m + - (n + p) = m + - pn, m, p:Zm + n + - n + - p = m + - pnow rewrite <- add_assoc, add_opp_diag_r, add_0_r. Qed.n, m, p:Zm + n + - n = m
a, n, i:ZH:0 <= ntestbit (a mod 2 ^ n) i = (i <? n) && testbit a idestruct (ltb_spec i n); rewrite ?mod_pow2_bits_low, ?mod_pow2_bits_high by auto; auto. Qed.a, n, i:ZH:0 <= ntestbit (a mod 2 ^ n) i = (i <? n) && testbit a in, i:ZH:0 <= ntestbit (ones n) i = (0 <=? i) && (i <? n)destruct (leb_spec 0 i), (ltb_spec i n); cbn; rewrite ?testbit_neg_r, ?ones_spec_low, ?ones_spec_high by auto; trivial. Qed.n, i:ZH:0 <= ntestbit (ones n) i = (0 <=? i) && (i <? n)n, i:ZHn:0 <= nHi:0 <= itestbit (ones n) i = (i <? n)n, i:ZHn:0 <= nHi:0 <= itestbit (ones n) i = (i <? n)destruct (leb_spec 0 i); cbn; solve [ trivial | destruct (proj1 (Z.le_ngt _ _) Hi ltac:(eassumption)) ]. Qed. End Z. Bind Scope Z_scope with Z.t Z.n, i:ZHn:0 <= nHi:0 <= i(0 <=? i) && (i <? n) = (i <? n)
Re-export Notations
Numeral Notation Z Z.of_int Z.to_int : Z_scope. Infix "+" := Z.add : Z_scope. Notation "- x" := (Z.opp x) : Z_scope. Infix "-" := Z.sub : Z_scope. Infix "*" := Z.mul : Z_scope. Infix "^" := Z.pow : Z_scope. Infix "/" := Z.div : Z_scope. Infix "mod" := Z.modulo (at level 40, no associativity) : Z_scope. Infix "÷" := Z.quot (at level 40, left associativity) : Z_scope. Infix "?=" := Z.compare (at level 70, no associativity) : Z_scope. Infix "=?" := Z.eqb (at level 70, no associativity) : Z_scope. Infix "<=?" := Z.leb (at level 70, no associativity) : Z_scope. Infix "<?" := Z.ltb (at level 70, no associativity) : Z_scope. Infix ">=?" := Z.geb (at level 70, no associativity) : Z_scope. Infix ">?" := Z.gtb (at level 70, no associativity) : Z_scope. Notation "( x | y )" := (Z.divide x y) (at level 0) : Z_scope. Infix "<=" := Z.le : Z_scope. Infix "<" := Z.lt : Z_scope. Infix ">=" := Z.ge : Z_scope. Infix ">" := Z.gt : Z_scope. Notation "x <= y <= z" := (x <= y /\ y <= z) : Z_scope. Notation "x <= y < z" := (x <= y /\ y < z) : Z_scope. Notation "x < y < z" := (x < y /\ y < z) : Z_scope. Notation "x < y <= z" := (x < y /\ y <= z) : Z_scope.
Conversions from / to positive numbers
Module Pos2Z.p:positiveZ.to_pos (Zpos p) = preflexivity. Qed.p:positiveZ.to_pos (Zpos p) = pp, q:positiveZpos p = Zpos q -> p = qnow injection 1. Qed.p, q:positiveZpos p = Zpos q -> p = qp, q:positiveZpos p = Zpos q <-> p = qp, q:positiveZpos p = Zpos q <-> p = qp, q:positiveZpos p = Zpos q -> p = qp, q:positivep = q -> Zpos p = Zpos qintros; now f_equal. Qed.p, q:positivep = q -> Zpos p = Zpos qp:positive0 < Zpos preflexivity. Qed.p:positive0 < Zpos pp:positive0 <= Zpos peasy. Qed.p:positive0 <= Zpos p1 = 1reflexivity. Qed.1 = 1p:positiveZpos p~0 = 2 * Zpos preflexivity. Qed.p:positiveZpos p~0 = 2 * Zpos pp:positiveZpos p~1 = 2 * Zpos p + 1reflexivity. Qed.p:positiveZpos p~1 = 2 * Zpos p + 1p:positiveZpos (Pos.succ p) = Z.succ (Zpos p)p:positiveZpos (Pos.succ p) = Z.succ (Zpos p)now rewrite Pos.add_1_r. Qed.p:positiveZpos (Pos.succ p) = Zpos (p + 1)p, q:positiveZpos (p + q) = Zpos p + Zpos qreflexivity. Qed.p, q:positiveZpos (p + q) = Zpos p + Zpos qp, q:positive(p < q)%positive -> Zpos (q - p) = Zpos q - Zpos pp, q:positive(p < q)%positive -> Zpos (q - p) = Zpos q - Zpos pp, q:positiveH:(p < q)%positiveZpos (q - p) = Zpos q - Zpos pnow rewrite Z.pos_sub_gt. Qed.p, q:positiveH:(p < q)%positiveZpos (q - p) = Z.pos_sub q pp, q:positiveZpos (p - q) = Z.max 1 (Zpos p - Zpos q)p, q:positiveZpos (p - q) = Z.max 1 (Zpos p - Zpos q)p, q:positiveZpos (p - q) = Z.max 1 (Z.pos_sub p q)p, q:positiveZpos (p - q) = Z.max 1 match (p ?= q)%positive with | Eq => 0 | Lt => Zneg (q - p) | Gt => Zpos (p - q) endp, q:positiveH:p = qZpos (p - q) = Z.max 1 0p, q:positiveH:(p < q)%positiveZpos (p - q) = Z.max 1 (Zneg (q - p))p, q:positiveH:(q < p)%positiveZpos (p - q) = Z.max 1 (Zpos (p - q))subst; now rewrite Pos.sub_diag.p, q:positiveH:p = qZpos (p - q) = Z.max 1 0now rewrite Pos.sub_lt.p, q:positiveH:(p < q)%positiveZpos (p - q) = Z.max 1 (Zneg (q - p))now destruct (p-q)%positive. Qed.p, q:positiveH:(q < p)%positiveZpos (p - q) = Z.max 1 (Zpos (p - q))p:positivep <> 1%positive -> Zpos (Pos.pred p) = Z.pred (Zpos p)destruct p; easy || now destruct 1. Qed.p:positivep <> 1%positive -> Zpos (Pos.pred p) = Z.pred (Zpos p)p, q:positiveZpos (p * q) = Zpos p * Zpos qreflexivity. Qed.p, q:positiveZpos (p * q) = Zpos p * Zpos qp, q:positiveZpos (p ^ q) = Z.pow_pos (Zpos p) qnow apply Pos.iter_swap_gen. Qed.p, q:positiveZpos (p ^ q) = Z.pow_pos (Zpos p) qp, q:positiveZpos (p ^ q) = Zpos p ^ Zpos qapply inj_pow_pos. Qed.p, q:positiveZpos (p ^ q) = Zpos p ^ Zpos qp:positiveZpos (Pos.square p) = Z.square (Zpos p)reflexivity. Qed.p:positiveZpos (Pos.square p) = Z.square (Zpos p)p, q:positive(p ?= q)%positive = (Zpos p ?= Zpos q)reflexivity. Qed.p, q:positive(p ?= q)%positive = (Zpos p ?= Zpos q)p, q:positive(p <=? q)%positive = (Zpos p <=? Zpos q)reflexivity. Qed.p, q:positive(p <=? q)%positive = (Zpos p <=? Zpos q)p, q:positive(p <? q)%positive = (Zpos p <? Zpos q)reflexivity. Qed.p, q:positive(p <? q)%positive = (Zpos p <? Zpos q)p, q:positive(p =? q)%positive = (Zpos p =? Zpos q)reflexivity. Qed.p, q:positive(p =? q)%positive = (Zpos p =? Zpos q)p, q:positiveZpos (Pos.max p q) = Z.max (Zpos p) (Zpos q)p, q:positiveZpos (Pos.max p q) = Z.max (Zpos p) (Zpos q)p, q:positiveZpos match (p ?= q)%positive with | Gt => p | _ => q end = match Zpos p ?= Zpos q with | Lt => Zpos q | _ => Zpos p endnow case Z.compare_spec. Qed.p, q:positiveZpos match Zpos p ?= Zpos q with | Gt => p | _ => q end = match Zpos p ?= Zpos q with | Lt => Zpos q | _ => Zpos p endp, q:positiveZpos (Pos.min p q) = Z.min (Zpos p) (Zpos q)p, q:positiveZpos (Pos.min p q) = Z.min (Zpos p) (Zpos q)p, q:positiveZpos match (p ?= q)%positive with | Gt => q | _ => p end = match Zpos p ?= Zpos q with | Gt => Zpos q | _ => Zpos p endnow case Z.compare_spec. Qed.p, q:positiveZpos match Zpos p ?= Zpos q with | Gt => q | _ => p end = match Zpos p ?= Zpos q with | Gt => Zpos q | _ => Zpos p endp:positiveZpos (Pos.sqrt p) = Z.sqrt (Zpos p)reflexivity. Qed.p:positiveZpos (Pos.sqrt p) = Z.sqrt (Zpos p)p, q:positiveZpos (Pos.gcd p q) = Z.gcd (Zpos p) (Zpos q)reflexivity. Qed.p, q:positiveZpos (Pos.gcd p q) = Z.gcd (Zpos p) (Zpos q)p, q:positive(Zpos p | Zpos q) <-> (p | q)%positiveapply Z.divide_Zpos. Qed.p, q:positive(Zpos p | Zpos q) <-> (p | q)%positivea:positiven:Z0 <= n -> Z.testbit (Zpos a) n = N.testbit (N.pos a) (Z.to_N n)apply Z.testbit_Zpos. Qed.a:positiven:Z0 <= n -> Z.testbit (Zpos a) n = N.testbit (N.pos a) (Z.to_N n)
Some results concerning Z.neg and Z.pos
p, q:positiveZneg p = Zneg q -> p = qnow injection 1. Qed.p, q:positiveZneg p = Zneg q -> p = qp, q:positiveZneg p = Zneg q <-> p = qp, q:positiveZneg p = Zneg q <-> p = qp, q:positiveZneg p = Zneg q -> p = qp, q:positivep = q -> Zneg p = Zneg qintros; now f_equal. Qed.p, q:positivep = q -> Zneg p = Zneg qp, q:positiveZpos p = Zpos q -> p = qnow injection 1. Qed.p, q:positiveZpos p = Zpos q -> p = qp, q:positiveZpos p = Zpos q <-> p = qp, q:positiveZpos p = Zpos q <-> p = qp, q:positiveZpos p = Zpos q -> p = qp, q:positivep = q -> Zpos p = Zpos qintros; now f_equal. Qed.p, q:positivep = q -> Zpos p = Zpos qp:positiveZneg p < 0reflexivity. Qed.p:positiveZneg p < 0p:positiveZneg p <= 0easy. Qed.p:positiveZneg p <= 0p:positive0 < Zpos preflexivity. Qed.p:positive0 < Zpos pp:positive0 <= Zpos peasy. Qed.p:positive0 <= Zpos pp, q:positiveZneg p <= Zpos qeasy. Qed.p, q:positiveZneg p <= Zpos qp, q:positiveZneg p < Zpos qeasy. Qed.p, q:positiveZneg p < Zpos qp, q:positive(q <= p)%positive -> Zneg p <= Zneg qp, q:positive(q <= p)%positive -> Zneg p <= Zneg qnow rewrite <- Pos.compare_antisym. Qed.p, q:positiveH:(q <= p)%positiveCompOpp (p ?= q)%positive <> Gtp, q:positive(q < p)%positive -> Zneg p < Zneg qp, q:positive(q < p)%positive -> Zneg p < Zneg qnow rewrite <- Pos.compare_antisym. Qed.p, q:positiveH:(q < p)%positiveCompOpp (p ?= q)%positive = Ltp, q:positive(p <= q)%positive -> Zpos p <= Zpos qeasy. Qed.p, q:positive(p <= q)%positive -> Zpos p <= Zpos qp, q:positive(p < q)%positive -> Zpos p < Zpos qeasy. Qed.p, q:positive(p < q)%positive -> Zpos p < Zpos qp:positiveZneg p~0 = 2 * Zneg preflexivity. Qed.p:positiveZneg p~0 = 2 * Zneg pp:positiveZneg p~1 = 2 * Zneg p - 1reflexivity. Qed.p:positiveZneg p~1 = 2 * Zneg p - 1p:positiveZpos p~0 = 2 * Zpos preflexivity. Qed.p:positiveZpos p~0 = 2 * Zpos pp:positiveZpos p~1 = 2 * Zpos p + 1reflexivity. Qed.p:positiveZpos p~1 = 2 * Zpos p + 1p:positive- Zneg p = Zpos preflexivity. Qed.p:positive- Zneg p = Zpos pp:positive- Zpos p = Zneg preflexivity. Qed.p:positive- Zpos p = Zneg pp, q:positiveZneg p + Zneg q = Zneg (p + q)reflexivity. Qed.p, q:positiveZneg p + Zneg q = Zneg (p + q)p, q:positiveZpos p + Zneg q = Z.pos_sub p qreflexivity. Qed.p, q:positiveZpos p + Zneg q = Z.pos_sub p qp, q:positiveZneg p + Zpos q = Z.pos_sub q preflexivity. Qed.p, q:positiveZneg p + Zpos q = Z.pos_sub q pp, q:positiveZpos p + Zpos q = Zpos (p + q)reflexivity. Qed.p, q:positiveZpos p + Zpos q = Zpos (p + q)n:Zp:positive(n | Zpos p) <-> (n | Zneg p)apply Z.divide_Zpos_Zneg_r. Qed.n:Zp:positive(n | Zpos p) <-> (n | Zneg p)n:Zp:positive(Zpos p | n) <-> (Zneg p | n)apply Z.divide_Zpos_Zneg_l. Qed.n:Zp:positive(Zpos p | n) <-> (Zneg p | n)a:positiven:Z0 <= n -> Z.testbit (Zneg a) n = negb (N.testbit (Pos.pred_N a) (Z.to_N n))apply Z.testbit_Zneg. Qed.a:positiven:Z0 <= n -> Z.testbit (Zneg a) n = negb (N.testbit (Pos.pred_N a) (Z.to_N n))a:positiven:Z0 <= n -> Z.testbit (Zpos a) n = N.testbit (N.pos a) (Z.to_N n)apply Z.testbit_Zpos. Qed. End Pos2Z. Module Z2Pos.a:positiven:Z0 <= n -> Z.testbit (Zpos a) n = N.testbit (N.pos a) (Z.to_N n)x:Z0 < x -> Zpos (Z.to_pos x) = xnow destruct x. Qed.x:Z0 < x -> Zpos (Z.to_pos x) = xx, y:Z0 < x -> 0 < y -> Z.to_pos x = Z.to_pos y -> x = yx, y:Z0 < x -> 0 < y -> Z.to_pos x = Z.to_pos y -> x = yp:positivey:Z0 < Zpos p -> 0 < y -> p = Z.to_pos y -> Zpos p = ynow apply id. Qed.y:ZH:0 < yZpos (Z.to_pos y) = yx, y:Z0 < x -> 0 < y -> Z.to_pos x = Z.to_pos y <-> x = yx, y:Z0 < x -> 0 < y -> Z.to_pos x = Z.to_pos y <-> x = yx, y:ZH:0 < xH0:0 < yZ.to_pos x = Z.to_pos y -> x = yx, y:ZH:0 < xH0:0 < yx = y -> Z.to_pos x = Z.to_pos yintros; now f_equal. Qed.x, y:ZH:0 < xH0:0 < yx = y -> Z.to_pos x = Z.to_pos yx:Zx <= 0 -> Z.to_pos x = 1%positivex:Zx <= 0 -> Z.to_pos x = 1%positivenow destruct 1. Qed.p:positiveZpos p <= 0 -> Z.to_pos (Zpos p) = 1%positiveZ.to_pos 1 = 1%positivereflexivity. Qed.Z.to_pos 1 = 1%positivex:Z0 < x -> Z.to_pos (Z.double x) = ((Z.to_pos x)~0)%positivenow destruct x. Qed.x:Z0 < x -> Z.to_pos (Z.double x) = ((Z.to_pos x)~0)%positivex:Z0 < x -> Z.to_pos (Z.succ_double x) = ((Z.to_pos x)~1)%positivenow destruct x. Qed.x:Z0 < x -> Z.to_pos (Z.succ_double x) = ((Z.to_pos x)~1)%positivex:Z0 < x -> Z.to_pos (Z.succ x) = Pos.succ (Z.to_pos x)x:Z0 < x -> Z.to_pos (Z.succ x) = Pos.succ (Z.to_pos x)p:positive0 < Zpos p -> Z.to_pos (Z.succ (Zpos p)) = Pos.succ (Z.to_pos (Zpos p))now rewrite Pos.add_1_r. Qed.p:positive0 < Zpos p -> (p + 1)%positive = Pos.succ px, y:Z0 < x -> 0 < y -> Z.to_pos (x + y) = (Z.to_pos x + Z.to_pos y)%positivedestruct x; easy || now destruct y. Qed.x, y:Z0 < x -> 0 < y -> Z.to_pos (x + y) = (Z.to_pos x + Z.to_pos y)%positivex, y:Z0 < x < y -> Z.to_pos (y - x) = (Z.to_pos y - Z.to_pos x)%positivex, y:Z0 < x < y -> Z.to_pos (y - x) = (Z.to_pos y - Z.to_pos x)%positivep:positivey:Z0 < Zpos p < y -> Z.to_pos (y - Zpos p) = (Z.to_pos y - Z.to_pos (Zpos p))%positivep, p0:positive0 < Zpos p < Zpos p0 -> Z.to_pos (Zpos p0 - Zpos p) = (Z.to_pos (Zpos p0) - Z.to_pos (Zpos p))%positivep, p0:positive0 < Zpos p < Zpos p0 -> Z.to_pos (Z.pos_sub p0 p) = (p0 - p)%positivenow rewrite Z.pos_sub_gt. Qed.p, p0:positiveH:0 < Zpos p < Zpos p0Z.to_pos (Z.pos_sub p0 p) = (p0 - p)%positivex:Z1 < x -> Z.to_pos (Z.pred x) = Pos.pred (Z.to_pos x)now destruct x as [|[x|x|]|]. Qed.x:Z1 < x -> Z.to_pos (Z.pred x) = Pos.pred (Z.to_pos x)x, y:Z0 < x -> 0 < y -> Z.to_pos (x * y) = (Z.to_pos x * Z.to_pos y)%positivedestruct x; easy || now destruct y. Qed.x, y:Z0 < x -> 0 < y -> Z.to_pos (x * y) = (Z.to_pos x * Z.to_pos y)%positivex, y:Z0 < x -> 0 < y -> Z.to_pos (x ^ y) = (Z.to_pos x ^ Z.to_pos y)%positivex, y:Z0 < x -> 0 < y -> Z.to_pos (x ^ y) = (Z.to_pos x ^ Z.to_pos y)%positivex, y:ZH:0 < xH0:0 < yZ.to_pos (x ^ y) = (Z.to_pos x ^ Z.to_pos y)%positivex, y:ZH:0 < xH0:0 < yZpos (Z.to_pos (x ^ y)) = Zpos (Z.to_pos x ^ Z.to_pos y)x, y:ZH:0 < xH0:0 < y0 < x ^ yx, y:ZH:0 < xH0:0 < y0 < xx, y:ZH:0 < xH0:0 < y0 <= ynow apply Z.lt_le_incl. Qed.x, y:ZH:0 < xH0:0 < y0 <= yx:Zp:positive0 < x -> Z.to_pos (Z.pow_pos x p) = (Z.to_pos x ^ p)%positivex:Zp:positive0 < x -> Z.to_pos (Z.pow_pos x p) = (Z.to_pos x ^ p)%positivenow apply (inj_pow x (Z.pos p)). Qed.x:Zp:positiveH:0 < xZ.to_pos (Z.pow_pos x p) = (Z.to_pos x ^ p)%positivex, y:Z0 < x -> 0 < y -> (x ?= y) = (Z.to_pos x ?= Z.to_pos y)%positivedestruct x; easy || now destruct y. Qed.x, y:Z0 < x -> 0 < y -> (x ?= y) = (Z.to_pos x ?= Z.to_pos y)%positivex, y:Z0 < x -> 0 < y -> (x <=? y) = (Z.to_pos x <=? Z.to_pos y)%positivedestruct x; easy || now destruct y. Qed.x, y:Z0 < x -> 0 < y -> (x <=? y) = (Z.to_pos x <=? Z.to_pos y)%positivex, y:Z0 < x -> 0 < y -> (x <? y) = (Z.to_pos x <? Z.to_pos y)%positivedestruct x; easy || now destruct y. Qed.x, y:Z0 < x -> 0 < y -> (x <? y) = (Z.to_pos x <? Z.to_pos y)%positivex, y:Z0 < x -> 0 < y -> (x =? y) = (Z.to_pos x =? Z.to_pos y)%positivedestruct x; easy || now destruct y. Qed.x, y:Z0 < x -> 0 < y -> (x =? y) = (Z.to_pos x =? Z.to_pos y)%positivex, y:ZZ.to_pos (Z.max x y) = Pos.max (Z.to_pos x) (Z.to_pos y)x, y:ZZ.to_pos (Z.max x y) = Pos.max (Z.to_pos x) (Z.to_pos y)y:ZZ.to_pos (Z.max 0 y) = Z.to_pos yp:positivey:ZZ.to_pos (Z.max (Zpos p) y) = Pos.max p (Z.to_pos y)p:positivey:ZZ.to_pos (Z.max (Zneg p) y) = Z.to_pos ynow destruct y.y:ZZ.to_pos (Z.max 0 y) = Z.to_pos ydestruct y; simpl; now rewrite ?Pos.max_1_r, <- ?Pos2Z.inj_max.p:positivey:ZZ.to_pos (Z.max (Zpos p) y) = Pos.max p (Z.to_pos y)p:positivey:ZZ.to_pos (Z.max (Zneg p) y) = Z.to_pos yp, p0:positiveZ.to_pos (Z.max (Zneg p) (Zneg p0)) = 1%positivenow apply Z.max_lub. Qed.p, p0:positiveZ.max (Zneg p) (Zneg p0) <= 0x, y:ZZ.to_pos (Z.min x y) = Pos.min (Z.to_pos x) (Z.to_pos y)x, y:ZZ.to_pos (Z.min x y) = Pos.min (Z.to_pos x) (Z.to_pos y)y:ZZ.to_pos (Z.min 0 y) = 1%positivep:positivey:ZZ.to_pos (Z.min (Zpos p) y) = Pos.min p (Z.to_pos y)p:positivey:ZZ.to_pos (Z.min (Zneg p) y) = 1%positivenow destruct y.y:ZZ.to_pos (Z.min 0 y) = 1%positivedestruct y; simpl; now rewrite ?Pos.min_1_r, <- ?Pos2Z.inj_min.p:positivey:ZZ.to_pos (Z.min (Zpos p) y) = Pos.min p (Z.to_pos y)p:positivey:ZZ.to_pos (Z.min (Zneg p) y) = 1%positivep, p0:positiveZ.to_pos (Z.min (Zneg p) (Zneg p0)) = 1%positivep, p0:positiveZ.min (Zneg p) (Zneg p0) <= 0now left. Qed.p, p0:positiveZneg p <= 0 \/ Zneg p0 <= 0x:ZZ.to_pos (Z.sqrt x) = Pos.sqrt (Z.to_pos x)now destruct x. Qed.x:ZZ.to_pos (Z.sqrt x) = Pos.sqrt (Z.to_pos x)x, y:Z0 < x -> 0 < y -> Z.to_pos (Z.gcd x y) = Pos.gcd (Z.to_pos x) (Z.to_pos y)destruct x; easy || now destruct y. Qed. End Z2Pos.x, y:Z0 < x -> 0 < y -> Z.to_pos (Z.gcd x y) = Pos.gcd (Z.to_pos x) (Z.to_pos y)
Compatibility Notations
Notation Zdouble_plus_one := Z.succ_double (only parsing). Notation Zdouble_minus_one := Z.pred_double (only parsing). Notation ZPminus := Z.pos_sub (only parsing). Notation Zplus := Z.add (only parsing). (* Slightly incompatible *) Notation Zminus := Z.sub (only parsing). Notation Zmult := Z.mul (only parsing). Notation Z_of_nat := Z.of_nat (only parsing). Notation Z_of_N := Z.of_N (only parsing). Notation Zind := Z.peano_ind (only parsing). Notation Zplus_0_l := Z.add_0_l (only parsing). Notation Zplus_0_r := Z.add_0_r (only parsing). Notation Zplus_comm := Z.add_comm (only parsing). Notation Zopp_plus_distr := Z.opp_add_distr (only parsing). Notation Zplus_opp_r := Z.add_opp_diag_r (only parsing). Notation Zplus_opp_l := Z.add_opp_diag_l (only parsing). Notation Zplus_assoc := Z.add_assoc (only parsing). Notation Zplus_permute := Z.add_shuffle3 (only parsing). Notation Zplus_reg_l := Z.add_reg_l (only parsing). Notation Zplus_succ_l := Z.add_succ_l (only parsing). Notation Zplus_succ_comm := Z.add_succ_comm (only parsing). Notation Zsucc_discr := Z.neq_succ_diag_r (only parsing). Notation Zsucc'_discr := Z.neq_succ_diag_r (only parsing). Notation Zminus_0_r := Z.sub_0_r (only parsing). Notation Zminus_diag := Z.sub_diag (only parsing). Notation Zminus_plus_distr := Z.sub_add_distr (only parsing). Notation Zminus_succ_r := Z.sub_succ_r (only parsing). Notation Zminus_plus := Z.add_simpl_l (only parsing). Notation Zmult_0_l := Z.mul_0_l (only parsing). Notation Zmult_0_r := Z.mul_0_r (only parsing). Notation Zmult_1_l := Z.mul_1_l (only parsing). Notation Zmult_1_r := Z.mul_1_r (only parsing). Notation Zmult_comm := Z.mul_comm (only parsing). Notation Zmult_assoc := Z.mul_assoc (only parsing). Notation Zmult_permute := Z.mul_shuffle3 (only parsing). Notation Zmult_1_inversion_l := Z.mul_eq_1 (only parsing). Notation Zdouble_mult := Z.double_spec (only parsing). Notation Zdouble_plus_one_mult := Z.succ_double_spec (only parsing). Notation Zopp_mult_distr_l_reverse := Z.mul_opp_l (only parsing). Notation Zmult_opp_opp := Z.mul_opp_opp (only parsing). Notation Zmult_opp_comm := Z.mul_opp_comm (only parsing). Notation Zopp_eq_mult_neg_1 := Z.opp_eq_mul_m1 (only parsing). Notation Zmult_plus_distr_r := Z.mul_add_distr_l (only parsing). Notation Zmult_plus_distr_l := Z.mul_add_distr_r (only parsing). Notation Zmult_minus_distr_r := Z.mul_sub_distr_r (only parsing). Notation Zmult_reg_l := Z.mul_reg_l (only parsing). Notation Zmult_reg_r := Z.mul_reg_r (only parsing). Notation Zmult_succ_l := Z.mul_succ_l (only parsing). Notation Zmult_succ_r := Z.mul_succ_r (only parsing). Notation Zpos_xI := Pos2Z.inj_xI (only parsing). Notation Zpos_xO := Pos2Z.inj_xO (only parsing). Notation Zneg_xI := Pos2Z.neg_xI (only parsing). Notation Zneg_xO := Pos2Z.neg_xO (only parsing). Notation Zopp_neg := Pos2Z.opp_neg (only parsing). Notation Zpos_succ_morphism := Pos2Z.inj_succ (only parsing). Notation Zpos_mult_morphism := Pos2Z.inj_mul (only parsing). Notation Zpos_minus_morphism := Pos2Z.inj_sub (only parsing). Notation Zpos_eq_rev := Pos2Z.inj (only parsing). Notation Zpos_plus_distr := Pos2Z.inj_add (only parsing). Notation Zneg_plus_distr := Pos2Z.add_neg_neg (only parsing). Notation Z := Z (only parsing). Notation Z_rect := Z_rect (only parsing). Notation Z_rec := Z_rec (only parsing). Notation Z_ind := Z_ind (only parsing). Notation Z0 := Z0 (only parsing). Notation Zpos := Zpos (only parsing). Notation Zneg := Zneg (only parsing).
Compatibility lemmas. These could be notations,
but scope information would be lost.
Notation SYM1 lem := (fun n => eq_sym (lem n)). Notation SYM2 lem := (fun n m => eq_sym (lem n m)). Notation SYM3 lem := (fun n m p => eq_sym (lem n m p)).Proof (SYM3 Z.add_assoc).forall n m p : BinNums.Z, n + m + p = n + (m + p)Proof (SYM2 Z.add_succ_r). Notation Zplus_succ_r := Zplus_succ_r_reverse (only parsing).forall n m : BinNums.Z, Z.succ (n + m) = n + Z.succ mProof (SYM1 Z.add_0_r).forall n : BinNums.Z, n = n + 0Proof (f_equal2 Z.add).forall n m p q : BinNums.Z, n = m -> p = q -> n + p = m + qProof (SYM1 Z.succ_pred).forall n : BinNums.Z, n = Z.succ (Z.pred n)Proof (SYM1 Z.pred_succ).forall n : BinNums.Z, n = Z.pred (Z.succ n)Proof (f_equal Z.succ).forall n m : BinNums.Z, n = m -> Z.succ n = Z.succ mProof (SYM1 Z.sub_0_r).forall n : BinNums.Z, n = n - 0Proof (SYM1 Z.sub_diag).forall n : BinNums.Z, 0 = n - nProof (SYM2 Z.sub_succ_l).forall n m : BinNums.Z, Z.succ (n - m) = Z.succ n - mforall n m p : BinNums.Z, n = m + p -> p = n - mforall n m p : BinNums.Z, n = m + p -> p = n - mnow apply Z.add_move_l. Qed.n, m, p:BinNums.ZH:n = m + pp = n - mProof (fun n m => eq_trans (Z.add_comm n (m-n)) (Z.sub_add n m)).forall n m : BinNums.Z, n + (m - n) = mProof (fun n m p => Z.add_add_simpl_l_l p n m).forall n m p : BinNums.Z, p + n - (p + m) = n - mProof (SYM3 Zminus_plus_simpl_l).forall n m p : BinNums.Z, n - m = p + n - (p + m)Proof (fun n m p => Z.add_add_simpl_r_r n p m).forall n m p : BinNums.Z, n + p - (m + p) = n - mProof (fun n m => proj2 (Z.sub_move_0_r n m)).forall n m : BinNums.Z, n = m -> n - m = 0Proof (fun n m => proj1 (Z.sub_move_0_r n m)).forall n m : BinNums.Z, n - m = 0 -> n = mProof (SYM1 Z.mul_0_r).forall n : BinNums.Z, 0 = n * 0Proof (SYM3 Z.mul_assoc).forall n m p : BinNums.Z, n * m * p = n * (m * p)Proof (fun n m => proj1 (Z.mul_eq_0 n m)).forall n m : BinNums.Z, n * m = 0 -> n = 0 \/ m = 0Proof (fun n m H H' => Z.mul_eq_0_l m n H' H).forall n m : BinNums.Z, n <> 0 -> m * n = 0 -> m = 0Proof (SYM2 Z.mul_opp_l).forall n m : BinNums.Z, - (n * m) = - n * mProof (SYM2 Z.mul_opp_r).forall n m : BinNums.Z, - (n * m) = n * - mProof (fun n m p => Z.mul_sub_distr_l p n m).forall n m p : BinNums.Z, p * (n - m) = p * n - p * mProof (SYM2 Z.mul_succ_r).forall n m : BinNums.Z, n * m + n = n * Z.succ mProof (SYM2 Z.mul_succ_l).forall n m : BinNums.Z, n * m + m = Z.succ n * mforall p q : positive, p = q -> BinNums.Zpos p = BinNums.Zpos qcongruence. Qed.forall p q : positive, p = q -> BinNums.Zpos p = BinNums.Zpos qProof (fun p q => iff_sym (Pos2Z.inj_iff p q)). Hint Immediate Zsucc_pred: zarith. (* Not kept : Zplus_0_simpl_l Zplus_0_simpl_l_reverse Zplus_opp_expand Zsucc_inj_contrapositive Zsucc_succ' Zpred_pred' *) (* No compat notation for : weak_assoc (now Z.add_assoc_pos) weak_Zmult_plus_distr_r (now Z.mul_add_distr_pos) *)forall p q : positive, p = q <-> BinNums.Zpos p = BinNums.Zpos q
Obsolete stuff
Definition Zne (x y:Z) := x <> y. (* TODO : to remove someday ? *) Register Zne as plugins.omega.Zne. Ltac elim_compare com1 com2 := case (Dcompare (com1 ?= com2)%Z); [ idtac | let x := fresh "H" in (intro x; case x; clear x) ].2%nat = (1 + 1)%natreflexivity. Qed.2%nat = (1 + 1)%natn:BinNums.Zn + n = n * 2n:BinNums.Zn + n = n * 2apply Z.add_diag. Qed.n:BinNums.Zn + n = 2 * nn, m:BinNums.Zm = 0 -> m * n = 0intros; now subst. Qed.n, m:BinNums.Zm = 0 -> m * n = 0