Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) Require Export ZArith. Require Export ZArithRing. Require Export Morphisms Setoid Bool.
Rationals are pairs of Z and positive numbers.
Record Q : Set := Qmake {Qnum : Z; Qden : positive}. Declare Scope Q_scope. Delimit Scope Q_scope with Q. Bind Scope Q_scope with Q. Arguments Qmake _%Z _%positive. Open Scope Q_scope. Ltac simpl_mult := rewrite ?Pos2Z.inj_mul.
a#b denotes the fraction a over b.
Notation "a # b" := (Qmake a b) (at level 55, no associativity) : Q_scope. Definition of_decimal (d:Decimal.decimal) : Q := let '(i, f, e) := match d with | Decimal.Decimal i f => (i, f, Decimal.Pos Decimal.Nil) | Decimal.DecimalExp i f e => (i, f, e) end in let num := Z.of_int (Decimal.app_int i f) in let e := Z.sub (Z.of_int e) (Z.of_nat (Decimal.nb_digits f)) in match e with | Z0 => Qmake num 1 | Zpos e => Qmake (Pos.iter (Z.mul 10) num e) 1 | Zneg e => Qmake num (Pos.iter (Pos.mul 10) 1%positive e) end. Definition to_decimal (q:Q) : option Decimal.decimal := let num := Z.to_int (Qnum q) in let (den, e_den) := Decimal.nztail (Pos.to_uint (Qden q)) in match den with | Decimal.D1 Decimal.Nil => match Z.of_nat e_den with | Z0 => Some (Decimal.Decimal num Decimal.Nil) | e => Some (Decimal.DecimalExp num Decimal.Nil (Z.to_int (Z.opp e))) end | _ => None end. Numeral Notation Q of_decimal to_decimal : Q_scope. Definition inject_Z (x : Z) := Qmake x 1. Arguments inject_Z x%Z. Notation QDen p := (Zpos (Qden p)). Definition Qeq (p q : Q) := (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z. Definition Qle (x y : Q) := (Qnum x * QDen y <= Qnum y * QDen x)%Z. Definition Qlt (x y : Q) := (Qnum x * QDen y < Qnum y * QDen x)%Z. Notation Qgt a b := (Qlt b a) (only parsing). Notation Qge a b := (Qle b a) (only parsing). Infix "==" := Qeq (at level 70, no associativity) : Q_scope. Infix "<" := Qlt : Q_scope. Infix "<=" := Qle : Q_scope. Notation "x > y" := (Qlt y x)(only parsing) : Q_scope. Notation "x >= y" := (Qle y x)(only parsing) : Q_scope. Notation "x <= y <= z" := (x<=y/\y<=z) : Q_scope.
injection from Z is injective.
a, b:Zinject_Z a == inject_Z b <-> a = ba, b:Zinject_Z a == inject_Z b <-> a = ba, b:Z(Qnum (inject_Z a) * QDen (inject_Z b))%Z = (Qnum (inject_Z b) * QDen (inject_Z a))%Z <-> a = bomega. Qed.a, b:Z(a * 1)%Z = (b * 1)%Z <-> a = b
Another approach : using Qcompare for defining order relations.
Definition Qcompare (p q : Q) := (Qnum p * QDen q ?= Qnum q * QDen p)%Z. Notation "p ?= q" := (Qcompare p q) : Q_scope.p, q:Qp == q <-> (p ?= q) = Eqp, q:Qp == q <-> (p ?= q) = Eqapply Z.compare_eq_iff. Qed.p, q:Q(p ?= q) = Eq <-> p == qp, q:Qp < q <-> (p ?= q) = Ltreflexivity. Qed.p, q:Qp < q <-> (p ?= q) = Ltp, q:Qq < p <-> (p ?= q) = Gtp, q:Qq < p <-> (p ?= q) = Gtapply Z.gt_lt_iff. Qed.p, q:Q(p ?= q) = Gt <-> q < pp, q:Qp <= q <-> (p ?= q) <> Gtreflexivity. Qed.p, q:Qp <= q <-> (p ?= q) <> Gtp, q:Qq <= p <-> (p ?= q) <> Ltp, q:Qq <= p <-> (p ?= q) <> Ltapply Z.ge_le_iff. Qed. Hint Unfold Qeq Qlt Qle : qarith. Hint Extern 5 (?X1 <> ?X2) => intro; discriminate: qarith.p, q:Q(p ?= q) <> Lt <-> q <= px, y:QCompOpp (x ?= y) = (y ?= x)x, y:QCompOpp (x ?= y) = (y ?= x)apply Z.compare_antisym. Qed.x, y:Q(y ?= x) = CompOpp (x ?= y)x, y:QCompareSpec (x == y) (x < y) (y < x) (x ?= y)x, y:QCompareSpec (x == y) (x < y) (y < x) (x ?= y)case Z.compare_spec; now constructor. Qed.x, y:QCompareSpec ((Qnum x * QDen y)%Z = (Qnum y * QDen x)%Z) (Qnum x * QDen y < Qnum y * QDen x)%Z (Qnum y * QDen x < Qnum x * QDen y)%Z (Qnum x * QDen y ?= Qnum y * QDen x)%Z
x:Qx == xauto with qarith. Qed.x:Qx == xx, y:Qx == y -> y == xauto with qarith. Qed.x, y:Qx == y -> y == xx, y, z:Qx == y -> y == z -> x == zx, y, z:Qx == y -> y == z -> x == zx, y, z:QXY:(Qnum x * QDen y)%Z = (Qnum y * QDen x)%ZYZ:(Qnum y * QDen z)%Z = (Qnum z * QDen y)%Z(Qnum x * QDen z)%Z = (Qnum z * QDen x)%Znow rewrite Z.mul_shuffle0, XY, Z.mul_shuffle0, YZ, Z.mul_shuffle0. Qed. Hint Immediate Qeq_sym : qarith. Hint Resolve Qeq_refl Qeq_trans : qarith.x, y, z:QXY:(Qnum x * QDen y)%Z = (Qnum y * QDen x)%ZYZ:(Qnum y * QDen z)%Z = (Qnum z * QDen y)%Z(Qnum x * QDen z * QDen y)%Z = (Qnum z * QDen x * QDen y)%Z
In a word, Qeq is a setoid equality.
Equivalence Qeqsplit; red; eauto with qarith. Qed.Equivalence Qeq
Furthermore, this equality is decidable:
x, y:Q{x == y} + {~ x == y}apply Z.eq_dec. Defined. Definition Qeq_bool x y := (Zeq_bool (Qnum x * QDen y) (Qnum y * QDen x))%Z. Definition Qle_bool x y := (Z.leb (Qnum x * QDen y) (Qnum y * QDen x))%Z.x, y:Q{x == y} + {~ x == y}x, y:QQeq_bool x y = true <-> x == ysymmetry; apply Zeq_is_eq_bool. Qed.x, y:QQeq_bool x y = true <-> x == yx, y:QQeq_bool x y = true -> x == yapply Qeq_bool_iff. Qed.x, y:QQeq_bool x y = true -> x == yx, y:Qx == y -> Qeq_bool x y = trueapply Qeq_bool_iff. Qed.x, y:Qx == y -> Qeq_bool x y = truex, y:QQeq_bool x y = false -> ~ x == yx, y:QQeq_bool x y = false -> ~ x == ynow intros ->. Qed.x, y:QQeq_bool x y = false -> Qeq_bool x y <> truex, y:QQle_bool x y = true <-> x <= ysymmetry; apply Zle_is_le_bool. Qed.x, y:QQle_bool x y = true <-> x <= yx, y:QQle_bool x y = true -> x <= yapply Qle_bool_iff. Qed.x, y:QQle_bool x y = true -> x <= yx, y:Q~ x == y -> ~ y == xauto with qarith. Qed.x, y:Q~ x == y -> ~ y == xx, y:QQeq_bool x y = Qeq_bool y xx, y:QQeq_bool x y = Qeq_bool y xx, y:QQeq_bool x y = true <-> Qeq_bool y x = truenow symmetry. Qed.x, y:Qx == y <-> y == xx:QQeq_bool x x = truex:QQeq_bool x x = truenow reflexivity. Qed.x:Qx == xx, y:QQeq_bool x y = true -> Qeq_bool y x = truex, y:QQeq_bool x y = true -> Qeq_bool y x = truenow symmetry. Qed.x, y:Qx == y -> y == xx, y, z:QQeq_bool x y = true -> Qeq_bool y z = true -> Qeq_bool x z = truerewrite !Qeq_bool_iff; apply Qeq_trans. Qed. Hint Resolve Qnot_eq_sym : qarith.x, y, z:QQeq_bool x y = true -> Qeq_bool y z = true -> Qeq_bool x z = true
The addition, multiplication and opposite are defined
in the straightforward way:
Definition Qplus (x y : Q) := (Qnum x * QDen y + Qnum y * QDen x) # (Qden x * Qden y). Definition Qmult (x y : Q) := (Qnum x * Qnum y) # (Qden x * Qden y). Definition Qopp (x : Q) := (- Qnum x) # (Qden x). Definition Qminus (x y : Q) := Qplus x (Qopp y). Definition Qinv (x : Q) := match Qnum x with | Z0 => 0 | Zpos p => (QDen x)#p | Zneg p => (Zneg (Qden x))#p end. Definition Qdiv (x y : Q) := Qmult x (Qinv y). Infix "+" := Qplus : Q_scope. Notation "- x" := (Qopp x) : Q_scope. Infix "-" := Qminus : Q_scope. Infix "*" := Qmult : Q_scope. Notation "/ x" := (Qinv x) : Q_scope. Infix "/" := Qdiv : Q_scope.
A light notation for Zpos
a:Zb:positivea # b == inject_Z a / inject_Z (Z.pos b)a:Zb:positivea # b == inject_Z a / inject_Z (Z.pos b)a:Zb:positive(Qnum (a # b) * QDen (inject_Z a / inject_Z (Z.pos b)))%Z = (Qnum (inject_Z a / inject_Z (Z.pos b)) * QDen (a # b))%Zring. Qed.a:Zb:positive(a * Z.pos b)%Z = (a * 1 * Z.pos b)%Z
Proper (Qeq ==> Qeq ==> Qeq) QplusProper (Qeq ==> Qeq ==> Qeq) QplusProper ((fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z) ==> (fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z) ==> (fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z)) (fun x y : Q => Qnum x * QDen y + Qnum y * QDen x # Qden x * Qden y)Proper ((fun p q : Q => Qnum p * QDen q = Qnum q * QDen p) ==> (fun p q : Q => Qnum p * QDen q = Qnum q * QDen p) ==> (fun p q : Q => Qnum p * QDen q = Qnum q * QDen p)) (fun x y : Q => Qnum x * QDen y + Qnum y * QDen x # Qden x * Qden y)p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2(p1 * Z.pos r2 + r1 * Z.pos p2) * Z.pos (q2 * s2) = (q1 * Z.pos s2 + s1 * Z.pos q2) * Z.pos (p2 * r2)p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2p1 * Z.pos r2 * Z.pos q2 * Z.pos s2 + r1 * Z.pos p2 * Z.pos q2 * Z.pos s2 = Z.pos r2 * Z.pos p2 * Z.pos q2 * s1 + Z.pos r2 * Z.pos p2 * Z.pos s2 * q1p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2p1 * Z.pos q2 * Z.pos r2 * Z.pos s2 + r1 * Z.pos p2 * Z.pos q2 * Z.pos s2 = Z.pos r2 * Z.pos p2 * Z.pos q2 * s1 + Z.pos r2 * Z.pos p2 * Z.pos s2 * q1p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2q1 * Z.pos p2 * Z.pos r2 * Z.pos s2 + r1 * Z.pos p2 * Z.pos q2 * Z.pos s2 = Z.pos r2 * Z.pos p2 * Z.pos q2 * s1 + Z.pos r2 * Z.pos p2 * Z.pos s2 * q1p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2q1 * Z.pos p2 * Z.pos r2 * Z.pos s2 + r1 * Z.pos s2 * Z.pos p2 * Z.pos q2 = Z.pos r2 * Z.pos p2 * Z.pos q2 * s1 + Z.pos r2 * Z.pos p2 * Z.pos s2 * q1ring. Close Scope Z_scope. Qed.p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2q1 * Z.pos p2 * Z.pos r2 * Z.pos s2 + s1 * Z.pos r2 * Z.pos p2 * Z.pos q2 = Z.pos r2 * Z.pos p2 * Z.pos q2 * s1 + Z.pos r2 * Z.pos p2 * Z.pos s2 * q1Proper (Qeq ==> Qeq) QoppProper (Qeq ==> Qeq) QoppProper ((fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z) ==> (fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z)) (fun x : Q => - Qnum x # Qden x)Proper ((fun p q : Q => Qnum p * QDen q = Qnum q * QDen p) ==> (fun p q : Q => Qnum p * QDen q = Qnum q * QDen p)) (fun x : Q => - Qnum x # Qden x)x, y:QH:Qnum x * QDen y = Qnum y * QDen x- Qnum x * QDen y = - Qnum y * QDen xrewrite H; ring. Close Scope Z_scope. Qed.x, y:QH:Qnum x * QDen y = Qnum y * QDen x- (Qnum x * QDen y) = - Qnum y * QDen xProper (Qeq ==> Qeq ==> Qeq) QminusProper (Qeq ==> Qeq ==> Qeq) Qminusx, x':QHx:x == x'y, y':QHy:y == y'x - y == x' - y'rewrite Hx, Hy; auto with qarith. Qed.x, x':QHx:x == x'y, y':QHy:y == y'x + - y == x' + - y'Proper (Qeq ==> Qeq ==> Qeq) QmultProper (Qeq ==> Qeq ==> Qeq) QmultProper ((fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z) ==> (fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z) ==> (fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z)) QmultProper ((fun p q : Q => Qnum p * QDen q = Qnum q * QDen p) ==> (fun p q : Q => Qnum p * QDen q = Qnum q * QDen p) ==> (fun p q : Q => Qnum p * QDen q = Qnum q * QDen p)) Qmultp1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2p1 * r1 * Z.pos (q2 * s2) = q1 * s1 * Z.pos (p2 * r2)p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2p1 * r1 * Z.pos q2 * Z.pos s2 = q1 * s1 * Z.pos p2 * Z.pos r2p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2p1 * r1 * Z.pos q2 * Z.pos s2 = q1 * Z.pos p2 * s1 * Z.pos r2p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2p1 * r1 * Z.pos q2 * Z.pos s2 = p1 * Z.pos q2 * s1 * Z.pos r2p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2r1 * Z.pos s2 * p1 * Z.pos q2 = p1 * Z.pos q2 * s1 * Z.pos r2ring. Close Scope Z_scope. Qed.p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH0:r1 * Z.pos s2 = s1 * Z.pos r2s1 * Z.pos r2 * p1 * Z.pos q2 = p1 * Z.pos q2 * s1 * Z.pos r2Proper (Qeq ==> Qeq) QinvProper (Qeq ==> Qeq) QinvProper ((fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z) ==> (fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z)) (fun x : Q => match Qnum x with | 0%Z => 0 | Z.pos p => QDen x # p | Z.neg p => Z.neg (Qden x) # p end)Proper ((fun p q : Q => Qnum p * QDen q = Qnum q * QDen p) ==> (fun p q : Q => Qnum p * QDen q = Qnum q * QDen p)) (fun x : Q => match Qnum x with | 0 => 0%Q | Z.pos p => QDen x # p | Z.neg p => Z.neg (Qden x) # p end)p1:Zp2:positiveq1:Zq2:positiveEQ:p1 * Z.pos q2 = q1 * Z.pos p2Qnum match p1 with | 0%Z => 0 | Z.pos p => Z.pos p2 # p | Z.neg p => Z.neg p2 # p end * QDen match q1 with | 0%Z => 0 | Z.pos p => Z.pos q2 # p | Z.neg p => Z.neg q2 # p end = Qnum match q1 with | 0%Z => 0 | Z.pos p => Z.pos q2 # p | Z.neg p => Z.neg q2 # p end * QDen match p1 with | 0%Z => 0 | Z.pos p => Z.pos p2 # p | Z.neg p => Z.neg p2 # p endp1:Zp2, q2:positiveEQ:p1 * Z.pos q2 = 0Qnum match p1 with | 0%Z => 0 | Z.pos p => Z.pos p2 # p | Z.neg p => Z.neg p2 # p end * 1 = 0p1:Zp2, p, q2:positiveEQ:p1 * Z.pos q2 = Z.pos (p * p2)Qnum match p1 with | 0%Z => 0 | Z.pos p0 => Z.pos p2 # p0 | Z.neg p0 => Z.neg p2 # p0 end * Z.pos p = Z.pos (q2 * Qden match p1 with | 0%Z => 0 | Z.pos p0 => Z.pos p2 # p0 | Z.neg p0 => Z.neg p2 # p0 end)p1:Zp2, p, q2:positiveEQ:p1 * Z.pos q2 = Z.neg (p * p2)Qnum match p1 with | 0%Z => 0 | Z.pos p0 => Z.pos p2 # p0 | Z.neg p0 => Z.neg p2 # p0 end * Z.pos p = Z.neg (q2 * Qden match p1 with | 0%Z => 0 | Z.pos p0 => Z.pos p2 # p0 | Z.neg p0 => Z.neg p2 # p0 end)p1:Zp2, q2:positiveEQ:p1 * Z.pos q2 = 0Qnum match p1 with | 0%Z => 0 | Z.pos p => Z.pos p2 # p | Z.neg p => Z.neg p2 # p end * 1 = 0destruct EQ; now subst.p1:Zp2, q2:positiveEQ:p1 = 0 \/ Z.pos q2 = 0Qnum match p1 with | 0%Z => 0 | Z.pos p => Z.pos p2 # p | Z.neg p => Z.neg p2 # p end * 1 = 0p1:Zp2, p, q2:positiveEQ:p1 * Z.pos q2 = Z.pos (p * p2)Qnum match p1 with | 0%Z => 0 | Z.pos p0 => Z.pos p2 # p0 | Z.neg p0 => Z.neg p2 # p0 end * Z.pos p = Z.pos (q2 * Qden match p1 with | 0%Z => 0 | Z.pos p0 => Z.pos p2 # p0 | Z.neg p0 => Z.neg p2 # p0 end)now rewrite Pos.mul_comm, <- EQ, Pos.mul_comm.p0, p2, p, q2:positiveEQ:Z.pos (p0 * q2) = Z.pos (p * p2)Z.pos (p2 * p) = Z.pos (q2 * p0)p1:Zp2, p, q2:positiveEQ:p1 * Z.pos q2 = Z.neg (p * p2)Qnum match p1 with | 0%Z => 0 | Z.pos p0 => Z.pos p2 # p0 | Z.neg p0 => Z.neg p2 # p0 end * Z.pos p = Z.neg (q2 * Qden match p1 with | 0%Z => 0 | Z.pos p0 => Z.pos p2 # p0 | Z.neg p0 => Z.neg p2 # p0 end)now rewrite Pos.mul_comm, <- EQ, Pos.mul_comm. Close Scope Z_scope. Qed.p0, p2, p, q2:positiveEQ:Z.neg (p0 * q2) = Z.neg (p * p2)Z.neg (p2 * p) = Z.neg (q2 * p0)Proper (Qeq ==> Qeq ==> Qeq) QdivProper (Qeq ==> Qeq ==> Qeq) Qdivrewrite Hx, Hy; auto with qarith. Qed.x, x':QHx:x == x'y, y':QHy:y == y'x * / y == x' * / y'Proper (Qeq ==> Qeq ==> eq) QcompareProper (Qeq ==> Qeq ==> eq) QcompareProper ((fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z) ==> (fun p q : Q => (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z) ==> eq) (fun p q : Q => (Qnum p * QDen q ?= Qnum q * QDen p)%Z)Proper ((fun p q : Q => Qnum p * QDen q = Qnum q * QDen p) ==> (fun p q : Q => Qnum p * QDen q = Qnum q * QDen p) ==> eq) (fun p q : Q => Qnum p * QDen q ?= Qnum q * QDen p)p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH':r1 * Z.pos s2 = s1 * Z.pos r2(p1 * Z.pos r2 ?= r1 * Z.pos p2) = (q1 * Z.pos s2 ?= s1 * Z.pos q2)p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH':r1 * Z.pos s2 = s1 * Z.pos r2(Z.pos (q2 * s2) * (p1 * Z.pos r2) ?= Z.pos (q2 * s2) * (r1 * Z.pos p2)) = (q1 * Z.pos s2 ?= s1 * Z.pos q2)p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH':r1 * Z.pos s2 = s1 * Z.pos r2(Z.pos (q2 * s2) * (p1 * Z.pos r2) ?= Z.pos (q2 * s2) * (r1 * Z.pos p2)) = (Z.pos (p2 * r2) * (q1 * Z.pos s2) ?= Z.pos (p2 * r2) * (s1 * Z.pos q2))p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH':r1 * Z.pos s2 = s1 * Z.pos r2(Z.pos q2 * Z.pos s2 * (p1 * Z.pos r2) ?= Z.pos q2 * Z.pos s2 * (r1 * Z.pos p2)) = (Z.pos (p2 * r2) * (q1 * Z.pos s2) ?= Z.pos (p2 * r2) * (s1 * Z.pos q2))p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH':r1 * Z.pos s2 = s1 * Z.pos r2(Z.pos q2 * Z.pos s2 * (p1 * Z.pos r2) ?= Z.pos q2 * Z.pos s2 * (r1 * Z.pos p2)) = (Z.pos p2 * Z.pos r2 * (q1 * Z.pos s2) ?= Z.pos p2 * Z.pos r2 * (s1 * Z.pos q2))p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH':r1 * Z.pos s2 = s1 * Z.pos r2(p1 * Z.pos q2 * Z.pos r2 * Z.pos s2 ?= Z.pos q2 * Z.pos s2 * (r1 * Z.pos p2)) = (Z.pos p2 * Z.pos r2 * (q1 * Z.pos s2) ?= Z.pos p2 * Z.pos r2 * (s1 * Z.pos q2))p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH':r1 * Z.pos s2 = s1 * Z.pos r2(q1 * Z.pos p2 * Z.pos r2 * Z.pos s2 ?= Z.pos q2 * Z.pos s2 * (r1 * Z.pos p2)) = (Z.pos p2 * Z.pos r2 * (q1 * Z.pos s2) ?= Z.pos p2 * Z.pos r2 * (s1 * Z.pos q2))p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH':r1 * Z.pos s2 = s1 * Z.pos r2(q1 * Z.pos p2 * Z.pos r2 * Z.pos s2 ?= r1 * Z.pos s2 * Z.pos q2 * Z.pos p2) = (Z.pos p2 * Z.pos r2 * (q1 * Z.pos s2) ?= Z.pos p2 * Z.pos r2 * (s1 * Z.pos q2))f_equal; ring. Close Scope Z_scope. Qed.p1:Zp2:positiveq1:Zq2:positiveH:p1 * Z.pos q2 = q1 * Z.pos p2r1:Zr2:positives1:Zs2:positiveH':r1 * Z.pos s2 = s1 * Z.pos r2(q1 * Z.pos p2 * Z.pos r2 * Z.pos s2 ?= s1 * Z.pos r2 * Z.pos q2 * Z.pos p2) = (Z.pos p2 * Z.pos r2 * (q1 * Z.pos s2) ?= Z.pos p2 * Z.pos r2 * (s1 * Z.pos q2))Proper (Qeq ==> Qeq ==> iff) QleProper (Qeq ==> Qeq ==> iff) Qlerewrite 2 Qle_alt, H, H'; auto with *. Qed.p, q:QH:p == qr, s:QH':r == sp <= r <-> q <= sProper (Qeq ==> Qeq ==> iff) QltProper (Qeq ==> Qeq ==> iff) Qltrewrite 2 Qlt_alt, H, H'; auto with *. Qed.p, q:QH:p == qr, s:QH':r == sp < r <-> q < sProper (Qeq ==> Qeq ==> eq) Qeq_boolProper (Qeq ==> Qeq ==> eq) Qeq_boolrewrite 2 Qeq_bool_iff, H, H'; split; auto with qarith. Qed.p, q:QH:p == qr, s:QH':r == sQeq_bool p r = true <-> Qeq_bool q s = trueProper (Qeq ==> Qeq ==> eq) Qle_boolProper (Qeq ==> Qeq ==> eq) Qle_boolrewrite 2 Qle_bool_iff, H, H'; split; auto with qarith. Qed.p, q:QH:p == qr, s:QH':r == sQle_bool p r = true <-> Qle_bool q s = true
0 and 1 are apart
~ 1 == 0unfold Qeq; auto with qarith. Qed.~ 1 == 0
Addition is associative:
forall x y z : Q, x + (y + z) == x + y + zforall x y z : Q, x + (y + z) == x + y + zunfold Qeq, Qplus; simpl; simpl_mult; ring. Qed.x1:Zx2:positivey1:Zy2:positivez1:Zz2:positive(x1 # x2) + ((y1 # y2) + (z1 # z2)) == (x1 # x2) + (y1 # y2) + (z1 # z2)
0 is a neutral element for addition:
forall x : Q, 0 + x == xintros (x1, x2); unfold Qeq, Qplus; simpl; ring. Qed.forall x : Q, 0 + x == xforall x : Q, x + 0 == xforall x : Q, x + 0 == xrewrite Pos.mul_comm; simpl; ring. Qed.x1:Zx2:positive((x1 * 1 + 0) * Z.pos x2)%Z = (x1 * Z.pos (x2 * 1))%Z
Commutativity of addition:
forall x y : Q, x + y == y + xforall x y : Q, x + y == y + xintros; rewrite Pos.mul_comm; ring. Qed.x1:Zx2:positiveforall y : Q, ((x1 * QDen y + Qnum y * Z.pos x2) * Z.pos (Qden y * x2))%Z = ((Qnum y * Z.pos x2 + x1 * QDen y) * Z.pos (x2 * Qden y))%Z
forall q : Q, - - q == qred; simpl; intros; ring. Qed.forall q : Q, - - q == qforall q : Q, q + - q == 0red; simpl; intro; ring. Qed.forall q : Q, q + - q == 0
Injectivity of addition (uses theory about Qopp above):
x, y, z:Qx + z == y + z <-> x == yx, y, z:Qx + z == y + z <-> x == yx, y, z:QE:x + z == y + zx == yx, y, z:QE:x == yx + z == y + zx, y, z:QE:x + z == y + zx + 0 == y + 0x, y, z:QE:x == yx + z == y + zx, y, z:QE:x + z == y + zx + (z + - z) == y + (z + - z)x, y, z:QE:x == yx + z == y + zx, y, z:QE:x + z == y + zx + z + - z == y + z + - zx, y, z:QE:x == yx + z == y + zx, y, z:QE:x + z == y + zy + z + - z == y + z + - zx, y, z:QE:x == yx + z == y + zx, y, z:QE:x == yx + z == y + zreflexivity. Qed.x, y, z:QE:x == yy + z == y + zx, y, z:Qz + x == z + y <-> x == yx, y, z:Qz + x == z + y <-> x == yapply Qplus_inj_r. Qed.x, y, z:Qx + z == y + z <-> x == y
Multiplication is associative:
forall n m p : Q, n * (m * p) == n * m * pintros; red; simpl; rewrite Pos.mul_assoc; ring. Qed.forall n m p : Q, n * (m * p) == n * m * p
multiplication and zero
forall x : Q, 0 * x == 0intros; compute; reflexivity. Qed.forall x : Q, 0 * x == 0forall x : Q, x * 0 == 0intros; red; simpl; ring. Qed.forall x : Q, x * 0 == 0
1 is a neutral element for multiplication:
forall n : Q, 1 * n == nintro; red; simpl; destruct (Qnum n); auto. Qed.forall n : Q, 1 * n == nforall n : Q, n * 1 == nforall n : Q, n * 1 == nn:Q(Qnum n * 1 * QDen n)%Z = (Qnum n * Z.pos (Qden n * 1))%Zrewrite Pos.mul_comm; simpl; trivial. Qed.n:Q(Qnum n * QDen n)%Z = (Qnum n * Z.pos (Qden n * 1))%Z
Commutativity of multiplication
forall x y : Q, x * y == y * xintros; red; simpl; rewrite Pos.mul_comm; ring. Qed.forall x y : Q, x * y == y * x
Distributivity over Qadd
forall x y z : Q, x * (y + z) == x * y + x * zforall x y z : Q, x * (y + z) == x * y + x * zunfold Qeq, Qmult, Qplus; simpl; simpl_mult; ring. Qed.x1:Zx2:positivey1:Zy2:positivez1:Zz2:positive(x1 # x2) * ((y1 # y2) + (z1 # z2)) == (x1 # x2) * (y1 # y2) + (x1 # x2) * (z1 # z2)forall x y z : Q, (x + y) * z == x * z + y * zforall x y z : Q, (x + y) * z == x * z + y * zunfold Qeq, Qmult, Qplus; simpl; simpl_mult; ring. Qed.x1:Zx2:positivey1:Zy2:positivez1:Zz2:positive((x1 # x2) + (y1 # y2)) * (z1 # z2) == (x1 # x2) * (z1 # z2) + (y1 # y2) * (z1 # z2)
Integrality
forall x y : Q, x * y == 0 -> x == 0 \/ y == 0forall x y : Q, x * y == 0 -> x == 0 \/ y == 0x1:Zx2:positivey1:Zy2:positive(x1 # x2) * (y1 # y2) == 0 -> x1 # x2 == 0 \/ y1 # y2 == 0now rewrite <- Z.mul_eq_0, !Z.mul_1_r. Qed.x1:Zx2:positivey1:Zy2:positive(x1 * y1 * 1)%Z = 0%Z -> (x1 * 1)%Z = 0%Z \/ (y1 * 1)%Z = 0%Zforall x y : Q, ~ x == 0 -> x * y == 0 -> y == 0forall x y : Q, ~ x == 0 -> x * y == 0 -> y == 0x1:Zx2:positivey1:Zy2:positive~ x1 # x2 == 0 -> (x1 # x2) * (y1 # y2) == 0 -> y1 # y2 == 0x1:Zx2:positivey1:Zy2:positive(x1 * 1)%Z <> 0%Z -> (x1 * y1 * 1)%Z = 0%Z -> (y1 * 1)%Z = 0%Zintuition. Qed.x1:Zx2:positivey1:Zy2:positivex1 <> 0%Z -> x1 = 0%Z \/ y1 = 0%Z -> y1 = 0%Z
x, y:Zinject_Z (x + y) = inject_Z x + inject_Z yx, y:Zinject_Z (x + y) = inject_Z x + inject_Z yx, y:Zx + y # 1 = Qnum (x # 1) * QDen (y # 1) + Qnum (y # 1) * QDen (x # 1) # Qden (x # 1) * Qden (y # 1)x, y:Zx + y # 1 = x * 1 + y * 1 # 1ring. Qed.x, y:Z(x + y)%Z = (x * 1 + y * 1)%Zx, y:Zinject_Z (x * y) = inject_Z x * inject_Z yreflexivity. Qed.x, y:Zinject_Z (x * y) = inject_Z x * inject_Z yx:Zinject_Z (- x) = - inject_Z xreflexivity. Qed.x:Zinject_Z (- x) = - inject_Z x
forall q : Q, / / q == qintros [[|n|n] d]; red; simpl; reflexivity. Qed.forall q : Q, / / q == qforall x : Q, ~ x == 0 -> x * / x == 1forall x : Q, ~ x == 0 -> x * / x == 1elim H; auto. Qed.x1:Zx2:positiveH:0%Z <> 0%Z0%Z = (Z.pos x2 * 1)%Zforall p q : Q, / (p * q) == / p * / qforall p q : Q, / (p * q) == / p * / qdestruct x1; simpl; auto; destruct y1; simpl; auto. Qed.x1:Zx2:positivey1:Zy2:positive(Qnum match x1 * y1 with | 0%Z => 0 | Z.pos p => Z.pos (x2 * y2) # p | Z.neg p => Z.neg (x2 * y2) # p end * Z.pos (Qden match x1 with | 0%Z => 0 | Z.pos p => Z.pos x2 # p | Z.neg p => Z.neg x2 # p end * Qden match y1 with | 0%Z => 0 | Z.pos p => Z.pos y2 # p | Z.neg p => Z.neg y2 # p end))%Z = (Qnum match x1 with | 0%Z => 0 | Z.pos p => Z.pos x2 # p | Z.neg p => Z.neg x2 # p end * Qnum match y1 with | 0%Z => 0 | Z.pos p => Z.pos y2 # p | Z.neg p => Z.neg y2 # p end * QDen match x1 * y1 with | 0%Z => 0 | Z.pos p => Z.pos (x2 * y2) # p | Z.neg p => Z.neg (x2 * y2) # p end)%Zforall x y : Q, ~ y == 0 -> x * y / y == xforall x y : Q, ~ y == 0 -> x * y / y == xx, y:QH:~ y == 0x * y * / y == xx, y:QH:~ y == 0x * (y * / y) == xapply Qmult_1_r. Qed.x, y:QH:~ y == 0x * 1 == xforall x y : Q, ~ y == 0 -> y * (x / y) == xforall x y : Q, ~ y == 0 -> y * (x / y) == xx, y:QH:~ y == 0y * (x * / y) == xx, y:QH:~ y == 0y * x * / y == xx, y:QH:~ y == 0x * y * / y == xapply Qdiv_mult_l; auto. Qed.x, y:QH:~ y == 0x * y / y == x
Injectivity of Qmult (requires theory about Qinv above):
x, y, z:Q~ z == 0 -> x * z == y * z <-> x == yx, y, z:Q~ z == 0 -> x * z == y * z <-> x == yx, y, z:Qz_ne_0:~ z == 0x * z == y * z <-> x == yx, y, z:Qz_ne_0:~ z == 0E:x * z == y * zx == yx, y, z:Qz_ne_0:~ z == 0E:x == yx * z == y * zx, y, z:Qz_ne_0:~ z == 0E:x * z == y * zx * 1 == y * 1x, y, z:Qz_ne_0:~ z == 0E:x == yx * z == y * zx, y, z:Qz_ne_0:~ z == 0E:x * z == y * zx * (z * / z) == y * (z * / z)x, y, z:Qz_ne_0:~ z == 0E:x == yx * z == y * zx, y, z:Qz_ne_0:~ z == 0E:x * z == y * zx * z * / z == y * z * / zx, y, z:Qz_ne_0:~ z == 0E:x == yx * z == y * zx, y, z:Qz_ne_0:~ z == 0E:x * z == y * zy * z * / z == y * z * / zx, y, z:Qz_ne_0:~ z == 0E:x == yx * z == y * zx, y, z:Qz_ne_0:~ z == 0E:x == yx * z == y * zreflexivity. Qed.x, y, z:Qz_ne_0:~ z == 0E:x == yy * z == y * zx, y, z:Q~ z == 0 -> z * x == z * y <-> x == yx, y, z:Q~ z == 0 -> z * x == z * y <-> x == yapply Qmult_inj_r. Qed.x, y, z:Q~ z == 0 -> x * z == y * z <-> x == y
x:Qx <= xunfold Qle; auto with zarith. Qed.x:Qx <= xx, y:Qx <= y -> y <= x -> x == yunfold Qle, Qeq; auto with zarith. Qed.x, y:Qx <= y -> y <= x -> x == yforall x y z : Q, x <= y -> y <= z -> x <= zforall x y z : Q, x <= y -> y <= z -> x <= zx1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:(x1 * Z.pos y2 <= y1 * Z.pos x2)%ZH0:(y1 * Z.pos z2 <= z1 * Z.pos y2)%Z(x1 * Z.pos z2 <= z1 * Z.pos x2)%Zx1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2x1 * Z.pos z2 <= z1 * Z.pos x2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2x1 * Z.pos z2 * Z.pos y2 <= z1 * Z.pos x2 * Z.pos y2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2x1 * Z.pos z2 * Z.pos y2 <= y1 * Z.pos x2 * Z.pos z2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2y1 * Z.pos x2 * Z.pos z2 <= z1 * Z.pos x2 * Z.pos y2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2x1 * Z.pos z2 * Z.pos y2 <= y1 * Z.pos x2 * Z.pos z2now apply Z.mul_le_mono_pos_r.x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2x1 * Z.pos y2 * Z.pos z2 <= y1 * Z.pos x2 * Z.pos z2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2y1 * Z.pos x2 * Z.pos z2 <= z1 * Z.pos x2 * Z.pos y2now apply Z.mul_le_mono_pos_r. Close Scope Z_scope. Qed. Hint Resolve Qle_trans : qarith.x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2y1 * Z.pos z2 * Z.pos x2 <= z1 * Z.pos y2 * Z.pos x2x:Q~ x < xx:Q~ x < xauto with zarith. Qed.x:Q~ (Qnum x * QDen x < Qnum x * QDen x)%Zx, y:Qx < y -> ~ x == yunfold Qlt, Qeq; auto with zarith. Qed.x, y:Qx < y -> ~ x == yx, y:Z(x <= y)%Z = (inject_Z x <= inject_Z y)x, y:Z(x <= y)%Z = (inject_Z x <= inject_Z y)x, y:Z(x <= y)%Z = (Qnum (inject_Z x) * QDen (inject_Z y) <= Qnum (inject_Z y) * QDen (inject_Z x))%Znow rewrite !Z.mul_1_r. Qed.x, y:Z(x <= y)%Z = (x * 1 <= y * 1)%Zx, y:Z(x < y)%Z = (inject_Z x < inject_Z y)x, y:Z(x < y)%Z = (inject_Z x < inject_Z y)x, y:Z(x < y)%Z = (Qnum (inject_Z x) * QDen (inject_Z y) < Qnum (inject_Z y) * QDen (inject_Z x))%Znow rewrite !Z.mul_1_r. Qed.x, y:Z(x < y)%Z = (x * 1 < y * 1)%Z
Large = strict or equal
x, y:Qx <= y <-> x < y \/ x == yx, y:Qx <= y <-> x < y \/ x == ydestruct (x ?= y); intuition; discriminate. Qed.x, y:Q(x ?= y) <> Gt <-> (x ?= y) = Lt \/ (x ?= y) = Eqx, y:Qx < y -> x <= yunfold Qle, Qlt; auto with zarith. Qed.x, y:Qx < y -> x <= yforall x y z : Q, x <= y -> y < z -> x < zforall x y z : Q, x <= y -> y < z -> x < zx1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:(x1 * Z.pos y2 <= y1 * Z.pos x2)%ZH0:(y1 * Z.pos z2 < z1 * Z.pos y2)%Z(x1 * Z.pos z2 < z1 * Z.pos x2)%Zx1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 < z1 * Z.pos y2x1 * Z.pos z2 < z1 * Z.pos x2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 < z1 * Z.pos y2x1 * Z.pos z2 * Z.pos y2 < z1 * Z.pos x2 * Z.pos y2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 < z1 * Z.pos y2x1 * Z.pos z2 * Z.pos y2 <= y1 * Z.pos x2 * Z.pos z2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 < z1 * Z.pos y2y1 * Z.pos x2 * Z.pos z2 < z1 * Z.pos x2 * Z.pos y2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 < z1 * Z.pos y2x1 * Z.pos z2 * Z.pos y2 <= y1 * Z.pos x2 * Z.pos z2now apply Z.mul_le_mono_pos_r.x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 < z1 * Z.pos y2x1 * Z.pos y2 * Z.pos z2 <= y1 * Z.pos x2 * Z.pos z2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 < z1 * Z.pos y2y1 * Z.pos x2 * Z.pos z2 < z1 * Z.pos x2 * Z.pos y2now apply Z.mul_lt_mono_pos_r. Close Scope Z_scope. Qed.x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:y1 * Z.pos z2 < z1 * Z.pos y2y1 * Z.pos z2 * Z.pos x2 < z1 * Z.pos y2 * Z.pos x2forall x y z : Q, x < y -> y <= z -> x < zforall x y z : Q, x < y -> y <= z -> x < zx1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:(x1 * Z.pos y2 < y1 * Z.pos x2)%ZH0:(y1 * Z.pos z2 <= z1 * Z.pos y2)%Z(x1 * Z.pos z2 < z1 * Z.pos x2)%Zx1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2x1 * Z.pos z2 < z1 * Z.pos x2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2x1 * Z.pos z2 * Z.pos y2 < z1 * Z.pos x2 * Z.pos y2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2x1 * Z.pos z2 * Z.pos y2 < y1 * Z.pos x2 * Z.pos z2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2y1 * Z.pos x2 * Z.pos z2 <= z1 * Z.pos x2 * Z.pos y2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2x1 * Z.pos z2 * Z.pos y2 < y1 * Z.pos x2 * Z.pos z2now apply Z.mul_lt_mono_pos_r.x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2x1 * Z.pos y2 * Z.pos z2 < y1 * Z.pos x2 * Z.pos z2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2y1 * Z.pos x2 * Z.pos z2 <= z1 * Z.pos x2 * Z.pos y2now apply Z.mul_le_mono_pos_r. Close Scope Z_scope. Qed.x1:Zx2:positivey1:Zy2:positivez1:Zz2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:y1 * Z.pos z2 <= z1 * Z.pos y2y1 * Z.pos z2 * Z.pos x2 <= z1 * Z.pos y2 * Z.pos x2forall x y z : Q, x < y -> y < z -> x < zforall x y z : Q, x < y -> y < z -> x < zx, y, z:QH:x < yH0:y < zx < zapply Qlt_le_weak; auto. Qed.x, y, z:QH:x < yH0:y < zx <= y
x<y iff ~(y≤x)
forall x y : Q, ~ x < y -> y <= xunfold Qle, Qlt; auto with zarith. Qed.forall x y : Q, ~ x < y -> y <= xforall x y : Q, ~ x <= y -> y < xunfold Qle, Qlt; auto with zarith. Qed.forall x y : Q, ~ x <= y -> y < xforall x y : Q, x < y -> ~ y <= xunfold Qle, Qlt; auto with zarith. Qed.forall x y : Q, x < y -> ~ y <= xforall x y : Q, x <= y -> ~ y < xunfold Qle, Qlt; auto with zarith. Qed.forall x y : Q, x <= y -> ~ y < xforall x y : Q, x <= y -> x < y \/ x == yunfold Qle, Qlt, Qeq; intros; now apply Z.lt_eq_cases. Qed. Hint Resolve Qle_not_lt Qlt_not_le Qnot_le_lt Qnot_lt_le Qlt_le_weak Qlt_not_eq Qle_antisym Qle_refl: qarith.forall x y : Q, x <= y -> x < y \/ x == y
Some decidability results about orders.
forall x y : Q, {x < y} + {y < x} + {x == y}forall x y : Q, {x < y} + {y < x} + {x == y}exact (Z_dec' (Qnum x * QDen y) (Qnum y * QDen x)). Defined.x, y:Q{(Qnum x * QDen y < Qnum y * QDen x)%Z} + {(Qnum y * QDen x < Qnum x * QDen y)%Z} + {(Qnum x * QDen y)%Z = (Qnum y * QDen x)%Z}forall x y : Q, {x < y} + {y <= x}forall x y : Q, {x < y} + {y <= x}exact (Z_lt_le_dec (Qnum x * QDen y) (Qnum y * QDen x)). Defined.x, y:Q{(Qnum x * QDen y < Qnum y * QDen x)%Z} + {(Qnum y * QDen x <= Qnum x * QDen y)%Z}
Compatibility of operations with respect to order.
forall p q : Q, p <= q -> - q <= - pforall p q : Q, p <= q -> - q <= - pa1:Za2:positiveb1:Zb2:positive(a1 * Z.pos b2 <= b1 * Z.pos a2)%Z -> (- b1 * Z.pos a2 <= - a1 * Z.pos b2)%Zomega. Qed. Hint Resolve Qopp_le_compat : qarith.a1:Za2:positiveb1:Zb2:positive(a1 * Z.pos b2 <= b1 * Z.pos a2)%Z -> (- (b1 * Z.pos a2) <= - (a1 * Z.pos b2))%Zforall p q : Q, p <= q <-> 0 <= q + - pforall p q : Q, p <= q <-> 0 <= q + - px1:Zx2:positivey1:Zy2:positive(x1 * Z.pos y2 <= y1 * Z.pos x2)%Z <-> (0 <= (y1 * Z.pos x2 + - x1 * Z.pos y2) * 1)%Zomega. Qed.x1:Zx2:positivey1:Zy2:positive(x1 * Z.pos y2 <= y1 * Z.pos x2)%Z <-> (0 <= (y1 * Z.pos x2 + - (x1 * Z.pos y2)) * 1)%Zforall p q : Q, p < q <-> 0 < q + - pforall p q : Q, p < q <-> 0 < q + - px1:Zx2:positivey1:Zy2:positive(x1 * Z.pos y2 < y1 * Z.pos x2)%Z <-> (0 < (y1 * Z.pos x2 + - x1 * Z.pos y2) * 1)%Zomega. Qed.x1:Zx2:positivey1:Zy2:positive(x1 * Z.pos y2 < y1 * Z.pos x2)%Z <-> (0 < (y1 * Z.pos x2 + - (x1 * Z.pos y2)) * 1)%Zforall x y z t : Q, x <= y -> z <= t -> x + z <= y + tforall x y z t : Q, x <= y -> z <= t -> x + z <= y + tx1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positive(x1 * Z.pos y2 <= y1 * Z.pos x2)%Z -> (z1 * Z.pos t2 <= t1 * Z.pos z2)%Z -> ((x1 * Z.pos z2 + z1 * Z.pos x2) * (Z.pos y2 * Z.pos t2) <= (y1 * Z.pos t2 + t1 * Z.pos y2) * (Z.pos x2 * Z.pos z2))%Zx1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positivex1 * Z.pos y2 <= y1 * Z.pos x2 -> z1 * Z.pos t2 <= t1 * Z.pos z2 -> (x1 * Z.pos z2 + z1 * Z.pos x2) * (Z.pos y2 * Z.pos t2) <= (y1 * Z.pos t2 + t1 * Z.pos y2) * (Z.pos x2 * Z.pos z2)x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2(x1 * Z.pos z2 + z1 * Z.pos x2) * (Z.pos y2 * Z.pos t2) <= (y1 * Z.pos t2 + t1 * Z.pos y2) * (Z.pos x2 * Z.pos z2)x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 + z1 * Z.pos x2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos y2 * t1 + Z.pos z2 * Z.pos x2 * Z.pos t2 * y1x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2z1 * Z.pos x2 * Z.pos y2 * Z.pos t2 + x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos y2 * t1 + Z.pos z2 * Z.pos x2 * Z.pos t2 * y1x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2z1 * Z.pos x2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos y2 * t1x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos t2 * y1x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2z1 * Z.pos t2 * Z.pos x2 * Z.pos y2 <= t1 * Z.pos z2 * Z.pos x2 * Z.pos y2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos t2 * y1x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos t2 * y1auto with zarith. Close Scope Z_scope. Qed.x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 <= y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2x1 * Z.pos y2 * Z.pos z2 * Z.pos t2 <= y1 * Z.pos x2 * Z.pos z2 * Z.pos t2forall x y z t : Q, x < y -> z <= t -> x + z < y + tforall x y z t : Q, x < y -> z <= t -> x + z < y + tx1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positive(x1 * Z.pos y2 < y1 * Z.pos x2)%Z -> (z1 * Z.pos t2 <= t1 * Z.pos z2)%Z -> ((x1 * Z.pos z2 + z1 * Z.pos x2) * (Z.pos y2 * Z.pos t2) < (y1 * Z.pos t2 + t1 * Z.pos y2) * (Z.pos x2 * Z.pos z2))%Zx1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positivex1 * Z.pos y2 < y1 * Z.pos x2 -> z1 * Z.pos t2 <= t1 * Z.pos z2 -> (x1 * Z.pos z2 + z1 * Z.pos x2) * (Z.pos y2 * Z.pos t2) < (y1 * Z.pos t2 + t1 * Z.pos y2) * (Z.pos x2 * Z.pos z2)x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2(x1 * Z.pos z2 + z1 * Z.pos x2) * (Z.pos y2 * Z.pos t2) < (y1 * Z.pos t2 + t1 * Z.pos y2) * (Z.pos x2 * Z.pos z2)x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 + z1 * Z.pos x2 * Z.pos y2 * Z.pos t2 < Z.pos z2 * Z.pos x2 * Z.pos y2 * t1 + Z.pos z2 * Z.pos x2 * Z.pos t2 * y1x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2z1 * Z.pos x2 * Z.pos y2 * Z.pos t2 + x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 < Z.pos z2 * Z.pos x2 * Z.pos y2 * t1 + Z.pos z2 * Z.pos x2 * Z.pos t2 * y1x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2z1 * Z.pos x2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos y2 * t1x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 < Z.pos z2 * Z.pos x2 * Z.pos t2 * y1x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2z1 * Z.pos t2 * Z.pos x2 * Z.pos y2 <= t1 * Z.pos z2 * Z.pos x2 * Z.pos y2x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 < Z.pos z2 * Z.pos x2 * Z.pos t2 * y1x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 < Z.pos z2 * Z.pos x2 * Z.pos t2 * y1do 2 (apply Z.mul_lt_mono_pos_r;try easy). Close Scope Z_scope. Qed.x1:Zx2:positivey1:Zy2:positivez1:Zz2:positivet1:Zt2:positiveH:x1 * Z.pos y2 < y1 * Z.pos x2H0:z1 * Z.pos t2 <= t1 * Z.pos z2x1 * Z.pos y2 * Z.pos z2 * Z.pos t2 < y1 * Z.pos x2 * Z.pos z2 * Z.pos t2x, y, z:Qx + z <= y + z <-> x <= yx, y, z:Qx + z <= y + z <-> x <= yx, y, z:QH:x + z <= y + zx <= yx, y, z:QH:x <= yx + z <= y + zx, y, z:QH:x + z <= y + zx + (z + - z) <= y + (z + - z)x, y, z:QH:x <= yx + z <= y + zx, y, z:QH:x + z <= y + zx + z + - z <= y + z + - zx, y, z:QH:x <= yx + z <= y + zapply Qplus_le_compat; auto with *. Qed.x, y, z:QH:x <= yx + z <= y + zx, y, z:Qz + x <= z + y <-> x <= yx, y, z:Qz + x <= z + y <-> x <= yapply Qplus_le_l. Qed.x, y, z:Qx + z <= y + z <-> x <= yx, y, z:Qx + z < y + z <-> x < yx, y, z:Qx + z < y + z <-> x < yx, y, z:QH:x + z < y + zx < yx, y, z:QH:x < yx + z < y + zx, y, z:QH:x + z < y + zx + (z + - z) < y + (z + - z)x, y, z:QH:x < yx + z < y + zx, y, z:QH:x + z < y + zx + z + - z < y + z + - zx, y, z:QH:x < yx + z < y + zapply Qplus_lt_le_compat; auto with *. Qed.x, y, z:QH:x < yx + z < y + zx, y, z:Qz + x < z + y <-> x < yx, y, z:Qz + x < z + y <-> x < yapply Qplus_lt_l. Qed.x, y, z:Qx + z < y + z <-> x < yforall x y z : Q, x <= y -> 0 <= z -> x * z <= y * zforall x y z : Q, x <= y -> 0 <= z -> x * z <= y * za1:Za2:positiveb1:Zb2:positivec1:Zc2:positive(a1 * Z.pos b2 <= b1 * Z.pos a2)%Z -> (0 <= c1 * 1)%Z -> (a1 * c1 * Z.pos (b2 * c2) <= b1 * c1 * Z.pos (a2 * c2))%Za1:Za2:positiveb1:Zb2:positivec1:Zc2:positivea1 * Z.pos b2 <= b1 * Z.pos a2 -> 0 <= c1 * 1 -> a1 * c1 * Z.pos (b2 * c2) <= b1 * c1 * Z.pos (a2 * c2)a1:Za2:positiveb1:Zb2:positivec1:Zc2:positiveH:a1 * Z.pos b2 <= b1 * Z.pos a2H0:0 <= c1 * 1a1 * c1 * (Z.pos b2 * Z.pos c2) <= b1 * c1 * (Z.pos a2 * Z.pos c2)apply Z.mul_le_mono_nonneg_r; auto with zarith. Close Scope Z_scope. Qed.a1:Za2:positiveb1:Zb2:positivec1:Zc2:positiveH:a1 * Z.pos b2 <= b1 * Z.pos a2H0:0 <= c1 * 1a1 * Z.pos b2 * (c1 * Z.pos c2) <= b1 * Z.pos a2 * (c1 * Z.pos c2)forall x y z : Q, 0 < z -> x * z <= y * z -> x <= yforall x y z : Q, 0 < z -> x * z <= y * z -> x <= ya1:Za2:positiveb1:Zb2:positivec1:Zc2:positive(0 < c1 * 1)%Z -> (a1 * c1 * Z.pos (b2 * c2) <= b1 * c1 * Z.pos (a2 * c2))%Z -> (a1 * Z.pos b2 <= b1 * Z.pos a2)%Za1:Za2:positiveb1:Zb2:positivec1:Zc2:positive0 < c1 * 1 -> a1 * c1 * Z.pos (b2 * c2) <= b1 * c1 * Z.pos (a2 * c2) -> a1 * Z.pos b2 <= b1 * Z.pos a2a1:Za2:positiveb1:Zb2:positivec1:Zc2:positive0 < c1 * 1 -> a1 * c1 * (Z.pos b2 * Z.pos c2) <= b1 * c1 * (Z.pos a2 * Z.pos c2) -> a1 * Z.pos b2 <= b1 * Z.pos a2a1:Za2:positiveb1:Zb2:positivec1:Zc2:positive0 < c1 * 1 -> a1 * Z.pos b2 * (c1 * Z.pos c2) <= b1 * Z.pos a2 * (c1 * Z.pos c2) -> a1 * Z.pos b2 <= b1 * Z.pos a2a1:Za2:positiveb1:Zb2:positivec1:Zc2:positiveLT:0 < c1 * 1LE:a1 * Z.pos b2 * (c1 * Z.pos c2) <= b1 * Z.pos a2 * (c1 * Z.pos c2)a1 * Z.pos b2 <= b1 * Z.pos a2apply Z.mul_pos_pos; [omega|easy]. Close Scope Z_scope. Qed.a1:Za2:positiveb1:Zb2:positivec1:Zc2:positiveLT:0 < c1 * 1LE:a1 * Z.pos b2 * (c1 * Z.pos c2) <= b1 * Z.pos a2 * (c1 * Z.pos c2)H:forall n m p : Z, 0 < p -> n * p <= m * p -> n <= m0 < c1 * Z.pos c2x, y, z:Q0 < z -> x * z <= y * z <-> x <= yx, y, z:Q0 < z -> x * z <= y * z <-> x <= yx, y, z:QH:0 < zH0:x * z <= y * zx <= yx, y, z:QH:0 < zH0:x <= yx * z <= y * zapply Qmult_le_compat_r; auto with qarith. Qed.x, y, z:QH:0 < zH0:x <= yx * z <= y * zx, y, z:Q0 < z -> z * x <= z * y <-> x <= yx, y, z:Q0 < z -> z * x <= z * y <-> x <= yapply Qmult_le_r. Qed.x, y, z:Q0 < z -> x * z <= y * z <-> x <= yforall x y z : Q, 0 < z -> x < y -> x * z < y * zforall x y z : Q, 0 < z -> x < y -> x * z < y * za1:Za2:positiveb1:Zb2:positivec1:Zc2:positive(0 < c1 * 1)%Z -> (a1 * Z.pos b2 < b1 * Z.pos a2)%Z -> (a1 * c1 * Z.pos (b2 * c2) < b1 * c1 * Z.pos (a2 * c2))%Za1:Za2:positiveb1:Zb2:positivec1:Zc2:positive0 < c1 * 1 -> a1 * Z.pos b2 < b1 * Z.pos a2 -> a1 * c1 * Z.pos (b2 * c2) < b1 * c1 * Z.pos (a2 * c2)a1:Za2:positiveb1:Zb2:positivec1:Zc2:positiveH:0 < c1 * 1H0:a1 * Z.pos b2 < b1 * Z.pos a2a1 * c1 * (Z.pos b2 * Z.pos c2) < b1 * c1 * (Z.pos a2 * Z.pos c2)a1:Za2:positiveb1:Zb2:positivec1:Zc2:positiveH:0 < c1 * 1H0:a1 * Z.pos b2 < b1 * Z.pos a2a1 * Z.pos b2 * (c1 * Z.pos c2) < b1 * Z.pos a2 * (c1 * Z.pos c2)apply Z.mul_pos_pos; [omega|reflexivity]. Close Scope Z_scope. Qed.a1:Za2:positiveb1:Zb2:positivec1:Zc2:positiveH:0 < c1 * 1H0:a1 * Z.pos b2 < b1 * Z.pos a20 < c1 * Z.pos c2forall x y z : Q, 0 < z -> x * z < y * z <-> x < yforall x y z : Q, 0 < z -> x * z < y * z <-> x < yforall x y z : Q, (0 < z)%Q -> (x * z < y * z)%Q <-> (x < y)%Qa1:Za2:positiveb1:Zb2:positivec1:Zc2:positive(0 < c1 # c2)%Q -> ((a1 # a2) * (c1 # c2) < (b1 # b2) * (c1 # c2))%Q <-> (a1 # a2 < b1 # b2)%Qa1:Za2:positiveb1:Zb2:positivec1:Zc2:positive0 < c1 * 1 -> a1 * c1 * Z.pos (b2 * c2) < b1 * c1 * Z.pos (a2 * c2) <-> a1 * Z.pos b2 < b1 * Z.pos a2a1:Za2:positiveb1:Zb2:positivec1:Zc2:positive0 < c1 * 1 -> a1 * c1 * (Z.pos b2 * Z.pos c2) < b1 * c1 * (Z.pos a2 * Z.pos c2) <-> a1 * Z.pos b2 < b1 * Z.pos a2a1:Za2:positiveb1:Zb2:positivec1:Zc2:positive0 < c1 * 1 -> a1 * Z.pos b2 * (c1 * Z.pos c2) < b1 * Z.pos a2 * (c1 * Z.pos c2) <-> a1 * Z.pos b2 < b1 * Z.pos a2a1:Za2:positiveb1:Zb2:positivec1:Zc2:positiveLT:0 < c1 * 1a1 * Z.pos b2 * (c1 * Z.pos c2) < b1 * Z.pos a2 * (c1 * Z.pos c2) <-> a1 * Z.pos b2 < b1 * Z.pos a2a1:Za2:positiveb1:Zb2:positivec1:Zc2:positiveLT:0 < c1 * 1a1 * Z.pos b2 < b1 * Z.pos a2 <-> a1 * Z.pos b2 < b1 * Z.pos a2a1:Za2:positiveb1:Zb2:positivec1:Zc2:positiveLT:0 < c1 * 10 < c1 * Z.pos c2apply Z.mul_pos_pos; [omega|reflexivity]. Close Scope Z_scope. Qed.a1:Za2:positiveb1:Zb2:positivec1:Zc2:positiveLT:0 < c1 * 10 < c1 * Z.pos c2x, y, z:Q0 < z -> z * x < z * y <-> x < yx, y, z:Q0 < z -> z * x < z * y <-> x < yapply Qmult_lt_r. Qed.x, y, z:Q0 < z -> x * z < y * z <-> x < yforall a b : Q, 0 <= a -> 0 <= b -> 0 <= a * bforall a b : Q, 0 <= a -> 0 <= b -> 0 <= a * ba, b:QHa:0 <= aHb:0 <= b0 <= a * ba, b:QHa:(Qnum 0 * QDen a <= Qnum a * QDen 0)%ZHb:(Qnum 0 * QDen b <= Qnum b * QDen 0)%Z(Qnum 0 * QDen (a * b) <= Qnum (a * b) * QDen 0)%Zauto with *. Qed.a, b:QHa:(0 <= Qnum a * 1)%ZHb:(0 <= Qnum b * 1)%Z(0 <= Qnum a * Qnum b * 1)%Zforall a : Q, 0 <= a -> 0 <= / aintros [[|n|n] d] Ha; assumption. Qed.forall a : Q, 0 <= a -> 0 <= / aforall a b c : Q, 0 < c -> a * c <= b -> a <= b / cforall a b c : Q, 0 < c -> a * c <= b -> a <= b / ca, b, c:QHc:0 < cH:a * c <= ba <= b / ca, b, c:QHc:0 < cH:a * c <= b0 < ca, b, c:QHc:0 < cH:a * c <= ba * c <= b / c * ca, b, c:QHc:0 < cH:a * c <= ba * c <= b / c * ca, b, c:QHc:0 < cH:a * c <= ba * c <= c * (b / c)auto with *. Qed.a, b, c:QHc:0 < cH:a * c <= b~ c == 0forall a c : Q, 0 < c -> a * c <= 1 -> a <= / cforall a c : Q, 0 < c -> a * c <= 1 -> a <= / ca, c:QHc:0 < cH:a * c <= 1a <= / ca, c:QHc:0 < cH:a * c <= 1a <= 1 * / capply Qle_shift_div_l; assumption. Qed.a, c:QHc:0 < cH:a * c <= 1a <= 1 / cforall a b c : Q, 0 < b -> a <= c * b -> a / b <= cforall a b c : Q, 0 < b -> a <= c * b -> a / b <= ca, b, c:QHc:0 < bH:a <= c * ba / b <= ca, b, c:QHc:0 < bH:a <= c * b0 < ba, b, c:QHc:0 < bH:a <= c * ba / b * b <= c * ba, b, c:QHc:0 < bH:a <= c * ba / b * b <= c * ba, b, c:QHc:0 < bH:a <= c * bb * (a / b) <= c * bauto with *. Qed.a, b, c:QHc:0 < bH:a <= c * b~ b == 0forall b c : Q, 0 < b -> 1 <= c * b -> / b <= cforall b c : Q, 0 < b -> 1 <= c * b -> / b <= cb, c:QHc:0 < bH:1 <= c * b/ b <= cb, c:QHc:0 < bH:1 <= c * b1 * / b <= capply Qle_shift_div_r; assumption. Qed.b, c:QHc:0 < bH:1 <= c * b1 / b <= cforall a : Q, 0 < a -> 0 < / aintros [[|n|n] d] Ha; assumption. Qed.forall a : Q, 0 < a -> 0 < / aforall a b c : Q, 0 < c -> a * c < b -> a < b / cforall a b c : Q, 0 < c -> a * c < b -> a < b / ca, b, c:QHc:0 < cH:a * c < ba < b / ca, b, c:QHc:0 < cH:a * c < b~ b / c <= aa, b, c:QHc:0 < cH:a * c < bH0:b / c <= aFalsea, b, c:QHc:0 < cH:a * c < bH0:b / c <= ab <= a * ca, b, c:QHc:0 < cH:a * c < bH0:b / c <= a0 < / ca, b, c:QHc:0 < cH:a * c < bH0:b / c <= ab * / c <= a * c * / ca, b, c:QHc:0 < cH:a * c < bH0:b / c <= a0 < ca, b, c:QHc:0 < cH:a * c < bH0:b / c <= ab * / c <= a * c * / ca, b, c:QHc:0 < cH:a * c < bH0:b / c <= ab * / c <= a * c * / cassumption. Qed.a, b, c:QHc:0 < cH:a * c < bH0:b / c <= ab * / c <= aforall a c : Q, 0 < c -> a * c < 1 -> a < / cforall a c : Q, 0 < c -> a * c < 1 -> a < / ca, c:QHc:0 < cH:a * c < 1a < / ca, c:QHc:0 < cH:a * c < 1a < 1 * / capply Qlt_shift_div_l; assumption. Qed.a, c:QHc:0 < cH:a * c < 1a < 1 / cforall a b c : Q, 0 < b -> a < c * b -> a / b < cforall a b c : Q, 0 < b -> a < c * b -> a / b < ca, b, c:QHc:0 < bH:a < c * ba / b < ca, b, c:QHc:0 < bH:a < c * b~ c <= a / ba, b, c:QHc:0 < bH:a < c * bH0:c <= a / bFalsea, b, c:QHc:0 < bH:a < c * bH0:c <= a / bc * b <= aa, b, c:QHc:0 < bH:a < c * bH0:c <= a / b0 < / ba, b, c:QHc:0 < bH:a < c * bH0:c <= a / bc * b * / b <= a * / ba, b, c:QHc:0 < bH:a < c * bH0:c <= a / b0 < ba, b, c:QHc:0 < bH:a < c * bH0:c <= a / bc * b * / b <= a * / ba, b, c:QHc:0 < bH:a < c * bH0:c <= a / bc * b * / b <= a * / bassumption. Qed.a, b, c:QHc:0 < bH:a < c * bH0:c <= a / bc <= a * / bforall b c : Q, 0 < b -> 1 < c * b -> / b < cforall b c : Q, 0 < b -> 1 < c * b -> / b < cb, c:QHc:0 < bH:1 < c * b/ b < cb, c:QHc:0 < bH:1 < c * b1 * / b < capply Qlt_shift_div_r; assumption. Qed.b, c:QHc:0 < bH:1 < c * b1 / b < c
Definition Qpower_positive : Q -> positive -> Q := pow_pos Qmult.Proper (Qeq ==> eq ==> Qeq) Qpower_positiveProper (Qeq ==> eq ==> Qeq) Qpower_positivex, x':QHx:x == x'y, y':positiveHy:y = y'Qpower_positive x y == Qpower_positive x' y'x, x':QHx:x == x'y:positiveQpower_positive x y == Qpower_positive x' yinduction y; simpl; try rewrite IHy; try rewrite Hx; reflexivity. Qed. Definition Qpower (q:Q) (z:Z) := match z with | Zpos p => Qpower_positive q p | Z0 => 1 | Zneg p => /Qpower_positive q p end. Notation " q ^ z " := (Qpower q z) : Q_scope.x, x':QHx:x == x'y:positivepow_pos Qmult x y == pow_pos Qmult x' yProper (Qeq ==> eq ==> Qeq) QpowerProper (Qeq ==> eq ==> Qeq) Qpowerx, x':QHx:x == x'y, y':ZHy:y = y'x ^ y == x' ^ y'destruct y; simpl; rewrite ?Hx; auto with *. Qed.x, x':QHx:x == x'y:Zx ^ y == x' ^ y