(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *         Copyright INRIA, CNRS and contributors             *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(*   \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_base.
Require Export ZArithRing.
Require Export ZArith.BinInt.
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 hex_Q_scope.
Delimit Scope hex_Q_scope with xQ.
Declare Scope Q_scope.
Delimit Scope Q_scope with Q.
Bind Scope Q_scope with Q.
Arguments Qmake _%_Z _%_positive.
Register Q as rat.Q.type.
Register Qmake as rat.Q.Qmake.
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 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.
Notation "x <= y < z" := (x<=y/\y<z) : Q_scope.
Notation "x < y <= z" := (x<y/\y<=z) : Q_scope.
Notation "x < y < z" := (x<y/\y<z) : Q_scope.
Register Qeq as rat.Q.Qeq.
Register Qle as rat.Q.Qle.
Register Qlt as rat.Q.Qlt.
(** Qeq construction from parts. Establishing equality by establishing equality for numerator and denominator separately. *)

(* Specifications: *)
Lemma Qden_cancel : forall (a b : Z) (p : positive),
(a#p)==(b#p) -> a=b.
Lemma Qnum_cancel : forall (a b : positive) (z : Z),
z<>0%Z -> (z#a)==(z#b) -> a=b.