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.

Definition of Q and basic properties

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:Z

inject_Z a == inject_Z b <-> a = b
a, b:Z

inject_Z a == inject_Z b <-> a = b
a, b:Z

(Qnum (inject_Z a) * QDen (inject_Z b))%Z = (Qnum (inject_Z b) * QDen (inject_Z a))%Z <-> a = b
a, b:Z

(a * 1)%Z = (b * 1)%Z <-> a = b
omega. Qed.
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:Q

p == q <-> (p ?= q) = Eq
p, q:Q

p == q <-> (p ?= q) = Eq
p, q:Q

(p ?= q) = Eq <-> p == q
apply Z.compare_eq_iff. Qed.
p, q:Q

p < q <-> (p ?= q) = Lt
p, q:Q

p < q <-> (p ?= q) = Lt
reflexivity. Qed.
p, q:Q

q < p <-> (p ?= q) = Gt
p, q:Q

q < p <-> (p ?= q) = Gt
p, q:Q

(p ?= q) = Gt <-> q < p
apply Z.gt_lt_iff. Qed.
p, q:Q

p <= q <-> (p ?= q) <> Gt
p, q:Q

p <= q <-> (p ?= q) <> Gt
reflexivity. Qed.
p, q:Q

q <= p <-> (p ?= q) <> Lt
p, q:Q

q <= p <-> (p ?= q) <> Lt
p, q:Q

(p ?= q) <> Lt <-> q <= p
apply Z.ge_le_iff. Qed. Hint Unfold Qeq Qlt Qle : qarith. Hint Extern 5 (?X1 <> ?X2) => intro; discriminate: qarith.
x, y:Q

CompOpp (x ?= y) = (y ?= x)
x, y:Q

CompOpp (x ?= y) = (y ?= x)
x, y:Q

(y ?= x) = CompOpp (x ?= y)
apply Z.compare_antisym. Qed.
x, y:Q

CompareSpec (x == y) (x < y) (y < x) (x ?= y)
x, y:Q

CompareSpec (x == y) (x < y) (y < x) (x ?= y)
x, y:Q

CompareSpec ((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
case Z.compare_spec; now constructor. Qed.

Properties of equality.

x:Q

x == x
x:Q

x == x
auto with qarith. Qed.
x, y:Q

x == y -> y == x
x, y:Q

x == y -> y == x
auto with qarith. Qed.
x, y, z:Q

x == y -> y == z -> x == z
x, y, z:Q

x == y -> y == z -> x == z
x, y, z:Q
XY:(Qnum x * QDen y)%Z = (Qnum y * QDen x)%Z
YZ:(Qnum y * QDen z)%Z = (Qnum z * QDen y)%Z

(Qnum x * QDen z)%Z = (Qnum z * QDen x)%Z
x, y, z:Q
XY:(Qnum x * QDen y)%Z = (Qnum y * QDen x)%Z
YZ:(Qnum y * QDen z)%Z = (Qnum z * QDen y)%Z

(Qnum x * QDen z * QDen y)%Z = (Qnum z * QDen x * QDen y)%Z
now 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.
In a word, Qeq is a setoid equality.

Equivalence Qeq

Equivalence Qeq
split; red; eauto with qarith. Qed.
Furthermore, this equality is decidable:
x, y:Q

{x == y} + {~ x == y}
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

Qeq_bool x y = true <-> x == y
x, y:Q

Qeq_bool x y = true <-> x == y
symmetry; apply Zeq_is_eq_bool. Qed.
x, y:Q

Qeq_bool x y = true -> x == y
x, y:Q

Qeq_bool x y = true -> x == y
apply Qeq_bool_iff. Qed.
x, y:Q

x == y -> Qeq_bool x y = true
x, y:Q

x == y -> Qeq_bool x y = true
apply Qeq_bool_iff. Qed.
x, y:Q

Qeq_bool x y = false -> ~ x == y
x, y:Q

Qeq_bool x y = false -> ~ x == y
x, y:Q

Qeq_bool x y = false -> Qeq_bool x y <> true
now intros ->. Qed.
x, y:Q

Qle_bool x y = true <-> x <= y
x, y:Q

Qle_bool x y = true <-> x <= y
symmetry; apply Zle_is_le_bool. Qed.
x, y:Q

Qle_bool x y = true -> x <= y
x, y:Q

Qle_bool x y = true -> x <= y
apply Qle_bool_iff. Qed.
x, y:Q

~ x == y -> ~ y == x
x, y:Q

~ x == y -> ~ y == x
auto with qarith. Qed.
x, y:Q

Qeq_bool x y = Qeq_bool y x
x, y:Q

Qeq_bool x y = Qeq_bool y x
x, y:Q

Qeq_bool x y = true <-> Qeq_bool y x = true
x, y:Q

x == y <-> y == x
now symmetry. Qed.
x:Q

Qeq_bool x x = true
x:Q

Qeq_bool x x = true
x:Q

x == x
now reflexivity. Qed.
x, y:Q

Qeq_bool x y = true -> Qeq_bool y x = true
x, y:Q

Qeq_bool x y = true -> Qeq_bool y x = true
x, y:Q

x == y -> y == x
now symmetry. Qed.
x, y, z:Q

Qeq_bool x y = true -> Qeq_bool y z = true -> Qeq_bool x z = true
x, y, z:Q

Qeq_bool x y = true -> Qeq_bool y z = true -> Qeq_bool x z = true
rewrite !Qeq_bool_iff; apply Qeq_trans. Qed. Hint Resolve Qnot_eq_sym : qarith.

Addition, multiplication and opposite

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:Z
b:positive

a # b == inject_Z a / inject_Z (Z.pos b)
a:Z
b:positive

a # b == inject_Z a / inject_Z (Z.pos b)
a:Z
b: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))%Z
a:Z
b:positive

(a * Z.pos b)%Z = (a * 1 * Z.pos b)%Z
ring. Qed.

Setoid compatibility results


Proper (Qeq ==> Qeq ==> Qeq) Qplus

Proper (Qeq ==> Qeq ==> Qeq) Qplus

