(************************************************************************)
(*         *   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)         *)
(************************************************************************)
(** [Qc] : A canonical representation of rational numbers. based on the setoid representation [Q]. *)
Record Qc : Set := Qcmake { this :> Q ; canon : Qred this = this }.
Declare Scope Qc_scope.
Delimit Scope Qc_scope with Qc.
Bind Scope Qc_scope with Qc.
Arguments Qcmake this%Q _.
Open Scope Qc_scope.
(** An alternative statement of [Qred q = q] via [Z.gcd] *)
(** Coercion from [Qc] to [Q] and equality *)
Hint Resolve Qc_is_canon : core.
(** [Q2Qc] : a conversion from [Q] to [Qc]. *)
Definition Q2Qc (q:Q) : Qc := Qcmake (Qred q) (Qred_involutive q).
Arguments Q2Qc q%Q.
Notation " 0 " := (Q2Qc 0) : Qc_scope.
Notation " 1 " := (Q2Qc 1) : Qc_scope.
Definition Qcle (x y : Qc) := (x <= y)%Q.
Definition Qclt (x y : Qc) := (x < y)%Q.
Notation Qcgt := (fun x y : Qc => Qlt y x).
Notation Qcge := (fun x y : Qc => Qle y x).
Infix "<" := Qclt : Qc_scope.
Infix "<=" := Qcle : Qc_scope.
Infix ">" := Qcgt : Qc_scope.
Infix ">=" := Qcge : Qc_scope.
Notation "x <= y <= z" := (x<=y/\y<=z) : Qc_scope.
Notation "x < y < z" := (x<y/\y<z) : Qc_scope.
Definition Qccompare (p q : Qc) := (Qcompare p q).
Notation "p ?= q" := (Qccompare p q) : Qc_scope.
(** equality on [Qc] is decidable: *)
Ltac qc := match goal with
| q:Qc |- _ => destruct q; qc
| _ => apply Qc_is_canon; simpl; rewrite !Qred_correct
end.
Opaque Qred.
(** Addition is associative: *)
(** [0] is a neutral element for addition: *)
(** Commutativity of addition: *)
(** Properties of [Qopp] *)
(** Multiplication is associative: *)
(** [0] is absorbing for multiplication: *)
(** [1] is a neutral element for multiplication: *)
(** Commutativity of multiplication *)
(** Distributivity *)
(** Integrality *)
(** Inverse and division. *)
(** Properties of order upon Qc. *)
(** Large = strict or equal *)
(** [x<y] iff [~(y<=x)] *)
(** Some decidability results about orders. *)
(** Rational to the n-th power *)
Fixpoint Qcpower (q:Qc)(n:nat) : Qc :=
match n with
| O => 1
| S n => q * (Qcpower q n)
end.
Notation " q ^ n " := (Qcpower q n) : Qc_scope.
(** And now everything is easier concerning tactics: *)
(** A ring tactic for rational numbers *)
Definition Qc_eq_bool (x y : Qc) :=
if Qc_eq_dec x y then true else false.

Lemma Qc_eq_bool_correct : forall x y : Qc, Qc_eq_bool x y = true -> x=y.