Require Export Coq.Classes.RelationClasses.
Require Export RelDefinitions.
(** * More classes for relation properties *)
(** In the following we introduce more typeclasses for characterizing properties of relations, in the spirit of the [RelationClasses] standard library. *)
(** ** Coreflexive relations *)
Class Coreflexive {A} (R: relation A) :=
coreflexivity: forall x y, R x y -> x = y.
Global Instance eq_corefl {A}:
Coreflexive (@eq A).
Global Instance subrel_eq {A} (R: relation A):
Coreflexive R ->
Related R eq subrel.
(** ** Composition *)
Class RCompose {A B C} (RAB : rel A B) (RBC : rel B C) (RAC : rel A C) :=
rcompose : forall x y z, RAB x y -> RBC y z -> RAC x z.
Ltac rcompose b :=
lazymatch goal with
| |- ?R ?a ?c =>
apply (rcompose a b c)
end.
Ltac ercompose :=
eapply rcompose.
(** [Transitive] is a special case of [RCompose]. The following makes it possible for the [transitivity] tactic to use [RCompose] instances. *)
Global Instance rcompose_transitive {A} (R : relation A) :
RCompose R R R -> Transitive R.
(** Conversely, we will want to use declared [Transitive] instances to satisfy [RCompose] queries. To avoid loops in the resolution process this is only declared as an immediate hint --- we expect all derived instances to be formulated in terms of [RCompose] rather than [Transitive]. *)

Lemma transitive_rcompose `(Transitive) :
RCompose R R R.