Section ClosureRelations.
Variables (X: Type).
Implicit Types (R S: X -> X -> Prop) (x y z : X).
Notation "R <<= S" := (subrelation R S) (at level 70).
Notation "R === S" := (R <<= S /\ S <<= R) (at level 70).
Definition functional R :=
forall x y z, R x y -> R x z -> y = z.
Inductive star R : X -> X -> Prop :=
| starRefl x     : star R x x
| starStep x x' y : R x x' -> star R x' y -> star R x y.
Inductive multiple R : X -> X -> Prop :=
| multipleSingle x y: R x y -> multiple R x y
| multipleStep x x' y: R x x' -> multiple R x' y -> multiple R x y.
Inductive counted R : nat -> X -> X -> Prop :=
| countedRefl x: counted R 0 x x
| countedStep x x' y n: R x x' -> counted R n x' y -> counted R (S n) x y.
Inductive sym R: X -> X -> Prop :=
| symId x y: R x y -> sym R x y
| symInv x y: R y x -> sym R x y.
Hint Constructors star multiple counted : core.
Definition Normal R x := forall y, ~ R x y.
Definition evaluates R s t := star R s t /\ Normal R t.
Definition equiv R := star (sym R).
Fact Normal_star_stops R x:
Normal R x -> forall y, star R x y -> x = y.
Fact counted_trans R x y z m n:
counted R m x y -> counted R n y z -> counted R (m + n) x z.
Global Instance multiple_transitive R:
Transitive (multiple R).
Global Instance star_preorder R: PreOrder (star R).
Global Instance star_exp R:
R <<= star R.
Global Instance multiple_exp R:
R <<= multiple R.
Fact counted_exp R:
R === counted R 1.
Global Instance multiple_star R : multiple R <<= star R.
Hint Resolve star_trans multiple_trans counted_trans star_exp
multiple_exp counted_exp : core.
Global Instance star_mono R S :
R <<= S -> star R <<= star S.
Global Instance multiple_mono R S :
R <<= S -> multiple R <<= multiple S.
Global Instance eval_subrel R:
(evaluates R) <<= (star R).
Fact star_idem R :
star (star R) === star R.
Fact multiple_idem R :
multiple (multiple R) === multiple R.
Fact multiple_fixpoint R :
multiple (star R) === star R.
Fact star_absorbtion R :
star (multiple R) === star R.
Global Instance sym_Symmetric R:
Symmetric (sym R).
Global Instance equiv_star R:
star R <<= equiv R.
Global Instance equiv_rel R:
R <<= equiv R.

Lemma equiv_reduce R x x' y y' :
star R x x' -> star R y y' -> equiv R x y -> equiv R x' y'.