Hint Extern 1 (Reflexive (set_ge _)) =>
eapply set_ge_refl : typeclass_instances.
Global Instance set_ge_compose `(RCompose) :
RCompose (set_ge RAB) (set_ge RBC) (set_ge RAC).
(** ** Inductive types *)
(** For inductive types, there is a systematic way of converting their definition into that of the corresponding relator. Where the original inductive definition quantifies over types, the corresponding relator will quantify over pairs of types and relations between them. Then, the constructors of the relator will essentially be [Proper] instances for the original constructors. In other words, the resulting relation will be the smallest one such that the constructors are order-preserving. *)
(** *** Nullary type constructors *)
(** As a proof-of-concept, we start with the most elementary types [Empty_set] and [unit], which can be considered as nullary type constructors related to [sum] and [prod] below. *)
Inductive Empty_set_rel: rel Empty_set Empty_set := .
Inductive unit_rel: rel unit unit :=
tt_rel: Proper unit_rel tt.
Global Existing Instance tt_rel.
(** *** Sum types *)
(** The definition of [sum_rel] could look something like this: << Inductive sum_rel: forall {A1 A2 B1 B2}, rel A1 A2 -> rel B1 B2 -> rel (A1+B1) (A2+B2):= | inl_rel: Proper (∀ RA : rel, ∀ RB : rel, RA ++> sum_rel RA RB) (@inl) | inr_rel: Proper (∀ RA : rel, ∀ RB : rel, RB ++> sum_rel RA RB) (@inr). >> However, to minimize the need for [inversion]s we want to keep as many arguments as possible as parameters of the inductive type. *)
Inductive sum_rel {A1 A2 B1 B2} RA RB: rel (A1 + B1)%type (A2 + B2)%type :=
| inl_rel_def: (RA ++> sum_rel RA RB)%rel (@inl A1 B1) (@inl A2 B2)
| inr_rel_def: (RB ++> sum_rel RA RB)%rel (@inr A1 B1) (@inr A2 B2).
Infix "+" := sum_rel : rel_scope.
(** Since it is not possible to retype the constructors after the fact, we use the [_def] suffix when defining them, then redeclare a corresponding, full-blown [Proper] instance. *)
Global Instance inl_rel:
Monotonic (@inl) (forallr RA, forallr RB, RA ++> RA + RB).
Global Instance inr_rel:
Monotonic (@inr) (forallr RA, forallr RB, RB ++> RA + RB).
Global Instance sum_subrel {A1 A2 B1 B2}:
Monotonic (@sum_rel A1 A2 B1 B2) (subrel ++> subrel ++> subrel).
Global Instance sum_subrel_params:
Params (@sum) 4.

(* Specifications: *)
Lemma sum_rel_refl {A B} (R1: rel A A) (R2: rel B B):
Reflexive R1 -> Reflexive R2 -> Reflexive (R1 + R2).