(************************************************************************)
(*         *      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)         *)
(************************************************************************)
(** [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] *)

(* Specifications: *)
Lemma Qred_identity :
forall q:Q, Z.gcd (Qnum q) (QDen q) = 1%Z -> Qred q = q.
Lemma Qred_identity2 :
forall q:Q, Qred q = q -> Z.gcd (Qnum q) (QDen q) = 1%Z.
Lemma Qred_iff : forall q:Q, Qred q = q <-> Z.gcd (Qnum q) (QDen q) = 1%Z.
(** Coercion from [Qc] to [Q] and equality *)
Lemma Qc_is_canon : forall q q' : Qc, q == q' -> q = q'.
#[global]
Hint Resolve Qc_is_canon : core.
Theorem Qc_decomp: forall q q': Qc, (q:Q) = q' -> q = q'.
(** [Q2Qc] : a conversion from [Q] to [Qc]. *)
Lemma Qred_involutive : forall q:Q, Qred (Qred q) = Qred q.
Definition Q2Qc (q:Q) : Qc := Qcmake (Qred q) (Qred_involutive q).