(** *** 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 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).
Lemma prod_rel_corefl {A B} (R1: rel A A) (R2: rel B B): Coreflexive R1 -> Coreflexive R2 -> Coreflexive (R1 * R2).
Lemma prod_rel_trans {A B} (R1: rel A A) (R2: rel B B): Transitive R1 -> Transitive R2 -> Transitive (R1 * R2).
Lemma prod_rel_sym {A B} (R1: rel A A) (R2: rel B B): Symmetric R1 -> Symmetric R2 -> Symmetric (R1 * R2).
Lemma prod_rel_preorder {A B} (R1: rel A A) (R2: rel B B): PreOrder R1 -> PreOrder R2 -> PreOrder (R1 * R2).