Hint Extern 2 (PreOrder (_ + _)) =>
eapply sum_rel_preorder : typeclass_instances.
(** *** Pairs *)
Definition prod_rel {A1 A2 B1 B2} RA RB: rel (A1 * B1)%type (A2 * B2)%type :=
fun x1 x2 => RA (fst x1) (fst x2) /\ RB (snd x1) (snd x2).
Infix "*" := prod_rel : rel_scope.
Global Instance pair_rel:
Monotonic (@pair) (forallr RA, forallr RB, RA ++> RB ++> RA * RB).
Global Instance fst_rel:
Monotonic (@fst) (forallr RA, forallr RB, RA * RB ==> RA).
Global Instance snd_rel:
Monotonic (@snd) (forallr RA, forallr RB, RA * RB ==> RB).
Global Instance prod_subrel {A1 A2 B1 B2}:
Monotonic (@prod_rel A1 A2 B1 B2) (subrel ++> subrel ++> subrel).
Global Instance prod_subrel_params:
Params (@prod_rel) 4.
Global Instance prod_rdestruct {A1 B1 A2 B2} (RA: rel A1 A2) (RB: rel B1 B2):
RDestruct
(RA * RB)%rel
(fun P => forall a1 a2 b1 b2, RA a1 a2 -> RB b1 b2 -> P (a1, b1) (a2, b2)).

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