Proper ((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:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0: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:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0:r1 * Z.pos s2 = s1 * Z.pos r2

p1 * 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 * q1
p1:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0:r1 * Z.pos s2 = s1 * Z.pos r2

p1 * 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 * q1
p1:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0:r1 * Z.pos s2 = s1 * Z.pos r2

q1 * 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 * q1
p1:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0:r1 * Z.pos s2 = s1 * Z.pos r2

q1 * 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 * q1
p1:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0:r1 * Z.pos s2 = s1 * Z.pos r2

q1 * 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 * q1
ring. Close Scope Z_scope. Qed.

Proper (Qeq ==> Qeq) Qopp

Proper (Qeq ==> Qeq) Qopp

Proper ((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:Q
H:Qnum x * QDen y = Qnum y * QDen x

- Qnum x * QDen y = - Qnum y * QDen x
x, y:Q
H:Qnum x * QDen y = Qnum y * QDen x

- (Qnum x * QDen y) = - Qnum y * QDen x
rewrite H; ring. Close Scope Z_scope. Qed.

Proper (Qeq ==> Qeq ==> Qeq) Qminus

Proper (Qeq ==> Qeq ==> Qeq) Qminus
x, x':Q
Hx:x == x'
y, y':Q
Hy:y == y'

x - y == x' - y'
x, x':Q
Hx:x == x'
y, y':Q
Hy:y == y'

x + - y == x' + - y'
rewrite Hx, Hy; auto with qarith. Qed.

Proper (Qeq ==> Qeq ==> Qeq) Qmult

Proper (Qeq ==> Qeq ==> Qeq) Qmult

Proper ((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)) Qmult

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)) Qmult
p1:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0:r1 * Z.pos s2 = s1 * Z.pos r2

p1 * r1 * Z.pos (q2 * s2) = q1 * s1 * Z.pos (p2 * r2)
p1:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0:r1 * Z.pos s2 = s1 * Z.pos r2

p1 * r1 * Z.pos q2 * Z.pos s2 = q1 * s1 * Z.pos p2 * Z.pos r2
p1:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0:r1 * Z.pos s2 = s1 * Z.pos r2

p1 * r1 * Z.pos q2 * Z.pos s2 = q1 * Z.pos p2 * s1 * Z.pos r2
p1:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0:r1 * Z.pos s2 = s1 * Z.pos r2

p1 * r1 * Z.pos q2 * Z.pos s2 = p1 * Z.pos q2 * s1 * Z.pos r2
p1:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0:r1 * Z.pos s2 = s1 * Z.pos r2

r1 * Z.pos s2 * p1 * Z.pos q2 = p1 * Z.pos q2 * s1 * Z.pos r2
p1:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H0:r1 * Z.pos s2 = s1 * Z.pos r2

s1 * Z.pos r2 * p1 * Z.pos q2 = p1 * Z.pos q2 * s1 * Z.pos r2
ring. Close Scope Z_scope. Qed.

Proper (Qeq ==> Qeq) Qinv

Proper (Qeq ==> Qeq) Qinv

Proper ((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:Z
p2:positive
q1:Z
q2:positive
EQ:p1 * Z.pos q2 = q1 * Z.pos p2

Qnum 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 end
p1:Z
p2, q2:positive
EQ:p1 * Z.pos q2 = 0

Qnum match p1 with | 0%Z => 0 | Z.pos p => Z.pos p2 # p | Z.neg p => Z.neg p2 # p end * 1 = 0
p1:Z
p2, p, q2:positive
EQ: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:Z
p2, p, q2:positive
EQ: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:Z
p2, q2:positive
EQ:p1 * Z.pos q2 = 0

Qnum match p1 with | 0%Z => 0 | Z.pos p => Z.pos p2 # p | Z.neg p => Z.neg p2 # p end * 1 = 0
p1:Z
p2, q2:positive
EQ:p1 = 0 \/ Z.pos q2 = 0

Qnum match p1 with | 0%Z => 0 | Z.pos p => Z.pos p2 # p | Z.neg p => Z.neg p2 # p end * 1 = 0
destruct EQ; now subst.
p1:Z
p2, p, q2:positive
EQ: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)
p0, p2, p, q2:positive
EQ:Z.pos (p0 * q2) = Z.pos (p * p2)

Z.pos (p2 * p) = Z.pos (q2 * p0)
now rewrite Pos.mul_comm, <- EQ, Pos.mul_comm.
p1:Z
p2, p, q2:positive
EQ: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)
p0, p2, p, q2:positive
EQ:Z.neg (p0 * q2) = Z.neg (p * p2)

Z.neg (p2 * p) = Z.neg (q2 * p0)
now rewrite Pos.mul_comm, <- EQ, Pos.mul_comm. Close Scope Z_scope. Qed.

Proper (Qeq ==> Qeq ==> Qeq) Qdiv

Proper (Qeq ==> Qeq ==> Qeq) Qdiv
x, x':Q
Hx:x == x'
y, y':Q
Hy:y == y'

x * / y == x' * / y'
rewrite Hx, Hy; auto with qarith. Qed.

Proper (Qeq ==> Qeq ==> eq) Qcompare

Proper (Qeq ==> Qeq ==> eq) Qcompare

Proper ((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:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H':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:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H':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:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H':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:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H':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:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H':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:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H':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:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H':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:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H':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))
p1:Z
p2:positive
q1:Z
q2:positive
H:p1 * Z.pos q2 = q1 * Z.pos p2
r1:Z
r2:positive
s1:Z
s2:positive
H':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))
f_equal; ring. Close Scope Z_scope. Qed.

Proper (Qeq ==> Qeq ==> iff) Qle

Proper (Qeq ==> Qeq ==> iff) Qle
p, q:Q
H:p == q
r, s:Q
H':r == s

p <= r <-> q <= s
rewrite 2 Qle_alt, H, H'; auto with *. Qed.

Proper (Qeq ==> Qeq ==> iff) Qlt

Proper (Qeq ==> Qeq ==> iff) Qlt
p, q:Q
H:p == q
r, s:Q
H':r == s

p < r <-> q < s
rewrite 2 Qlt_alt, H, H'; auto with *. Qed.

Proper (Qeq ==> Qeq ==> eq) Qeq_bool

Proper (Qeq ==> Qeq ==> eq) Qeq_bool
p, q:Q
H:p == q
r, s:Q
H':r == s

Qeq_bool p r = true <-> Qeq_bool q s = true
rewrite 2 Qeq_bool_iff, H, H'; split; auto with qarith. Qed.

Proper (Qeq ==> Qeq ==> eq) Qle_bool

Proper (Qeq ==> Qeq ==> eq) Qle_bool
p, q:Q
H:p == q
r, s:Q
H':r == s

Qle_bool p r = true <-> Qle_bool q s = true
rewrite 2 Qle_bool_iff, H, H'; split; auto with qarith. Qed.
0 and 1 are apart

~ 1 == 0

~ 1 == 0
unfold Qeq; auto with qarith. Qed.

Properties of Qadd

Addition is associative:

forall x y z : Q, x + (y + z) == x + y + z

forall x y z : Q, x + (y + z) == x + y + z
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive

(x1 # x2) + ((y1 # y2) + (z1 # z2)) == (x1 # x2) + (y1 # y2) + (z1 # z2)
unfold Qeq, Qplus; simpl; simpl_mult; ring. Qed.
0 is a neutral element for addition:

forall x : Q, 0 + x == x

forall x : Q, 0 + x == x
intros (x1, x2); unfold Qeq, Qplus; simpl; ring. Qed.

forall x : Q, x + 0 == x

forall x : Q, x + 0 == x
x1:Z
x2:positive

((x1 * 1 + 0) * Z.pos x2)%Z = (x1 * Z.pos (x2 * 1))%Z
rewrite Pos.mul_comm; simpl; ring. Qed.
Commutativity of addition:

forall x y : Q, x + y == y + x

forall x y : Q, x + y == y + x
x1:Z
x2:positive

forall 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
intros; rewrite Pos.mul_comm; ring. Qed.

Properties of Qopp


forall q : Q, - - q == q

forall q : Q, - - q == q
red; simpl; intros; ring. Qed.

forall q : Q, q + - q == 0

forall q : Q, q + - q == 0
red; simpl; intro; ring. Qed.
Injectivity of addition (uses theory about Qopp above):
x, y, z:Q

x + z == y + z <-> x == y
x, y, z:Q

x + z == y + z <-> x == y
x, y, z:Q
E:x + z == y + z

x == y
x, y, z:Q
E:x == y
x + z == y + z
x, y, z:Q
E:x + z == y + z

x + 0 == y + 0
x, y, z:Q
E:x == y
x + z == y + z
x, y, z:Q
E:x + z == y + z

x + (z + - z) == y + (z + - z)
x, y, z:Q
E:x == y
x + z == y + z
x, y, z:Q
E:x + z == y + z

x + z + - z == y + z + - z
x, y, z:Q
E:x == y
x + z == y + z
x, y, z:Q
E:x + z == y + z

y + z + - z == y + z + - z
x, y, z:Q
E:x == y
x + z == y + z
x, y, z:Q
E:x == y

x + z == y + z
x, y, z:Q
E:x == y

y + z == y + z
reflexivity. Qed.
x, y, z:Q

z + x == z + y <-> x == y
x, y, z:Q

z + x == z + y <-> x == y
x, y, z:Q

x + z == y + z <-> x == y
apply Qplus_inj_r. Qed.

Properties of Qmult

Multiplication is associative:

forall n m p : Q, n * (m * p) == n * m * p

forall n m p : Q, n * (m * p) == n * m * p
intros; red; simpl; rewrite Pos.mul_assoc; ring. Qed.
multiplication and zero

forall x : Q, 0 * x == 0

forall x : Q, 0 * x == 0
intros; compute; reflexivity. Qed.

forall x : Q, x * 0 == 0

forall x : Q, x * 0 == 0
intros; red; simpl; ring. Qed.
1 is a neutral element for multiplication:

forall n : Q, 1 * n == n

forall n : Q, 1 * n == n
intro; red; simpl; destruct (Qnum n); auto. Qed.

forall n : Q, n * 1 == n

forall n : Q, n * 1 == n
n:Q

(Qnum n * 1 * QDen n)%Z = (Qnum n * Z.pos (Qden n * 1))%Z
n:Q

(Qnum n * QDen n)%Z = (Qnum n * Z.pos (Qden n * 1))%Z
rewrite Pos.mul_comm; simpl; trivial. Qed.
Commutativity of multiplication

forall x y : Q, x * y == y * x

forall x y : Q, x * y == y * x
intros; red; simpl; rewrite Pos.mul_comm; ring. Qed.
Distributivity over Qadd

forall x y z : Q, x * (y + z) == x * y + x * z

forall x y z : Q, x * (y + z) == x * y + x * z
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive

(x1 # x2) * ((y1 # y2) + (z1 # z2)) == (x1 # x2) * (y1 # y2) + (x1 # x2) * (z1 # z2)
unfold Qeq, Qmult, Qplus; simpl; simpl_mult; ring. Qed.

forall x y z : Q, (x + y) * z == x * z + y * z

forall x y z : Q, (x + y) * z == x * z + y * z
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive

((x1 # x2) + (y1 # y2)) * (z1 # z2) == (x1 # x2) * (z1 # z2) + (y1 # y2) * (z1 # z2)
unfold Qeq, Qmult, Qplus; simpl; simpl_mult; ring. Qed.
Integrality

forall x y : Q, x * y == 0 -> x == 0 \/ y == 0

forall x y : Q, x * y == 0 -> x == 0 \/ y == 0
x1:Z
x2:positive
y1:Z
y2:positive

(x1 # x2) * (y1 # y2) == 0 -> x1 # x2 == 0 \/ y1 # y2 == 0
x1:Z
x2:positive
y1:Z
y2:positive

(x1 * y1 * 1)%Z = 0%Z -> (x1 * 1)%Z = 0%Z \/ (y1 * 1)%Z = 0%Z
now rewrite <- Z.mul_eq_0, !Z.mul_1_r. Qed.

forall x y : Q, ~ x == 0 -> x * y == 0 -> y == 0

forall x y : Q, ~ x == 0 -> x * y == 0 -> y == 0
x1:Z
x2:positive
y1:Z
y2:positive

~ x1 # x2 == 0 -> (x1 # x2) * (y1 # y2) == 0 -> y1 # y2 == 0
x1:Z
x2:positive
y1:Z
y2:positive

(x1 * 1)%Z <> 0%Z -> (x1 * y1 * 1)%Z = 0%Z -> (y1 * 1)%Z = 0%Z
x1:Z
x2:positive
y1:Z
y2:positive

x1 <> 0%Z -> x1 = 0%Z \/ y1 = 0%Z -> y1 = 0%Z
intuition. Qed.

inject_Z is a ring homomorphism:

x, y:Z

inject_Z (x + y) = inject_Z x + inject_Z y
x, y:Z

inject_Z (x + y) = inject_Z x + inject_Z y
x, y:Z

x + y # 1 = Qnum (x # 1) * QDen (y # 1) + Qnum (y # 1) * QDen (x # 1) # Qden (x # 1) * Qden (y # 1)
x, y:Z

x + y # 1 = x * 1 + y * 1 # 1
x, y:Z

(x + y)%Z = (x * 1 + y * 1)%Z
ring. Qed.
x, y:Z

inject_Z (x * y) = inject_Z x * inject_Z y
x, y:Z

inject_Z (x * y) = inject_Z x * inject_Z y
reflexivity. Qed.
x:Z

inject_Z (- x) = - inject_Z x
x:Z

inject_Z (- x) = - inject_Z x
reflexivity. Qed.

Inverse and division.


forall q : Q, / / q == q

forall q : Q, / / q == q
intros [[|n|n] d]; red; simpl; reflexivity. Qed.

forall x : Q, ~ x == 0 -> x * / x == 1

forall x : Q, ~ x == 0 -> x * / x == 1
x1:Z
x2:positive
H:0%Z <> 0%Z

0%Z = (Z.pos x2 * 1)%Z
elim H; auto. Qed.

forall p q : Q, / (p * q) == / p * / q

forall p q : Q, / (p * q) == / p * / q
x1:Z
x2:positive
y1:Z
y2: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)%Z
destruct x1; simpl; auto; destruct y1; simpl; auto. Qed.

forall x y : Q, ~ y == 0 -> x * y / y == x

forall x y : Q, ~ y == 0 -> x * y / y == x
x, y:Q
H:~ y == 0

x * y * / y == x
x, y:Q
H:~ y == 0

x * (y * / y) == x
x, y:Q
H:~ y == 0

x * 1 == x
apply Qmult_1_r. Qed.

forall x y : Q, ~ y == 0 -> y * (x / y) == x

forall x y : Q, ~ y == 0 -> y * (x / y) == x
x, y:Q
H:~ y == 0

y * (x * / y) == x
x, y:Q
H:~ y == 0

y * x * / y == x
x, y:Q
H:~ y == 0

x * y * / y == x
x, y:Q
H:~ y == 0

x * y / y == x
apply Qdiv_mult_l; auto. Qed.
Injectivity of Qmult (requires theory about Qinv above):
x, y, z:Q

~ z == 0 -> x * z == y * z <-> x == y
x, y, z:Q

~ z == 0 -> x * z == y * z <-> x == y
x, y, z:Q
z_ne_0:~ z == 0

x * z == y * z <-> x == y
x, y, z:Q
z_ne_0:~ z == 0
E:x * z == y * z

x == y
x, y, z:Q
z_ne_0:~ z == 0
E:x == y
x * z == y * z
x, y, z:Q
z_ne_0:~ z == 0
E:x * z == y * z

x * 1 == y * 1
x, y, z:Q
z_ne_0:~ z == 0
E:x == y
x * z == y * z
x, y, z:Q
z_ne_0:~ z == 0
E:x * z == y * z

x * (z * / z) == y * (z * / z)
x, y, z:Q
z_ne_0:~ z == 0
E:x == y
x * z == y * z
x, y, z:Q
z_ne_0:~ z == 0
E:x * z == y * z

x * z * / z == y * z * / z
x, y, z:Q
z_ne_0:~ z == 0
E:x == y
x * z == y * z
x, y, z:Q
z_ne_0:~ z == 0
E:x * z == y * z

y * z * / z == y * z * / z
x, y, z:Q
z_ne_0:~ z == 0
E:x == y
x * z == y * z
x, y, z:Q
z_ne_0:~ z == 0
E:x == y

x * z == y * z
x, y, z:Q
z_ne_0:~ z == 0
E:x == y

y * z == y * z
reflexivity. Qed.
x, y, z:Q

~ z == 0 -> z * x == z * y <-> x == y
x, y, z:Q

~ z == 0 -> z * x == z * y <-> x == y
x, y, z:Q

~ z == 0 -> x * z == y * z <-> x == y
apply Qmult_inj_r. Qed.

Properties of order upon Q.

x:Q

x <= x
x:Q

x <= x
unfold Qle; auto with zarith. Qed.
x, y:Q

x <= y -> y <= x -> x == y
x, y:Q

x <= y -> y <= x -> x == y
unfold Qle, Qeq; auto with zarith. Qed.

forall x y z : Q, x <= y -> y <= z -> x <= z

forall x y z : Q, x <= y -> y <= z -> x <= z
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:(x1 * Z.pos y2 <= y1 * Z.pos x2)%Z
H0:(y1 * Z.pos z2 <= z1 * Z.pos y2)%Z

(x1 * Z.pos z2 <= z1 * Z.pos x2)%Z
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

x1 * Z.pos z2 <= z1 * Z.pos x2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

x1 * Z.pos z2 * Z.pos y2 <= z1 * Z.pos x2 * Z.pos y2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

x1 * Z.pos z2 * Z.pos y2 <= y1 * Z.pos x2 * Z.pos z2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2
y1 * Z.pos x2 * Z.pos z2 <= z1 * Z.pos x2 * Z.pos y2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

x1 * Z.pos z2 * Z.pos y2 <= y1 * Z.pos x2 * Z.pos z2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

x1 * Z.pos y2 * Z.pos z2 <= y1 * Z.pos x2 * Z.pos z2
now apply Z.mul_le_mono_pos_r.
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

y1 * Z.pos x2 * Z.pos z2 <= z1 * Z.pos x2 * Z.pos y2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

y1 * Z.pos z2 * Z.pos x2 <= z1 * Z.pos y2 * Z.pos x2
now apply Z.mul_le_mono_pos_r. Close Scope Z_scope. Qed. Hint Resolve Qle_trans : qarith.
x:Q

~ x < x
x:Q

~ x < x
x:Q

~ (Qnum x * QDen x < Qnum x * QDen x)%Z
auto with zarith. Qed.
x, y:Q

x < y -> ~ x == y
x, y:Q

x < y -> ~ x == y
unfold Qlt, Qeq; auto with zarith. Qed.
x, 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))%Z
x, y:Z

(x <= y)%Z = (x * 1 <= y * 1)%Z
now rewrite !Z.mul_1_r. Qed.
x, 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))%Z
x, y:Z

(x < y)%Z = (x * 1 < y * 1)%Z
now rewrite !Z.mul_1_r. Qed.
Large = strict or equal
x, y:Q

x <= y <-> x < y \/ x == y
x, y:Q

x <= y <-> x < y \/ x == y
x, y:Q

(x ?= y) <> Gt <-> (x ?= y) = Lt \/ (x ?= y) = Eq
destruct (x ?= y); intuition; discriminate. Qed.
x, y:Q

x < y -> x <= y
x, y:Q

x < y -> x <= y
unfold Qle, Qlt; auto with zarith. Qed.

forall x y z : Q, x <= y -> y < z -> x < z

forall x y z : Q, x <= y -> y < z -> x < z
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:(x1 * Z.pos y2 <= y1 * Z.pos x2)%Z
H0:(y1 * Z.pos z2 < z1 * Z.pos y2)%Z

(x1 * Z.pos z2 < z1 * Z.pos x2)%Z
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 < z1 * Z.pos y2

x1 * Z.pos z2 < z1 * Z.pos x2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 < z1 * Z.pos y2

x1 * Z.pos z2 * Z.pos y2 < z1 * Z.pos x2 * Z.pos y2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 < z1 * Z.pos y2

x1 * Z.pos z2 * Z.pos y2 <= y1 * Z.pos x2 * Z.pos z2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 < z1 * Z.pos y2
y1 * Z.pos x2 * Z.pos z2 < z1 * Z.pos x2 * Z.pos y2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 < z1 * Z.pos y2

x1 * Z.pos z2 * Z.pos y2 <= y1 * Z.pos x2 * Z.pos z2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 < z1 * Z.pos y2

x1 * Z.pos y2 * Z.pos z2 <= y1 * Z.pos x2 * Z.pos z2
now apply Z.mul_le_mono_pos_r.
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 < z1 * Z.pos y2

y1 * Z.pos x2 * Z.pos z2 < z1 * Z.pos x2 * Z.pos y2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:y1 * Z.pos z2 < z1 * Z.pos y2

y1 * Z.pos z2 * Z.pos x2 < z1 * Z.pos y2 * Z.pos x2
now apply Z.mul_lt_mono_pos_r. Close Scope Z_scope. Qed.

forall x y z : Q, x < y -> y <= z -> x < z

forall x y z : Q, x < y -> y <= z -> x < z
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:(x1 * Z.pos y2 < y1 * Z.pos x2)%Z
H0:(y1 * Z.pos z2 <= z1 * Z.pos y2)%Z

(x1 * Z.pos z2 < z1 * Z.pos x2)%Z
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

x1 * Z.pos z2 < z1 * Z.pos x2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

x1 * Z.pos z2 * Z.pos y2 < z1 * Z.pos x2 * Z.pos y2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

x1 * Z.pos z2 * Z.pos y2 < y1 * Z.pos x2 * Z.pos z2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2
y1 * Z.pos x2 * Z.pos z2 <= z1 * Z.pos x2 * Z.pos y2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

x1 * Z.pos z2 * Z.pos y2 < y1 * Z.pos x2 * Z.pos z2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

x1 * Z.pos y2 * Z.pos z2 < y1 * Z.pos x2 * Z.pos z2
now apply Z.mul_lt_mono_pos_r.
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

y1 * Z.pos x2 * Z.pos z2 <= z1 * Z.pos x2 * Z.pos y2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:y1 * Z.pos z2 <= z1 * Z.pos y2

y1 * Z.pos z2 * Z.pos x2 <= z1 * Z.pos y2 * Z.pos x2
now apply Z.mul_le_mono_pos_r. Close Scope Z_scope. Qed.

forall x y z : Q, x < y -> y < z -> x < z

forall x y z : Q, x < y -> y < z -> x < z
x, y, z:Q
H:x < y
H0:y < z

x < z
x, y, z:Q
H:x < y
H0:y < z

x <= y
apply Qlt_le_weak; auto. Qed.
x<y iff ~(yx)

forall x y : Q, ~ x < y -> y <= x

forall x y : Q, ~ x < y -> y <= x
unfold Qle, Qlt; auto with zarith. Qed.

forall x y : Q, ~ x <= y -> y < x

forall x y : Q, ~ x <= y -> y < x
unfold Qle, Qlt; auto with zarith. Qed.

forall x y : Q, x < y -> ~ y <= x

forall x y : Q, x < y -> ~ y <= x
unfold Qle, Qlt; auto with zarith. Qed.

forall x y : Q, x <= y -> ~ y < x

forall x y : Q, x <= y -> ~ y < x
unfold Qle, Qlt; auto with zarith. Qed.

forall x y : Q, x <= y -> x < y \/ x == y

forall x y : Q, x <= y -> x < y \/ x == y
unfold 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.
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}
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}
exact (Z_dec' (Qnum x * QDen y) (Qnum y * QDen x)). Defined.

forall x y : Q, {x < y} + {y <= x}

forall x y : Q, {x < y} + {y <= x}
x, y:Q

{(Qnum x * QDen y < Qnum y * QDen x)%Z} + {(Qnum y * QDen x <= Qnum x * QDen y)%Z}
exact (Z_lt_le_dec (Qnum x * QDen y) (Qnum y * QDen x)). Defined.
Compatibility of operations with respect to order.

forall p q : Q, p <= q -> - q <= - p

forall p q : Q, p <= q -> - q <= - p
a1:Z
a2:positive
b1:Z
b2:positive

(a1 * Z.pos b2 <= b1 * Z.pos a2)%Z -> (- b1 * Z.pos a2 <= - a1 * Z.pos b2)%Z
a1:Z
a2:positive
b1:Z
b2:positive

(a1 * Z.pos b2 <= b1 * Z.pos a2)%Z -> (- (b1 * Z.pos a2) <= - (a1 * Z.pos b2))%Z
omega. Qed. Hint Resolve Qopp_le_compat : qarith.

forall p q : Q, p <= q <-> 0 <= q + - p

forall p q : Q, p <= q <-> 0 <= q + - p
x1:Z
x2:positive
y1:Z
y2:positive

(x1 * Z.pos y2 <= y1 * Z.pos x2)%Z <-> (0 <= (y1 * Z.pos x2 + - x1 * Z.pos y2) * 1)%Z
x1:Z
x2:positive
y1:Z
y2:positive

(x1 * Z.pos y2 <= y1 * Z.pos x2)%Z <-> (0 <= (y1 * Z.pos x2 + - (x1 * Z.pos y2)) * 1)%Z
omega. Qed.

forall p q : Q, p < q <-> 0 < q + - p

forall p q : Q, p < q <-> 0 < q + - p
x1:Z
x2:positive
y1:Z
y2:positive

(x1 * Z.pos y2 < y1 * Z.pos x2)%Z <-> (0 < (y1 * Z.pos x2 + - x1 * Z.pos y2) * 1)%Z
x1:Z
x2:positive
y1:Z
y2:positive

(x1 * Z.pos y2 < y1 * Z.pos x2)%Z <-> (0 < (y1 * Z.pos x2 + - (x1 * Z.pos y2)) * 1)%Z
omega. Qed.

forall x y z t : Q, x <= y -> z <= t -> x + z <= y + t

forall x y z t : Q, x <= y -> z <= t -> x + z <= y + t
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2: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))%Z
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive

