(** * 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.(** * 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.

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