Local Open Scope logic_base.
Local Open Scope syntax.
Local Open Scope kripke_model.
Class ModalBisJoin (worlds: Type) {R2: KM.Relation worlds} {J: Join worlds} := {
KM_join_bis: forall m n, R2 m n ->
(forall n1 n2, join n1 n2 n ->
exists m1 m2, join m1 m2 m /\ R2 m1 n1 /\ R2 m2 n2) /\
(forall m1 m2, join m1 m2 m ->
exists n1 n2, join n1 n2 n /\ R2 m1 n1 /\ R2 m2 n2)
}.
Instance prod_KM_bis_J (A B: Type) (RA: KM.Relation A) (RB: KM.Relation B) (JA: Join A) (JB: Join B) {KM_bis_JA: ModalBisJoin A} {KM_bis_JB: ModalBisJoin B}: @ModalBisJoin (A * B) (RelProd RA RB) (@prod_Join _ _ JA JB).
Instance eq_bis_J (A: Type) (J: Join A): @ModalBisJoin A eq J.

(* Specifications: *)
Lemma sound_sepcon_boxp {L: Language} {nL: NormalLanguage L} {pL: PropositionalLanguage L} {mL: ModalLanguage L} {sL: SeparationLanguage L} {MD: Model} {kMD: KripkeModel MD} {M: Kmodel} {R1: KI.Relation (Kworlds M)} {R2: KM.Relation (Kworlds M)} {J: Join (Kworlds M)} {KM_bis_J: ModalBisJoin (Kworlds M)} {SM: Semantics L MD} {kiSM: KripkeIntuitionisticSemantics L MD M SM} {fm: FlatModalSemantics L MD M SM} {fsSM: SeparatingSemantics L MD M SM}:
forall x y: expr,
forall m: Kworlds M, KRIPKE: M, m |= boxp x * boxp y --> boxp (x * y).