x1 * 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:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0: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:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

x1 * 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 * y1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

z1 * 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 * y1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

z1 * Z.pos x2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos y2 * t1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2
x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos t2 * y1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

z1 * Z.pos t2 * Z.pos x2 * Z.pos y2 <= t1 * Z.pos z2 * Z.pos x2 * Z.pos y2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2
x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos t2 * y1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos t2 * y1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 <= y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

x1 * Z.pos y2 * Z.pos z2 * Z.pos t2 <= y1 * Z.pos x2 * Z.pos z2 * Z.pos t2
auto with zarith. Close Scope Z_scope. Qed.

forall x y z t : Q, x < y -> z <= t -> x + z < y + t

forall x y z t : Q, x < y -> z <= t -> x + z < y + t
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2: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))%Z
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive

x1 * 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:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0: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:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

x1 * 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 * y1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

z1 * 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 * y1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

z1 * Z.pos x2 * Z.pos y2 * Z.pos t2 <= Z.pos z2 * Z.pos x2 * Z.pos y2 * t1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2
x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 < Z.pos z2 * Z.pos x2 * Z.pos t2 * y1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

z1 * Z.pos t2 * Z.pos x2 * Z.pos y2 <= t1 * Z.pos z2 * Z.pos x2 * Z.pos y2
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2
x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 < Z.pos z2 * Z.pos x2 * Z.pos t2 * y1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

