(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *   INRIA, CNRS and contributors - Copyright 1999-2019       *)
(* <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)         *)
(************************************************************************)
(************************************************************************)
(** Morphisms used to transport results from any instance of ConstructiveReals to any other. Between any two constructive reals structures R1 and R2, all morphisms R1 -> R2 are extensionally equal. We will further show that they exist, and so are isomorphisms. The difference between two morphisms R1 -> R2 is therefore the speed of computation.  The canonical isomorphisms we provide here are often very slow, when a new implementation of constructive reals is added, it should define its own ad hoc isomorphisms for better speed.  Apart from the speed, those unique isomorphisms also serve as sanity checks of the interface ConstructiveReals : it captures a concept with a strong notion of uniqueness.  WARNING: this file is experimental and likely to change in future releases. *)
Local Open Scope ConstructiveReals.
Record ConstructiveRealsMorphism {R1 R2 : ConstructiveReals} : Set :=
{
CRmorph : CRcarrier R1 -> CRcarrier R2;
CRmorph_rat : forall q : Q,
CRmorph (CR_of_Q R1 q) == CR_of_Q R2 q;
CRmorph_increasing : forall x y : CRcarrier R1,
CRlt R1 x y -> CRlt R2 (CRmorph x) (CRmorph y);
}.

(* Specifications: *)
Lemma CRmorph_increasing_inv
: forall {R1 R2 : ConstructiveReals}
(f : ConstructiveRealsMorphism)
(x y : CRcarrier R1),
CRlt R2 (CRmorph f x) (CRmorph f y)
-> CRlt R1 x y.
Lemma CRmorph_unique : forall {R1 R2 : ConstructiveReals}
(f g : @ConstructiveRealsMorphism R1 R2)
(x : CRcarrier R1),
CRmorph f x == CRmorph g x.
(* The identity is the only endomorphism of constructive reals. For any ConstructiveReals R1, R2 and any morphisms f : R1 -> R2 and g : R2 -> R1, f and g are isomorphisms and are inverses of each other. *)
Lemma Endomorph_id
: forall {R : ConstructiveReals} (f : @ConstructiveRealsMorphism R R)
(x : CRcarrier R),
CRmorph f x == x.
Lemma CRmorph_proper
: forall {R1 R2 : ConstructiveReals}
(f : @ConstructiveRealsMorphism R1 R2)
(x y : CRcarrier R1),
x == y -> CRmorph f x == CRmorph f y.