Set Implicit Arguments.
Set Strict Implicit.
Set Asymmetric Patterns.
Section parametric.
Variable T : Type.
Variable R : T -> T -> Prop.
(** Reflexivity **)
Inductive makeRefl (x : T) : T -> Prop :=
| RRefl : makeRefl x x
| RStep : forall y, R x y -> makeRefl x y.
Global Instance Refl_makeRefl : Reflexive makeRefl.
Global Instance Refl_makeTrans : Transitive R -> Transitive makeRefl.
(** Transitivity **)
Inductive makeTrans (x y : T) : Prop :=
| TStep : R x y -> makeTrans x y
| TTrans : forall z, makeTrans x z -> makeTrans z y -> makeTrans x y.
Global Instance Trans_makeTrans : Transitive makeTrans.
Global Instance Trans_makeRefl : Reflexive R -> Reflexive makeTrans.
Inductive leftTrans (x y : T) : Prop :=
| LTFin : R x y -> leftTrans x y
| LTStep : forall z, R x z -> leftTrans z y -> leftTrans x y.
Inductive rightTrans (x y : T) : Prop :=
| RTFin : R x y -> rightTrans x y
| RTStep : forall z, rightTrans x z -> R z y -> rightTrans x y.
(** Equivalence of definitions of transitivity **)
Fixpoint leftTrans_rightTrans_acc x y (l : leftTrans y x) : forall z, rightTrans z y -> rightTrans z x :=
match l with
| LTFin pf => fun z pfR => RTStep pfR pf
| LTStep _ pf pfL => fun z pfR =>
leftTrans_rightTrans_acc pfL (RTStep pfR pf)
end.
Fixpoint rightTrans_leftTrans_acc x y (l : rightTrans x y) : forall z, leftTrans y z -> leftTrans x z :=
match l with
| RTFin pf => fun z pfR => LTStep pf pfR
| RTStep _ pf pfL => fun z pfR =>
rightTrans_leftTrans_acc pf (LTStep pfL pfR)
end.

(* Specifications: *)
Theorem leftTrans_rightTrans : forall x y,
leftTrans x y <-> rightTrans x y.