x1 * Z.pos z2 * Z.pos y2 * Z.pos t2 < Z.pos z2 * Z.pos x2 * Z.pos t2 * y1
x1:Z
x2:positive
y1:Z
y2:positive
z1:Z
z2:positive
t1:Z
t2:positive
H:x1 * Z.pos y2 < y1 * Z.pos x2
H0:z1 * Z.pos t2 <= t1 * Z.pos z2

x1 * Z.pos y2 * Z.pos z2 * Z.pos t2 < y1 * Z.pos x2 * Z.pos z2 * Z.pos t2
do 2 (apply Z.mul_lt_mono_pos_r;try easy). Close Scope Z_scope. Qed.
x, y, z:Q

x + z <= y + z <-> x <= y
x, y, z:Q

x + z <= y + z <-> x <= y
x, y, z:Q
H:x + z <= y + z

x <= y
x, y, z:Q
H:x <= y
x + z <= y + z
x, y, z:Q
H:x + z <= y + z

x + (z + - z) <= y + (z + - z)
x, y, z:Q
H:x <= y
x + z <= y + z
x, y, z:Q
H:x + z <= y + z

x + z + - z <= y + z + - z
x, y, z:Q
H:x <= y
x + z <= y + z
x, y, z:Q
H:x <= y

x + z <= y + z
apply Qplus_le_compat; auto with *. Qed.
x, y, z:Q

