Set Implicit Arguments.
Unset Strict Implicit.
Set Maximal Implicit Insertion.
Section RelProducts.
Context {A B : Type} {relA : relation A} {relB : relation B}.
Context {HA: Equivalence relA}.
Context {HB: Equivalence relB}.
Definition rel_prod : relation (A * B) :=
fun p1 p2 => (relA (fst p1) (fst p2) /\ relB (snd p1) (snd p2)).
Global Instance prod_proper : Proper (relA ==> relB ==> rel_prod) (@pair A B).
Global Instance equiv_prod : Equivalence rel_prod.
End RelProducts.
Section SAProd.
Context A B `{HA: SepAlg A} `{HB: SepAlg B}.
Instance SepAlgOps_prod: SepAlgOps (A * B) :=
{ sa_unit ab := sa_unit (fst ab) /\ sa_unit (snd ab)
; sa_mul a b c :=
sa_mul (fst a) (fst b) (fst c) /\
sa_mul (snd a) (snd b) (snd c)
}.
Definition SepAlg_prod: SepAlg (rel := rel_prod (relA := rel) (relB := rel0)) (A * B).

(* Specifications: *)
Lemma subheap_prod (a a' : A) (b b' : B)
: subheap (a, b) (a', b') <-> subheap a a' /\ subheap b b'.
Lemma sa_mul_split (a b c : A) (a' b' c' : B)
: sa_mul (a, a') (b, b') (c, c') <-> sa_mul a b c /\ sa_mul a' b' c'.