(************************************************************************)
(*         *      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)         *)
(************************************************************************)
(** * Typeclass-based morphism definition and standard, minimal instances  Author: Matthieu Sozeau Institution: LRI, CNRS UMR 8623 - University Paris Sud *)
Require Export Corelib.Classes.CRelationClasses.
Generalizable Variables A eqA B C D R RA RB RC m f x y.
Local Obligation Tactic := try solve [ simpl_crelation ].
Local Arguments transitivity {A R Transitive x} y {z}.
Set Universe Polymorphism.
(** * Morphisms.  We now turn to the definition of [Proper] and declare standard instances. These will be used by the [setoid_rewrite] tactic later. *)
(** A morphism for a relation [R] is a proper element of the relation. The relation [R] will be instantiated by [respectful] and [A] by an arrow type for usual morphisms. *)
Section Proper.
Context {A : Type}.
Class Proper (R : crelation A) (m : A) :=
proper_prf : R m m.
(** Every element in the carrier of a reflexive relation is a morphism for this relation.  We use a proxy class for this case which is used internally to discharge reflexivity constraints.  The [Reflexive] instance will almost always be used, but it won't apply in general to any kind of [Proper (A -> B) _ _] goal, making proof-search much slower. A cleaner solution would be to be able to set different priorities in different hint bases and select a particular hint database for resolution of a type class constraint. *)
Class ProperProxy (R : crelation A) (m : A) :=
proper_proxy : R m m.

(* Specifications: *)
Lemma eq_proper_proxy (x : A) : ProperProxy (@eq A) x.
Global Instance subrelation_id_proper `(subrelation A RA RA') : Proper (RA ==> RA') id.