z + x <= z + y <-> x <= y
x, y, z:Q

z + x <= z + y <-> x <= y
x, y, z:Q

x + z <= y + z <-> x <= y
apply Qplus_le_l. Qed.
x, y, z:Q

x + z < y + z <-> x < y
x, y, z:Q

x + z < y + z <-> x < y
x, y, z:Q
H:x + z < y + z

x < y
x, y, z:Q
H:x < y
x + z < y + z
x, y, z:Q
H:x + z < y + z

x + (z + - z) < y + (z + - z)
x, y, z:Q
H:x < y
x + z < y + z
x, y, z:Q
H:x + z < y + z

x + z + - z < y + z + - z
x, y, z:Q
H:x < y
x + z < y + z
x, y, z:Q
H:x < y

x + z < y + z
apply Qplus_lt_le_compat; auto with *. Qed.
x, y, z:Q

z + x < z + y <-> x < y
x, y, z:Q

z + x < z + y <-> x < y
x, y, z:Q

x + z < y + z <-> x < y
apply Qplus_lt_l. Qed.

forall x y z : Q, x <= y -> 0 <= z -> x * z <= y * z

forall x y z : Q, x <= y -> 0 <= z -> x * z <= y * z
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2: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))%Z
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive

a1 * Z.pos b2 <= b1 * Z.pos a2 -> 0 <= c1 * 1 -> a1 * c1 * Z.pos (b2 * c2) <= b1 * c1 * Z.pos (a2 * c2)
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive
H:a1 * Z.pos b2 <= b1 * Z.pos a2
H0:0 <= c1 * 1

