Inductive sum_worlds {worlds1 worlds2}: Type:
    Type:=
  | lw (w:worlds1): sum_worlds
  | rw (w:worlds2): sum_worlds.Inductive sum_worlds {worlds1 worlds2}: Type:
    Type:=
  | lw (w:worlds1): sum_worlds
  | rw (w:worlds2): sum_worlds.Inductive sum_worlds {worlds1 worlds2}: Type:
    Type:=
  | lw (w:worlds1): sum_worlds
  | rw (w:worlds2): sum_worlds.Inductive sum_join {A B: Type} {J1: Join A} {J2: Join B}:
    @sum_worlds A B ->
    @sum_worlds A B ->
    @sum_worlds A B-> Prop :=
  | left_join a b c:
      join a b c ->
      sum_join (lw a) (lw b) (lw c)
  | right_join a b c:
      join a b c ->
      sum_join (rw a) (rw b) (rw c).Inductive sum_join {A B: Type} {J1: Join A} {J2: Join B}:
    @sum_worlds A B ->
    @sum_worlds A B ->
    @sum_worlds A B-> Prop :=
  | left_join a b c:
      join a b c ->
      sum_join (lw a) (lw b) (lw c)
  | right_join a b c:
      join a b c ->
      sum_join (rw a) (rw b) (rw c).Inductive sum_join {A B: Type} {J1: Join A} {J2: Join B}:
    @sum_worlds A B ->
    @sum_worlds A B ->
    @sum_worlds A B-> Prop :=
  | left_join a b c:
      join a b c ->
      sum_join (lw a) (lw b) (lw c)
  | right_join a b c:
      join a b c ->
      sum_join (rw a) (rw b) (rw c).Definition sum_Join (A B: Type) {Join_A: Join A} {Join_B: Join B}: Join (@sum_worlds A B) :=
    (@sum_join A B Join_A Join_B).Definition sum_SA (A B: Type) {Join_A: Join A} {Join_B: Join B} {SA_A: SeparationAlgebra A} {SA_B: SeparationAlgebra B}: @SeparationAlgebra (@sum_worlds A B) (sum_Join A B).Definition prod_Join (A B: Type) {Join_A: Join A} {Join_B: Join B}: Join (A * B) :=
    (fun a b c => join (fst a) (fst b) (fst c) /\ join (snd a) (snd b) (snd c)).Definition prod_SA (A B: Type) {Join_A: Join A} {Join_B: Join B} {SA_A: SeparationAlgebra A} {SA_B: SeparationAlgebra B}: @SeparationAlgebra (A * B) (prod_Join A B).

(* Specifications: *)
Lemma prod_uSA (A B: Type) {R_A: Relation A} {R_B: Relation B} {Join_A: Join A} {Join_B: Join B} {dSA_A: UpwardsClosedSeparationAlgebra A} {dSA_B: UpwardsClosedSeparationAlgebra B}: @UpwardsClosedSeparationAlgebra (A * B) (RelProd R_A R_B) (@prod_Join _ _ Join_A Join_B).
Lemma prod_dSA (A B: Type) {R_A: Relation A} {R_B: Relation B} {Join_A: Join A} {Join_B: Join B} {uSA_A: DownwardsClosedSeparationAlgebra A} {uSA_B: DownwardsClosedSeparationAlgebra B}: @DownwardsClosedSeparationAlgebra (A * B) (RelProd R_A R_B) (@prod_Join _ _ Join_A Join_B).
Lemma prod_incr (A B: Type) {R_A: Relation A} {R_B: Relation B} {Join_A: Join A} {Join_B: Join B}: forall (a: A) (b: B), increasing a -> increasing b -> @increasing _ (RelProd R_A R_B) (@prod_Join _ _ Join_A Join_B) (a,b).
Lemma prod_incrSA (A B: Type) {R_A: Relation A} {R_B: Relation B} {Join_A: Join A} {Join_B: Join B} {incrSA_A: IncreasingSeparationAlgebra A} {incrSA_B: IncreasingSeparationAlgebra B}: @IncreasingSeparationAlgebra (A * B) (RelProd R_A R_B) (@prod_Join _ _ Join_A Join_B).
Lemma prod_residualSA (A B: Type) {R_A: Relation A} {R_B: Relation B} {Join_A: Join A} {Join_B: Join B} {residualSA_A: ResidualSeparationAlgebra A} {residualSA_B: ResidualSeparationAlgebra B}: @ResidualSeparationAlgebra (A * B) (RelProd R_A R_B) (@prod_Join _ _ Join_A Join_B).
Lemma prod_unitalSA (A B: Type) {R_A: Relation A} {R_B: Relation B} {Join_A: Join A} {Join_B: Join B} {unitalSA_A: UnitalSeparationAlgebra A} {unitalSA_B: UnitalSeparationAlgebra B}: @UnitalSeparationAlgebra (A * B) (RelProd R_A R_B) (@prod_Join _ _ Join_A Join_B).