a1 * c1 * (Z.pos b2 * Z.pos c2) <= b1 * c1 * (Z.pos a2 * Z.pos c2)
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive
H:a1 * Z.pos b2 <= b1 * Z.pos a2
H0:0 <= c1 * 1

a1 * Z.pos b2 * (c1 * Z.pos c2) <= b1 * Z.pos a2 * (c1 * Z.pos c2)
apply Z.mul_le_mono_nonneg_r; auto with zarith. Close Scope Z_scope. Qed.

forall x y z : Q, 0 < z -> x * z <= y * z -> x <= y

forall x y z : Q, 0 < z -> x * z <= y * z -> x <= y
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2: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)%Z
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive

0 < c1 * 1 -> a1 * c1 * Z.pos (b2 * c2) <= b1 * c1 * Z.pos (a2 * c2) -> a1 * Z.pos b2 <= b1 * Z.pos a2
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive

0 < 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 a2
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive

0 < 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 a2
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive
LT:0 < c1 * 1
LE:a1 * Z.pos b2 * (c1 * Z.pos c2) <= b1 * Z.pos a2 * (c1 * Z.pos c2)

a1 * Z.pos b2 <= b1 * Z.pos a2
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive
LT:0 < c1 * 1
LE: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 <= m

0 < c1 * Z.pos c2
apply Z.mul_pos_pos; [omega|easy]. Close Scope Z_scope. Qed.
x, y, z:Q

0 < z -> x * z <= y * z <-> x <= y
x, y, z:Q

0 < z -> x * z <= y * z <-> x <= y
x, y, z:Q
H:0 < z
H0:x * z <= y * z

x <= y
x, y, z:Q
H:0 < z
H0:x <= y
x * z <= y * z
x, y, z:Q
H:0 < z
H0:x <= y

x * z <= y * z
apply Qmult_le_compat_r; auto with qarith. Qed.
x, y, z:Q

0 < z -> z * x <= z * y <-> x <= y
x, y, z:Q

0 < z -> z * x <= z * y <-> x <= y
x, y, z:Q

0 < z -> x * z <= y * z <-> x <= y
apply Qmult_le_r. Qed.

forall x y z : Q, 0 < z -> x < y -> x * z < y * z

forall x y z : Q, 0 < z -> x < y -> x * z < y * z
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2: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))%Z
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive

0 < c1 * 1 -> a1 * Z.pos b2 < b1 * Z.pos a2 -> a1 * c1 * Z.pos (b2 * c2) < b1 * c1 * Z.pos (a2 * c2)
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive
H:0 < c1 * 1
H0:a1 * Z.pos b2 < b1 * Z.pos a2

a1 * c1 * (Z.pos b2 * Z.pos c2) < b1 * c1 * (Z.pos a2 * Z.pos c2)
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive
H:0 < c1 * 1
H0:a1 * Z.pos b2 < b1 * Z.pos a2

a1 * Z.pos b2 * (c1 * Z.pos c2) < b1 * Z.pos a2 * (c1 * Z.pos c2)
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive
H:0 < c1 * 1
H0:a1 * Z.pos b2 < b1 * Z.pos a2

0 < c1 * Z.pos c2
apply Z.mul_pos_pos; [omega|reflexivity]. Close Scope Z_scope. Qed.

forall x y z : Q, 0 < z -> x * z < y * z <-> x < y

forall x y z : Q, 0 < z -> x * z < y * z <-> x < y

forall x y z : Q, (0 < z)%Q -> (x * z < y * z)%Q <-> (x < y)%Q
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive

(0 < c1 # c2)%Q -> ((a1 # a2) * (c1 # c2) < (b1 # b2) * (c1 # c2))%Q <-> (a1 # a2 < b1 # b2)%Q
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive

0 < c1 * 1 -> a1 * c1 * Z.pos (b2 * c2) < b1 * c1 * Z.pos (a2 * c2) <-> a1 * Z.pos b2 < b1 * Z.pos a2
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive

0 < 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 a2
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive

0 < 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 a2
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive
LT:0 < 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 a2
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive
LT:0 < c1 * 1

a1 * Z.pos b2 < b1 * Z.pos a2 <-> a1 * Z.pos b2 < b1 * Z.pos a2
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive
LT:0 < c1 * 1
0 < c1 * Z.pos c2
a1:Z
a2:positive
b1:Z
b2:positive
c1:Z
c2:positive
LT:0 < c1 * 1

0 < c1 * Z.pos c2
apply Z.mul_pos_pos; [omega|reflexivity]. Close Scope Z_scope. Qed.
x, y, z:Q

0 < z -> z * x < z * y <-> x < y
x, y, z:Q

0 < z -> z * x < z * y <-> x < y
x, y, z:Q

0 < z -> x * z < y * z <-> x < y
apply Qmult_lt_r. Qed.

forall a b : Q, 0 <= a -> 0 <= b -> 0 <= a * b

forall a b : Q, 0 <= a -> 0 <= b -> 0 <= a * b
a, b:Q
Ha:0 <= a
Hb:0 <= b

0 <= a * b
a, b:Q
Ha:(Qnum 0 * QDen a <= Qnum a * QDen 0)%Z
Hb:(Qnum 0 * QDen b <= Qnum b * QDen 0)%Z

(Qnum 0 * QDen (a * b) <= Qnum (a * b) * QDen 0)%Z
a, b:Q
Ha:(0 <= Qnum a * 1)%Z
Hb:(0 <= Qnum b * 1)%Z

(0 <= Qnum a * Qnum b * 1)%Z
auto with *. Qed.

forall a : Q, 0 <= a -> 0 <= / a

forall a : Q, 0 <= a -> 0 <= / a
intros [[|n|n] d] Ha; assumption. Qed.

forall a b c : Q, 0 < c -> a * c <= b -> a <= b / c

forall a b c : Q, 0 < c -> a * c <= b -> a <= b / c
a, b, c:Q
Hc:0 < c
H:a * c <= b

a <= b / c
a, b, c:Q
Hc:0 < c
H:a * c <= b

0 < c
a, b, c:Q
Hc:0 < c
H:a * c <= b
a * c <= b / c * c
a, b, c:Q
Hc:0 < c
H:a * c <= b

a * c <= b / c * c
a, b, c:Q
Hc:0 < c
H:a * c <= b

a * c <= c * (b / c)
a, b, c:Q
Hc:0 < c
H:a * c <= b

~ c == 0
auto with *. Qed.

forall a c : Q, 0 < c -> a * c <= 1 -> a <= / c

forall a c : Q, 0 < c -> a * c <= 1 -> a <= / c
a, c:Q
Hc:0 < c
H:a * c <= 1

a <= / c
a, c:Q
Hc:0 < c
H:a * c <= 1

a <= 1 * / c
a, c:Q
Hc:0 < c
H:a * c <= 1

a <= 1 / c
apply Qle_shift_div_l; assumption. Qed.

forall a b c : Q, 0 < b -> a <= c * b -> a / b <= c

forall a b c : Q, 0 < b -> a <= c * b -> a / b <= c
a, b, c:Q
Hc:0 < b
H:a <= c * b

a / b <= c
a, b, c:Q
Hc:0 < b
H:a <= c * b

0 < b
a, b, c:Q
Hc:0 < b
H:a <= c * b
a / b * b <= c * b
a, b, c:Q
Hc:0 < b
H:a <= c * b

a / b * b <= c * b
a, b, c:Q
Hc:0 < b
H:a <= c * b

b * (a / b) <= c * b
a, b, c:Q
Hc:0 < b
H:a <= c * b

~ b == 0
auto with *. Qed.

forall b c : Q, 0 < b -> 1 <= c * b -> / b <= c

forall b c : Q, 0 < b -> 1 <= c * b -> / b <= c
b, c:Q
Hc:0 < b
H:1 <= c * b

/ b <= c
b, c:Q
Hc:0 < b
H:1 <= c * b

1 * / b <= c
b, c:Q
Hc:0 < b
H:1 <= c * b

1 / b <= c
apply Qle_shift_div_r; assumption. Qed.

forall a : Q, 0 < a -> 0 < / a

forall a : Q, 0 < a -> 0 < / a
intros [[|n|n] d] Ha; assumption. Qed.

forall a b c : Q, 0 < c -> a * c < b -> a < b / c

forall a b c : Q, 0 < c -> a * c < b -> a < b / c
a, b, c:Q
Hc:0 < c
H:a * c < b

a < b / c
a, b, c:Q
Hc:0 < c
H:a * c < b

~ b / c <= a
a, b, c:Q
Hc:0 < c
H:a * c < b
H0:b / c <= a

False
a, b, c:Q
Hc:0 < c
H:a * c < b
H0:b / c <= a

b <= a * c
a, b, c:Q
Hc:0 < c
H:a * c < b
H0:b / c <= a

0 < / c
a, b, c:Q
Hc:0 < c
H:a * c < b
H0:b / c <= a
b * / c <= a * c * / c
a, b, c:Q
Hc:0 < c
H:a * c < b
H0:b / c <= a

0 < c
a, b, c:Q
Hc:0 < c
H:a * c < b
H0:b / c <= a
b * / c <= a * c * / c
a, b, c:Q
Hc:0 < c
H:a * c < b
H0:b / c <= a

b * / c <= a * c * / c
a, b, c:Q
Hc:0 < c
H:a * c < b
H0:b / c <= a

b * / c <= a
assumption. Qed.

forall a c : Q, 0 < c -> a * c < 1 -> a < / c

forall a c : Q, 0 < c -> a * c < 1 -> a < / c
a, c:Q
Hc:0 < c
H:a * c < 1

a < / c
a, c:Q
Hc:0 < c
H:a * c < 1

a < 1 * / c
a, c:Q
Hc:0 < c
H:a * c < 1

a < 1 / c
apply Qlt_shift_div_l; assumption. Qed.

forall a b c : Q, 0 < b -> a < c * b -> a / b < c

forall a b c : Q, 0 < b -> a < c * b -> a / b < c
a, b, c:Q
Hc:0 < b
H:a < c * b

a / b < c
a, b, c:Q
Hc:0 < b
H:a < c * b

~ c <= a / b
a, b, c:Q
Hc:0 < b
H:a < c * b
H0:c <= a / b

False
a, b, c:Q
Hc:0 < b
H:a < c * b
H0:c <= a / b

c * b <= a
a, b, c:Q
Hc:0 < b
H:a < c * b
H0:c <= a / b

0 < / b
a, b, c:Q
Hc:0 < b
H:a < c * b
H0:c <= a / b
c * b * / b <= a * / b
a, b, c:Q
Hc:0 < b
H:a < c * b
H0:c <= a / b

0 < b
a, b, c:Q
Hc:0 < b
H:a < c * b
H0:c <= a / b
c * b * / b <= a * / b
a, b, c:Q
Hc:0 < b
H:a < c * b
H0:c <= a / b

c * b * / b <= a * / b
a, b, c:Q
Hc:0 < b
H:a < c * b
H0:c <= a / b

c <= a * / b
assumption. Qed.

forall b c : Q, 0 < b -> 1 < c * b -> / b < c

forall b c : Q, 0 < b -> 1 < c * b -> / b < c
b, c:Q
Hc:0 < b
H:1 < c * b

/ b < c
b, c:Q
Hc:0 < b
H:1 < c * b

1 * / b < c
b, c:Q
Hc:0 < b
H:1 < c * b

1 / b < c
apply Qlt_shift_div_r; assumption. Qed.

Rational to the n-th power

Definition Qpower_positive : Q -> positive -> Q :=
 pow_pos Qmult.


Proper (Qeq ==> eq ==> Qeq) Qpower_positive

Proper (Qeq ==> eq ==> Qeq) Qpower_positive
x, x':Q
Hx:x == x'
y, y':positive
Hy:y = y'

Qpower_positive x y == Qpower_positive x' y'
x, x':Q
Hx:x == x'
y:positive

Qpower_positive x y == Qpower_positive x' y
x, x':Q
Hx:x == x'
y:positive

pow_pos Qmult x y == pow_pos Qmult x' y
induction 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.

Proper (Qeq ==> eq ==> Qeq) Qpower

Proper (Qeq ==> eq ==> Qeq) Qpower
x, x':Q
Hx:x == x'
y, y':Z
Hy:y = y'

x ^ y == x' ^ y'
x, x':Q
Hx:x == x'
y:Z

x ^ y == x' ^ y
destruct y; simpl; rewrite ?Hx; auto with *. Qed.