Up to index of Isabelle/HOL/CoreSafe
theory TypeEnvironment(* Title: TypeEnvironment Author: Javier de Dios and Ricardo Peņa Copyright: June 2008, Universidad Complutense de Madrid *) header {* Type Environment and operators *} (*<*) theory TypeEnvironment imports Main begin (*>*) text{* Non-functional algebraic types may be safe types s'', condemned types d'' or indanger types r''. *} datatype Mark = s'' | d'' | r'' text{* A type environment is a partial mapping from program variables to marks. *} types TypeEnvironment = "string \<rightharpoonup> Mark" text{* Some auxiliary predicates: 'unsafe' is true for condemned and in-danger types, 'safe' is true for safe types. *} constdefs unsafe :: "Mark option => bool" "unsafe x ≡ (x = Some d'') ∨ (x = Some r'')" constdefs safe :: "Mark option => bool" "safe x ≡ (x = Some s'')" subsection {* Operators on type environments *} constdefs unionEnv :: "TypeEnvironment => TypeEnvironment => TypeEnvironment" "unionEnv Γ1 Γ2 ≡ (%x. if x: dom Γ1 then Γ1 x else Γ2 x)" text{* Operator +: Disjoint union of environments *} constdefs def_disjointUnionEnv :: "TypeEnvironment => TypeEnvironment => bool" "def_disjointUnionEnv Γ1 Γ2 ≡ dom Γ1 ∩ dom Γ2 = {}" constdefs disjointUnionEnv :: "TypeEnvironment => TypeEnvironment => TypeEnvironment" (infix "+" 100) "Γ1 + Γ2 ≡ unionEnv Γ1 Γ2" text{* Operator $\otimes$ : It allows to join two non-disjoint environments provided they map the common variables to the same types. *} constdefs def_nonDisjointUnionEnv :: "TypeEnvironment => TypeEnvironment => bool" "def_nonDisjointUnionEnv Γ1 Γ2 ≡ (∀x ∈ dom Γ1 ∩ dom Γ2. Γ1 x = Γ2 x)" constdefs nonDisjointUnionEnv :: "TypeEnvironment => TypeEnvironment => TypeEnvironment" (infixl "⊗" 60) "Γ1 ⊗ Γ2 ≡ unionEnv Γ1 Γ2" text{* Operator $\otimes$ : It allows to join n-non-disjoint environments provided they map the common variables to the same types. *} fun nonDisjointUnionEnvList :: "TypeEnvironment list => TypeEnvironment" where "nonDisjointUnionEnvList Γs = foldl nonDisjointUnionEnv empty Γs" fun def_nonDisjointUnionEnvList :: "TypeEnvironment list => bool" where "def_nonDisjointUnionEnvList [] = True" | "def_nonDisjointUnionEnvList (G#Gs) = (let Gs' = nonDisjointUnionEnvList Gs; def_Gs' = def_nonDisjointUnionEnvList Gs in def_nonDisjointUnionEnv G Gs' ∧ def_Gs' )" text{* Operator $\oplus$ : It allows to join two non-disjoint environments provided they map the common variables to the same safe types. *} constdefs def_nonDisjointUnionSafeEnv :: "TypeEnvironment => TypeEnvironment => bool" "def_nonDisjointUnionSafeEnv Γ1 Γ2 ≡ (∀x ∈ dom Γ1 ∩ dom Γ2. safe (Γ1 x) ∧ safe (Γ2 x))" constdefs nonDisjointUnionSafeEnv :: "TypeEnvironment => TypeEnvironment => TypeEnvironment" (infixl "⊕" 60) "Γ1 ⊕ Γ2 ≡ unionEnv Γ1 Γ2" fun nonDisjointUnionSafeEnvList :: "TypeEnvironment list => TypeEnvironment" where "nonDisjointUnionSafeEnvList Γs = foldl nonDisjointUnionSafeEnv empty Γs" fun def_nonDisjointUnionSafeEnvList :: "TypeEnvironment list => bool" where "def_nonDisjointUnionSafeEnvList [] = True" | "def_nonDisjointUnionSafeEnvList (G#Gs) = (let Gs' = nonDisjointUnionSafeEnvList Gs; def_Gs' = def_nonDisjointUnionSafeEnvList Gs in def_nonDisjointUnionSafeEnv G Gs' ∧ def_Gs' )" text{* Operator $\triangleright$ : This is used in rules for let. In the union $\Gamma$1 $\triangleright$ $\Gamma$2 not allowed that variables in L may have unsafe type in $\Gamma$1 . Also, variables common to $\Gamma$2 and L may not have unsafe type in $\Gamma$2. Once well defined, in environment $\Gamma$1 $\triangleright$ $\Gamma$2 the types assigned in $\Gamma$2 to common variables, will prevail. *} constdefs def_pp :: "TypeEnvironment => TypeEnvironment => string set => bool" "def_pp Γ1 Γ2 L ≡ (∀x. x ∈ dom Γ1 --> unsafe (Γ1 x) --> x ∉ L ∧ (x ∉ dom Γ2 ∨ (Γ2 x ≠ Some s'' ∧ Γ2 x ≠ Some d''))) ∧ (∀x. x ∈ dom Γ2 ∧ (Γ2 x = Some s'' ∨ Γ2 x = Some d'') --> x ∈ L)" constdefs pp :: "TypeEnvironment => TypeEnvironment => string set => TypeEnvironment" ("_\<triangleright>_ _") "Γ1 \<triangleright> Γ2 L ≡ (%x. (if x ∉ dom Γ1 ∨ (x ∈ dom Γ1 ∩ dom Γ2 ∧ safe (Γ1 x)) then Γ2 x else Γ1 x))" text{* Lemmas for unionEnv operator *} lemma empty_unionEnv: "unionEnv m empty = m" apply (rule ext) by (simp add: unionEnv_def split: option.split add: dom_def) lemma dom_empty_unionEnv: "dom (unionEnv m1 empty) = dom m1" apply (subgoal_tac "unionEnv m1 empty = m1") by (simp, rule empty_unionEnv) text{* Lemmas for disjointUnionEnv operator *} lemma empty_disjointUnionEnv: "disjointUnionEnv m empty = m" by (simp add: disjointUnionEnv_def, rule empty_unionEnv) lemma dom_empty_disjointUnionEnv: "dom (disjointUnionEnv m1 empty) = dom m1" by (simp add: disjointUnionEnv_def, rule dom_empty_unionEnv) lemma union_dom_disjointUnionEnv: "def_disjointUnionEnv Γ1 Γ2 ==> dom (disjointUnionEnv Γ1 Γ2) = dom Γ1 ∪ dom Γ2" apply (simp add: def_disjointUnionEnv_def add: disjointUnionEnv_def add: unionEnv_def, auto) by (split split_if_asm,simp,simp) lemma dom_disjointUnionEnv_monotone: "dom (G + G') = dom G ∪ dom G'" apply (simp add: disjointUnionEnv_def add: unionEnv_def, auto) by (split split_if_asm, simp, simp) text{* Lemmas for nonDisjointUnionEnv operator *} lemma empty_nonDisjointUnionEnv : "empty ⊗ A = A" by (simp add: nonDisjointUnionEnv_def add: unionEnv_def) lemma refl_nonDisjointUnionEnv : "A ⊗ A = A" by (simp add: nonDisjointUnionEnv_def add: unionEnv_def) lemma list_induct3: "[| P [] 0; !!x xs. P (x#xs) 0; !!i. P [] (Suc i); !!x xs i. P xs i ==> P (x#xs) (Suc i) |] ==> P xs i" by (induct xs arbitrary: i) (case_tac x, auto)+ lemma nonDisjointUnionEnv_conmutative: "def_nonDisjointUnionEnv G G' ==> (G ⊗ G') = (G' ⊗ G)" apply (simp add: nonDisjointUnionEnv_def add: unionEnv_def) apply (rule ext) by (simp add: def_nonDisjointUnionEnv_def,clarsimp) lemma nonDisjointUnionEnv_assoc: "(G1 ⊗ G2) ⊗ G3 = G1 ⊗ (G2 ⊗ G3)" apply (simp add: nonDisjointUnionEnv_def add: unionEnv_def) apply (rule ext, auto) apply (split split_if_asm, simp, simp) apply (split split_if_asm, simp,simp) by (split split_if_asm, simp, simp add: dom_def) lemma nonDisjointUnionEnv_disjointUnionEnv_assoc: "(G1 ⊗ G2) + G3 = G1 ⊗ (G2 + G3)" apply (simp add: nonDisjointUnionEnv_def add: disjointUnionEnv_def add: unionEnv_def) apply (rule ext, auto) apply (split split_if_asm, simp, simp) apply (split split_if_asm, simp,simp) by (split split_if_asm, simp, simp add: dom_def) lemma foldl_prop1: "foldl op ⊗ (G' ⊗ G) Gs = G' ⊗ foldl op ⊗ G Gs" apply (induct Gs arbitrary: G) apply simp by (simp_all add: nonDisjointUnionEnv_assoc) lemma foldl_prop2: "foldl op ⊗ (G' ⊗ G) Gs + G'' = G' ⊗ foldl op ⊗ G Gs + G''" apply (induct Gs arbitrary: G) apply (simp_all add: nonDisjointUnionEnv_assoc) by (rule nonDisjointUnionEnv_disjointUnionEnv_assoc) lemma union_dom_nonDisjointUnionEnv: " dom (A ⊗ B) = dom A ∪ dom B" apply (simp add: nonDisjointUnionEnv_def add: unionEnv_def,auto) by (split split_if_asm,simp_all) lemma union_dom_nonDisjointUnionEnv_disjointUnionEnv: " dom (A ⊗ B + [x \<mapsto> m]) = dom A ∪ dom (B + [x \<mapsto> m])" apply (simp add: nonDisjointUnionEnv_def add: unionEnv_def, auto) apply (split split_if_asm,simp) by simp lemma def_nonDisjointUnionEnvList_prop1: "def_nonDisjointUnionEnvList (x # xs) --> def_nonDisjointUnionEnv x (foldl op ⊗ empty xs)" by (simp add: Let_def) lemma dom_foldl_monotone: " dom (foldl op ⊗ (empty ⊗ snd a) (map snd assert)) = dom (snd a) ∪ dom (foldl op ⊗ empty (map snd assert))" apply (subgoal_tac "empty ⊗ snd a = snd a ⊗ empty",simp) apply (subgoal_tac "foldl op ⊗ (snd a ⊗ empty) (map snd assert) = (snd a) ⊗ foldl op ⊗ empty (map snd assert)",simp) apply (rule union_dom_nonDisjointUnionEnv) apply (rule foldl_prop1) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd a)") apply (erule nonDisjointUnionEnv_conmutative) by (simp add: def_nonDisjointUnionEnv_def) lemma dom_foldl_disjointUnionEnv_monotone: " dom (foldl op ⊗ (empty ⊗ snd a) (map snd assert) + [x \<mapsto> d'']) = dom (snd a) ∪ dom (foldl op ⊗ empty (map snd assert)) ∪ dom [x \<mapsto> d'']" apply (subgoal_tac "empty ⊗ snd a = snd a ⊗ empty",simp) apply (subgoal_tac "foldl op ⊗ (snd a ⊗ empty) (map snd assert) = (snd a) ⊗ foldl op ⊗ empty (map snd assert)",simp) apply (subst dom_disjointUnionEnv_monotone) apply (subst union_dom_nonDisjointUnionEnv) apply simp apply (rule foldl_prop1) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd a)") apply (erule nonDisjointUnionEnv_conmutative) by (simp add: def_nonDisjointUnionEnv_def) lemma dom_monotone: " length assert > i ==> dom (snd (assert ! i)) ⊆ dom (foldl op ⊗ empty (map snd assert))" apply (induct assert i rule: list_induct3, simp_all) apply (subgoal_tac " dom (foldl op ⊗ (empty ⊗ snd x) (map snd xs)) = dom (snd x) ∪ dom (foldl op ⊗ empty (map snd xs))",simp) apply blast apply (rule dom_foldl_monotone) apply (subgoal_tac " dom (foldl op ⊗ (empty ⊗ snd x) (map snd xs)) = dom (snd x) ∪ dom (foldl op ⊗ empty (map snd xs))",simp) apply blast by (rule dom_foldl_monotone) lemma dom_monotone_foldl_nonDijointUnionEnv: "length assert > i ==> dom (snd (assert ! i)) ⊆ dom (foldl op ⊗ empty (map snd assert) + [x \<mapsto> d''])" apply (induct assert i rule: list_induct3, simp_all) apply (subgoal_tac " dom (foldl op ⊗ (empty ⊗ snd xa) (map snd xs) + [x \<mapsto> d'']) = dom (snd xa) ∪ dom (foldl op ⊗ empty (map snd xs)) ∪ dom [x \<mapsto> d'']",simp) apply blast apply (rule dom_foldl_disjointUnionEnv_monotone) apply (subgoal_tac " dom (foldl op ⊗ (empty ⊗ snd xa) (map snd xs) + [x \<mapsto> d'']) = dom (snd xa) ∪ dom (foldl op ⊗ empty (map snd xs)) ∪ dom [x \<mapsto> d'']",simp) apply (subgoal_tac "dom (foldl op ⊗ empty (map snd xs) + [x \<mapsto> d'']) = dom (foldl op ⊗ empty (map snd xs)) ∪ dom [x \<mapsto> d'']",simp) apply blast apply (rule dom_disjointUnionEnv_monotone) by (rule dom_foldl_disjointUnionEnv_monotone) lemma dom_Γi_subseteq_dom_Γ_case: " length assert > 0 ==> (∀i< length assert. dom (snd (assert ! i)) ⊆ dom (foldl op ⊗ empty (map snd assert)))" apply (induct assert) apply simp apply (case_tac "assert = []") apply (simp add: nonDisjointUnionEnv_def add: unionEnv_def,simp) apply (rule allI) apply (subgoal_tac " dom (foldl op ⊗ (empty ⊗ snd a) (map snd assert)) = dom (snd a) ∪ dom (foldl op ⊗ empty (map snd assert))",simp) apply (case_tac i) apply (simp,blast) apply simp apply (erule_tac x="nat" in allE) apply (blast,simp) apply (subgoal_tac "empty ⊗ snd a = snd a ⊗ empty",simp) apply (subgoal_tac "foldl op ⊗ (snd a ⊗ empty) (map snd assert) = (snd a) ⊗ foldl op ⊗ empty (map snd assert)",simp) apply (rule union_dom_nonDisjointUnionEnv) apply (rule foldl_prop1) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd a)") apply (erule nonDisjointUnionEnv_conmutative) by (simp add: def_nonDisjointUnionEnv_def) lemma dom_Γi_subseteq_dom_Γ_cased: " length assert > 0 ==> (∀i< length assert. dom (snd (assert ! i)) ⊆ dom (foldl op ⊗ empty (map snd assert) + [x \<mapsto> d'']))" apply (induct assert) apply simp apply (case_tac "assert = []") apply (simp add: nonDisjointUnionEnv_def add: unionEnv_def) apply (simp add: disjointUnionEnv_def add: unionEnv_def, clarsimp) apply (rule allI) apply (subgoal_tac " dom (foldl op ⊗ (empty ⊗ snd a) (map snd assert) + [x \<mapsto> d'']) = dom (snd a) ∪ dom (foldl op ⊗ empty (map snd assert) + [x \<mapsto> d''])",simp) apply (case_tac i) apply (simp,blast) apply simp apply (erule_tac x="nat" in allE) apply (blast,simp) apply (subgoal_tac "empty ⊗ snd a = snd a ⊗ empty",simp) apply (subgoal_tac "foldl op ⊗ (snd a ⊗ empty) (map snd assert) + [x \<mapsto> d''] = (snd a) ⊗ foldl op ⊗ empty (map snd assert) + [x \<mapsto> d'']",simp) apply (rule union_dom_nonDisjointUnionEnv_disjointUnionEnv) apply (rule foldl_prop2) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd a)") apply (erule nonDisjointUnionEnv_conmutative) by (simp add: def_nonDisjointUnionEnv_def) lemma nonDisjointUnionEnv_prop1: "(G ⊗ G') z = Some m ==> G z = Some m ∨ (z ∉ dom G ∧ G' z = Some m)" apply (simp add: nonDisjointUnionEnv_def add: unionEnv_def) by (split split_if_asm,simp_all) lemma nonDisjointUnionEnv_prop2: "[| def_nonDisjointUnionEnv G G'; (G ⊗ G') z = Some m |] ==> G' z = Some m ∨ (z ∉ dom G' ∧ G z = Some m)" apply (frule nonDisjointUnionEnv_conmutative,simp) by (erule nonDisjointUnionEnv_prop1) lemma nonDisjointUnionEnv_prop5: "[| x ∈ dom G; G x ≠ Some m |] ==> (G ⊗ G') x ≠ Some m" by (simp add: nonDisjointUnionEnv_def add: unionEnv_def) lemma nonDisjointUnionEnv_prop6: "[| def_nonDisjointUnionEnv G G'; z ∈ dom G'; G' z ≠ Some m |] ==> (G ⊗ G') z ≠ Some m" apply (simp add: def_nonDisjointUnionEnv_def) apply (erule_tac x="z" in ballE) apply (simp add: nonDisjointUnionEnv_def add: unionEnv_def) by (simp add: nonDisjointUnionEnv_def add: unionEnv_def) lemma nonDisjointUnionEnv_prop6_1: "[| x ∈ dom G; G x = Some m |] ==> (G ⊗ G') x = Some m" by (simp add: nonDisjointUnionEnv_def add: unionEnv_def) lemma nonDisjointUnionEnv_prop6_2: "[| def_nonDisjointUnionEnv G G'; G' z = Some m |] ==> (G ⊗ G') z = Some m" apply (simp add: def_nonDisjointUnionEnv_def) apply (erule_tac x="z" in ballE) apply (simp add: nonDisjointUnionEnv_def add: unionEnv_def) apply (simp add: nonDisjointUnionEnv_def add: unionEnv_def) by (rule impI, simp, simp add: dom_def) lemma Otimes_prop1: "i < length (map snd assert) --> length (map snd assert) > 0 --> def_nonDisjointUnionEnvList (map snd assert) --> foldl op ⊗ empty (map snd assert) z = Some d'' --> z ∈ dom (snd (assert ! i)) --> (snd (assert ! i)) z = Some d''" apply (induct assert i rule: list_induct3, simp_all) apply (intro impI) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd x)") prefer 2 apply (simp add: def_nonDisjointUnionEnv_def) apply (subgoal_tac "(empty ⊗ (snd x)) = ((snd x) ⊗ empty)" ,simp) prefer 2 apply (rule nonDisjointUnionEnv_conmutative,simp) apply (subgoal_tac "foldl op ⊗ (snd x ⊗ empty) (map snd xs) = (snd x) ⊗ foldl op ⊗ empty (map snd xs)",simp) prefer 2 apply (rule foldl_prop1) apply (frule nonDisjointUnionEnv_prop1) apply (erule disjE) apply (simp add: dom_def) apply (simp,intro impI,simp) apply (case_tac "xs=[]",simp) apply (simp add: Let_def) apply (elim conjE) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd x)") prefer 2 apply (simp add: def_nonDisjointUnionEnv_def) apply (subgoal_tac "(empty ⊗ snd x) = (snd x ⊗ empty)",simp) prefer 2 apply (rule nonDisjointUnionEnv_conmutative,simp) apply (subgoal_tac "foldl op ⊗ (snd x ⊗ empty) (map snd xs) = snd x ⊗ foldl op ⊗ empty (map snd xs)",simp) prefer 2 apply (rule foldl_prop1) apply (subgoal_tac "def_nonDisjointUnionEnvList (snd x # (map snd xs)) --> def_nonDisjointUnionEnv (snd x) (foldl op ⊗ empty (map snd xs))",simp) prefer 2 apply (rule def_nonDisjointUnionEnvList_prop1) apply (frule_tac G="snd x" and G'="foldl op ⊗ empty (map snd xs)" in nonDisjointUnionEnv_prop2,simp) apply (erule disjE) apply simp apply (elim conjE) apply (subgoal_tac " dom (snd (xs ! i)) ⊆ dom (foldl op ⊗ empty (map snd xs))") prefer 2 apply (rule dom_monotone,blast) by blast lemma Otimes_prop2 [rule_format]: " i < length (map snd assert) --> length (map snd assert) > 0 --> def_nonDisjointUnionEnvList (map snd assert) --> x ∈ dom (snd (assert ! i)) --> snd (assert ! i) x ≠ Some s'' --> foldl op ⊗ empty (map snd assert) x ≠ Some s''" apply (induct assert i rule: list_induct3, simp_all) apply (intro impI) apply (simp add: Let_def) apply (elim conjE) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd xa)") prefer 2 apply (simp add: def_nonDisjointUnionEnv_def) apply (subgoal_tac "(empty ⊗ (snd xa)) = ((snd xa) ⊗ empty)",simp) prefer 2 apply (rule nonDisjointUnionEnv_conmutative,simp) apply (subgoal_tac "foldl op ⊗ (snd xa ⊗ empty) (map snd xs) = (snd xa) ⊗ foldl op ⊗ empty (map snd xs)",simp) prefer 2 apply (rule foldl_prop1) apply (rule nonDisjointUnionEnv_prop5,assumption+) apply (intro impI,simp) apply (case_tac "xs=[]",simp) apply (simp add: Let_def) apply (elim conjE) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd xa)") prefer 2 apply (simp add: def_nonDisjointUnionEnv_def) apply (subgoal_tac "(empty ⊗ snd xa) = (snd xa ⊗ empty)",simp) prefer 2 apply (rule nonDisjointUnionEnv_conmutative,simp) apply (subgoal_tac "foldl op ⊗ (snd xa ⊗ empty) (map snd xs) = snd xa ⊗ foldl op ⊗ empty (map snd xs)",simp) prefer 2 apply (rule foldl_prop1) apply (subgoal_tac "def_nonDisjointUnionEnvList (snd xa # (map snd xs)) --> def_nonDisjointUnionEnv (snd xa) (foldl op ⊗ empty (map snd xs))",simp) prefer 2 apply (rule def_nonDisjointUnionEnvList_prop1) apply (subgoal_tac " dom (snd (xs ! i)) ⊆ dom (foldl op ⊗ empty (map snd xs))") prefer 2 apply (rule dom_monotone,simp) apply (subgoal_tac "x ∈ dom (foldl op ⊗ empty (map snd xs))") prefer 2 apply blast by (rule nonDisjointUnionEnv_prop6,assumption+) lemma Otimes_prop3: " i < length (map snd assert) --> length (map snd assert) > 0 --> def_nonDisjointUnionEnvList (map snd assert) --> snd (assert ! i) x = Some m --> foldl op ⊗ empty (map snd assert) x = Some m" apply (induct assert i rule: list_induct3, simp_all) apply (intro impI) apply (simp add: Let_def) apply (elim conjE) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd xa)") prefer 2 apply (simp add: def_nonDisjointUnionEnv_def) apply (subgoal_tac "(empty ⊗ (snd xa)) = ((snd xa) ⊗ empty)",simp) prefer 2 apply (rule nonDisjointUnionEnv_conmutative,simp) apply (subgoal_tac "foldl op ⊗ (snd xa ⊗ empty) (map snd xs) = (snd xa) ⊗ foldl op ⊗ empty (map snd xs)",simp) prefer 2 apply (rule foldl_prop1) apply (rule nonDisjointUnionEnv_prop6_1, simp add: dom_def, assumption+) apply (intro impI,simp) apply (case_tac "xs=[]",simp) apply (simp add: Let_def) apply (elim conjE) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd xa)") prefer 2 apply (simp add: def_nonDisjointUnionEnv_def) apply (subgoal_tac "(empty ⊗ snd xa) = (snd xa ⊗ empty)",simp) prefer 2 apply (rule nonDisjointUnionEnv_conmutative,simp) apply (subgoal_tac "foldl op ⊗ (snd xa ⊗ empty) (map snd xs) = snd xa ⊗ foldl op ⊗ empty (map snd xs)",simp) prefer 2 apply (rule foldl_prop1) apply (subgoal_tac "def_nonDisjointUnionEnvList (snd xa # (map snd xs)) --> def_nonDisjointUnionEnv (snd xa) (foldl op ⊗ empty (map snd xs))",simp) prefer 2 apply (rule def_nonDisjointUnionEnvList_prop1) apply (subgoal_tac " dom (snd (xs ! i)) ⊆ dom (foldl op ⊗ empty (map snd xs))") prefer 2 apply (rule dom_monotone,simp) apply (subgoal_tac "x ∈ dom (foldl op ⊗ empty (map snd xs))") prefer 2 apply blast by (rule nonDisjointUnionEnv_prop6_2,assumption+) lemma nonDisjointUnionEnv_disjointUnionEnv_prop1: "[| x ∈ dom G; G x ≠ Some m |] ==> ((G ⊗ G') + G'') x ≠ Some m" apply (simp add: nonDisjointUnionEnv_def add: disjointUnionEnv_def add: unionEnv_def) apply (rule impI, auto) apply (split split_if_asm, simp add: dom_def) by (simp add: dom_def) lemma nonDisjointUnionEnv_disjointUnionEnv_prop2: "[| def_nonDisjointUnionEnv G G'; z ∈ dom G'; G' z ≠ Some m |] ==> ((G ⊗ G') + G'') z ≠ Some m" apply (simp add: def_nonDisjointUnionEnv_def) apply (erule_tac x="z" in ballE) apply (simp add: nonDisjointUnionEnv_def add: disjointUnionEnv_def add: unionEnv_def) apply (rule impI, auto) apply (simp add: nonDisjointUnionEnv_def add: disjointUnionEnv_def add: unionEnv_def) by (split split_if_asm, simp add: dom_def,auto) lemma nonDisjointUnionEnv_disjointUnionEnv_prop3: "[| x ∈ dom G; G x = Some m |] ==> ((G ⊗ G') + G'') x = Some m" apply (simp add: nonDisjointUnionEnv_def add: disjointUnionEnv_def add: unionEnv_def) by (rule impI,auto) lemma nonDisjointUnionEnv_disjointUnionEnv_prop4: "[| def_nonDisjointUnionEnv G G'; G' z = Some m |] ==> ((G ⊗ G') + G'') z = Some m" apply (simp add: def_nonDisjointUnionEnv_def) apply (erule_tac x="z" in ballE) apply (simp add: nonDisjointUnionEnv_def add: disjointUnionEnv_def add: unionEnv_def) apply (rule impI,auto) apply (simp add: nonDisjointUnionEnv_def add: disjointUnionEnv_def add: unionEnv_def) apply (split split_if_asm,auto) by (split split_if_asm,auto) lemma Otimes_prop2_not_s [rule_format]: " i < length (map snd assert) --> length (map snd assert) > 0 --> def_nonDisjointUnionEnvList (map snd assert) --> y ∈ dom (snd (assert ! i)) --> snd (assert ! i) y ≠ Some s'' --> (foldl op ⊗ empty (map snd assert) + [x \<mapsto> d'']) y ≠ Some s''" apply (induct assert i rule: list_induct3, simp_all) apply (intro impI) apply (simp add: Let_def) apply (elim conjE) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd xa)") prefer 2 apply (simp add: def_nonDisjointUnionEnv_def) apply (subgoal_tac "(empty ⊗ (snd xa)) = ((snd xa) ⊗ empty)",simp) prefer 2 apply (rule nonDisjointUnionEnv_conmutative,simp) apply (subgoal_tac "foldl op ⊗ (snd xa ⊗ empty) (map snd xs) = (snd xa) ⊗ foldl op ⊗ empty (map snd xs)",simp) prefer 2 apply (rule foldl_prop1) apply (rule nonDisjointUnionEnv_disjointUnionEnv_prop1,assumption+) apply (intro impI,simp) apply (case_tac "xs=[]",simp) apply (simp add: Let_def) apply (elim conjE) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd xa)") prefer 2 apply (simp add: def_nonDisjointUnionEnv_def) apply (subgoal_tac "(empty ⊗ snd xa) = (snd xa ⊗ empty)",simp) prefer 2 apply (rule nonDisjointUnionEnv_conmutative,simp) apply (subgoal_tac "foldl op ⊗ (snd xa ⊗ empty) (map snd xs) = snd xa ⊗ foldl op ⊗ empty (map snd xs)",simp) prefer 2 apply (rule foldl_prop1) apply (subgoal_tac "def_nonDisjointUnionEnvList (snd xa # (map snd xs)) --> def_nonDisjointUnionEnv (snd xa) (foldl op ⊗ empty (map snd xs))",simp) prefer 2 apply (rule def_nonDisjointUnionEnvList_prop1) apply (subgoal_tac " dom (snd (xs ! i)) ⊆ dom (foldl op ⊗ empty (map snd xs))") prefer 2 apply (rule dom_monotone,simp) apply (subgoal_tac "y ∈ dom (foldl op ⊗ empty (map snd xs))") prefer 2 apply blast apply (rule nonDisjointUnionEnv_disjointUnionEnv_prop2,assumption+) by (simp add: disjointUnionEnv_def add: unionEnv_def) lemma Otimes_prop4 [rule_format]: " i < length (map snd assert) --> length (map snd assert) > 0 --> def_nonDisjointUnionEnvList (map snd assert) --> snd (assert ! i) xa = Some m --> (foldl op ⊗ empty (map snd assert) + [x \<mapsto> d'']) xa = Some m" apply (induct assert i rule: list_induct3, simp_all) apply (intro impI) apply (simp add: Let_def) apply (elim conjE) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd xb)") prefer 2 apply (simp add: def_nonDisjointUnionEnv_def) apply (subgoal_tac "(empty ⊗ (snd xb)) = ((snd xb) ⊗ empty)",simp) prefer 2 apply (rule nonDisjointUnionEnv_conmutative,simp) apply (subgoal_tac "foldl op ⊗ (snd xb ⊗ empty) (map snd xs) = (snd xb) ⊗ foldl op ⊗ empty (map snd xs)",simp) prefer 2 apply (rule foldl_prop1) apply (rule nonDisjointUnionEnv_disjointUnionEnv_prop3, simp add: dom_def, assumption+) apply (intro impI,simp) apply (case_tac "xs=[]",simp) apply (simp add: Let_def) apply (elim conjE) apply (subgoal_tac "def_nonDisjointUnionEnv empty (snd xb)") prefer 2 apply (simp add: def_nonDisjointUnionEnv_def) apply (subgoal_tac "(empty ⊗ snd xb) = (snd xb ⊗ empty)",simp) prefer 2 apply (rule nonDisjointUnionEnv_conmutative,simp) apply (subgoal_tac "foldl op ⊗ (snd xb ⊗ empty) (map snd xs) = snd xb ⊗ foldl op ⊗ empty (map snd xs)",simp) prefer 2 apply (rule foldl_prop1) apply (subgoal_tac "def_nonDisjointUnionEnvList (snd xb # (map snd xs)) --> def_nonDisjointUnionEnv (snd xb) (foldl op ⊗ empty (map snd xs))",simp) prefer 2 apply (rule def_nonDisjointUnionEnvList_prop1) apply (subgoal_tac " dom (snd (xs ! i)) ⊆ dom (foldl op ⊗ empty (map snd xs))") prefer 2 apply (rule dom_monotone,simp) apply (subgoal_tac "xa ∈ dom (foldl op ⊗ empty (map snd xs))") prefer 2 apply blast apply (rule nonDisjointUnionEnv_disjointUnionEnv_prop4,assumption) by (simp add: disjointUnionEnv_def add: unionEnv_def) text{* Lemmas for nonDisjointUnionSafeEnv operator *} lemma empty_nonDisjointUnionSafeEnv : "empty ⊕ A = A" by (simp add: nonDisjointUnionSafeEnv_def add: unionEnv_def) text{* Lemmas for triangle operator *} lemma safe_triangle: "[| (def_pp Γ1 Γ2 L2); Γ2 x = Some s''|] ==> (pp Γ1 Γ2 L2) x = Some s''" apply (simp add: pp_def add: def_pp_def add: safe_def add: unsafe_def) apply (erule conjE) apply (erule_tac x="x" in allE)+ apply auto by (case_tac "y", simp+) lemma safe_Gamma2_triangle: "[|def_pp Γ1 Γ2 L2; Γ2 x = Some s''; x ∈ L2|] ==> Γ1 x = Some s'' ∨ x ∉ dom Γ1" apply (simp add: def_pp_def) apply (erule conjE)+ apply (erule_tac x="x" in allE)+ apply (simp add: unsafe_def,auto) by (case_tac "y", simp_all) lemma unsafe_triangle: "[|def_pp Γ1 Γ2 L2; def_disjointUnionEnv Γ2 (empty(x1 \<mapsto> m)); L2 ⊆ dom (disjointUnionEnv Γ2 (empty(x1 \<mapsto> m))); x ≠ x1; Γ2 x ≠ Some s''; x ∈ L2|] ==> (pp Γ1 Γ2 L2) x ≠ Some s''" apply (simp add: def_pp_def) apply (elim conjE) apply (erule_tac x="x" in allE,clarsimp)+ apply (simp add: unsafe_def add: pp_def) apply (split split_if_asm,clarsimp) apply (simp add: safe_def) apply (erule conjE) apply (subgoal_tac "[| x ≠ x1; x ∈ L2; L2 ⊆ dom (Γ2 + [x1 \<mapsto> m])|] ==> x ∈ dom Γ2",clarsimp) apply (subgoal_tac "dom (disjointUnionEnv Γ2 [x1 \<mapsto> m]) = dom Γ2 ∪ dom [x1 \<mapsto> m]",simp) apply blast by (rule union_dom_disjointUnionEnv,assumption) lemma safe_Gamma_triangle_3: "[|def_pp Γ1 Γ2 L2; def_disjointUnionEnv Γ2 (empty(x1 \<mapsto> m)); L2 ⊆ dom (disjointUnionEnv Γ2 (empty(x1 \<mapsto> m))); x ≠ x1; Γ2 x ≠ Some s''; x∈ L2|] ==> Γ1 x = Some s'' ∨ x ∉ dom Γ1" apply (frule unsafe_triangle,assumption+) apply (simp add: pp_def) apply (split split_if_asm,clarsimp) apply (simp add: safe_def,clarsimp) apply (simp add: safe_def add: def_pp_def) apply (erule conjE) apply (erule_tac x="x" in allE, simp) apply (simp add: unsafe_def, clarsimp) by (case_tac "y",simp_all) lemma unsafe_Gamma2_triangle: "[| def_pp Γ1 Γ2 L2; (Γ2 + [x1 \<mapsto> m]) y ≠ Some s''; y ≠ x1 |] ==> Γ2 y ≠ Some s''" apply (simp add: disjointUnionEnv_def add: unionEnv_def) apply (split split_if_asm) apply simp apply (simp add: def_pp_def) by auto lemma condemned_Gamma2_triangle: "[|def_pp Γ1 Γ2 L2; (Γ2 + [x1 \<mapsto> s'']) x = Some d''|] ==> (pp Γ1 Γ2 L2) x = Some d''" apply (simp add: disjointUnionEnv_def add: unionEnv_def) apply (split split_if_asm) apply (simp add: pp_def add: def_pp_def, clarsimp) apply (simp add: safe_def add: unsafe_def) apply (erule_tac x="x" in allE)+ apply (simp add: dom_def) apply (case_tac "ya", simp_all) apply (split split_if_asm) apply simp by simp lemma unsafe_triangle_unsafe_2: "[| def_pp Γ1 Γ2 L2; (pp Γ1 Γ2 L2) x = Some d'' |] ==> Γ2 x ≠ Some s''" apply (simp add: pp_def) apply (split split_if_asm) apply (simp add: safe_def) apply (simp add: safe_def) apply (simp add: def_pp_def) apply (simp add: unsafe_def) by auto lemma triangle_d_Gamma1_s_or_not_dom_Gamma1: "[|def_disjointUnionEnv Γ2 (empty(x1 \<mapsto> m)); L1 ⊆ dom Γ1; L2 ⊆ dom (disjointUnionEnv Γ2 (empty(x1 \<mapsto> m))); z ≠ x1; def_pp Γ1 Γ2 L2 ;(pp Γ1 Γ2 L2) z = Some d''; z ∈ L2 |] ==> (Γ1 z = Some s'' ∨ z ∉ dom Γ1)" apply (subgoal_tac "Γ2 z = Some d''"); apply (subgoal_tac "z ∈ dom Γ2") prefer 2 apply blast apply (simp add: pp_def) apply (case_tac "z∈ L1") apply (rule disjI1) apply (subgoal_tac "z ∈ dom Γ1") prefer 2 apply blast apply (simp add: safe_def) apply (split split_if_asm, simp, simp) apply (simp add: def_pp_def) apply auto apply (erule_tac x="z" in allE)+ apply simp apply (simp add: unsafe_def, auto) apply (simp add: safe_def) apply (split split_if_asm, simp) apply (simp add: def_pp_def, auto) apply (simp add: def_pp_def, auto) apply (simp add: unsafe_def, auto) apply (simp add: def_pp_def) apply (subgoal_tac "z ∈ dom Γ2") apply (erule conjE) apply (erule_tac x="z" in allE)+ apply simp apply (simp add: unsafe_def add: pp_def) apply (split split_if_asm, simp, simp) apply (subgoal_tac "dom (Γ2 + [x1 \<mapsto> m]) = dom Γ2 ∪ dom [x1 \<mapsto> m]") prefer 2 apply (rule union_dom_disjointUnionEnv) apply simp apply (subgoal_tac "dom [x1 \<mapsto> m] = {x1}",simp) apply blast by simp lemma triangle_d_Gamma1_s_Gamma2_d: "[|(pp Γ1 Γ2 L2) z = Some d''; Γ1 z = Some s''|] ==> Γ2 z = Some d''" apply (simp add: pp_def) apply (split split_if_asm) apply simp by simp lemma triangle_prop: "[|x ∈ dom Γ1; Γ1 x ≠ Some s''|] ==> x ∈ dom (pp Γ1 Γ2 L2) ∧ (pp Γ1 Γ2 L2) x ≠ Some s''" by (simp add: pp_def, simp add: dom_def add: safe_def) lemma triangle_d_Gamma1_d_or_Gamma2_d: "[|(pp Γ1 Γ2 L2) z = Some d''|] ==> Γ1 z = Some d'' ∨ Γ2 z = Some d''" apply (simp add: pp_def add: safe_def) apply (split split_if_asm) apply simp by simp lemma triangle_d_Gamma2_d_Gamma1_s: "[|L1 ⊆ dom Γ1; def_pp Γ1 Γ2 L2; (pp Γ1 Γ2 L2) z = Some d''; Γ2 z = Some d''; z ∈ L1|] ==> Γ1 z = Some s'' ∧ z ∈ L2" apply (subgoal_tac "z ∈ dom Γ1") prefer 2 apply (erule set_mp, assumption) apply (rule conjI) apply (simp add: pp_def) apply (split split_if_asm) apply (simp_all add: safe_def) apply (simp add: def_pp_def) apply (erule conjE) apply (erule_tac x="z" in allE)+ apply (simp add: unsafe_def) apply (erule conjE) apply (simp add: dom_def) apply (simp add: def_pp_def) apply (erule conjE)+ apply (erule_tac x="z" in allE,simp)+ by (simp add: unsafe_def add: pp_def add: safe_def,clarsimp) lemma Gamma2_d_disjointUnionEnv_m_d: "[|def_disjointUnionEnv Γ2 (empty(x1 \<mapsto> m)); Γ2 z = Some d''|] ==> (disjointUnionEnv Γ2 (empty(x1 \<mapsto> m))) z = Some d''" by (simp add: disjointUnionEnv_def unionEnv_def def_disjointUnionEnv_def, auto) lemma dom_Gamma1_dom_triangle: "x∈ dom Γ1 ==> x ∈ dom (pp Γ1 Γ2 L2)" by (simp add: pp_def,auto) lemma safe_triangle_safe_Gamma1: "[| (pp Γ1 Γ2 L2) x = Some s''; x ∈ dom Γ1 |] ==> Γ1 x = Some s''" apply (simp add: pp_def) apply (split split_if_asm) apply (simp add: safe_def) by simp lemma dom_Gamma2_dom_triangle: "[| x ≠ x1; x ∈ dom (Γ2 + [x1 \<mapsto> m]) |] ==> x ∈ dom (pp Γ1 Γ2 L2)" apply (simp add: pp_def add: disjointUnionEnv_def add: unionEnv_def,clarsimp) apply (split split_if_asm) apply (simp add: safe_def add: dom_def) by simp lemma usafe_Gamma2_unsafe_triangle: "[|x≠x1; x ∈ dom (Γ2 + [x1 \<mapsto> m]); (Γ2 + [x1 \<mapsto> m]) x ≠ Some s''|] ==> (pp Γ1 Γ2 L2) x ≠ Some s''" apply (simp add: pp_def add: disjointUnionEnv_def add: unionEnv_def,clarsimp) apply (split split_if_asm) apply (simp add: safe_def add: dom_def) by simp lemma def_disjointUnionEnv_monotone: "def_disjointUnionEnv Γ2 [x1 \<mapsto> d''] ==> (Γ2 + [x1 \<mapsto> d'']) x1 = Some d''" by (simp add: def_disjointUnionEnv_def add: disjointUnionEnv_def add: unionEnv_def) lemma disjointUnionEnv_d_Gamma2_d: "[|def_disjointUnionEnv Γ2 [x1 \<mapsto> d'']; (Γ2 + [x1 \<mapsto> d'']) z = Some d''; z≠ x1|] ==> Γ2 z = Some d''" apply (simp add: disjointUnionEnv_def add: unionEnv_def) apply (split split_if_asm,clarsimp) by (simp add: def_disjointUnionEnv_def) lemma Gamma2_d_disjointUnionEnv_d: "[|def_disjointUnionEnv Γ2 [x1 \<mapsto> d'']; Γ2 z = Some d''|] ==> (Γ2 + [x1 \<mapsto> d'']) z = Some d''" by (simp add: disjointUnionEnv_def unionEnv_def def_disjointUnionEnv_def, auto) lemma dom_disjointUnionEnv_subset_dom_extend: "[|def_disjointUnionEnv Γ2 [x1 \<mapsto> d'']; dom (disjointUnionEnv Γ2 (empty(x1 \<mapsto> d''))) ⊆ dom (E1(x1 \<mapsto> v1)); (Γ2 + [x1 \<mapsto> d'']) x = Some s''|] ==> x ∈ dom E1" apply (simp add: disjointUnionEnv_def add: unionEnv_def) apply (subgoal_tac "x≠x1") apply blast apply (simp add: def_disjointUnionEnv_def) apply (split split_if_asm,clarsimp,simp) by (split split_if_asm,clarsimp, simp) lemma Gamma2_d_triangle_d: "[|def_pp Γ1 Γ2 L2; Γ2 x = Some d''|] ==> (pp Γ1 Γ2 L2) x = Some d''" apply (simp add: pp_def add: def_pp_def, clarsimp) apply (simp add: safe_def add: unsafe_def) apply (erule_tac x="x" in allE)+ apply (simp add: dom_def) apply (elim conjE) apply (case_tac "y", simp_all) done lemma disjounitUnionEnv_d_triangle_d: "[|x≠x1;def_pp Γ1 Γ2 L2; (Γ2 + [x1 \<mapsto> d'']) x = Some d''|] ==> (pp Γ1 Γ2 L2) x = Some d''" apply (simp add: disjointUnionEnv_def add: unionEnv_def) apply (split split_if_asm) apply (simp add: pp_def add: def_pp_def, clarsimp) apply (simp add: safe_def add: unsafe_def) apply (erule_tac x="x" in allE)+ apply (simp add: dom_def) apply (case_tac "ya", simp_all) done (********** CASE **************) (*declare dom_fun_upd [simp del]*) end
lemma empty_unionEnv:
unionEnv m empty = m
lemma dom_empty_unionEnv:
dom (unionEnv m1.0 empty) = dom m1.0
lemma empty_disjointUnionEnv:
m + empty = m
lemma dom_empty_disjointUnionEnv:
dom (m1.0 + empty) = dom m1.0
lemma union_dom_disjointUnionEnv:
def_disjointUnionEnv Γ1.0 Γ2.0 ==> dom (Γ1.0 + Γ2.0) = dom Γ1.0 ∪ dom Γ2.0
lemma dom_disjointUnionEnv_monotone:
dom (G + G') = dom G ∪ dom G'
lemma empty_nonDisjointUnionEnv:
empty ⊗ A = A
lemma refl_nonDisjointUnionEnv:
A ⊗ A = A
lemma list_induct3:
[| P [] 0; !!x xs. P (x # xs) 0; !!i. P [] (Suc i);
!!x xs i. P xs i ==> P (x # xs) (Suc i) |]
==> P xs i
lemma nonDisjointUnionEnv_conmutative:
def_nonDisjointUnionEnv G G' ==> G ⊗ G' = G' ⊗ G
lemma nonDisjointUnionEnv_assoc:
G1.0 ⊗ G2.0 ⊗ G3.0 = G1.0 ⊗ (G2.0 ⊗ G3.0)
lemma nonDisjointUnionEnv_disjointUnionEnv_assoc:
(G1.0 ⊗ G2.0) + G3.0 = G1.0 ⊗ G2.0 + G3.0
lemma foldl_prop1:
foldl op ⊗ (G' ⊗ G) Gs = G' ⊗ foldl op ⊗ G Gs
lemma foldl_prop2:
foldl op ⊗ (G' ⊗ G) Gs + G'' = G' ⊗ foldl op ⊗ G Gs + G''
lemma union_dom_nonDisjointUnionEnv:
dom (A ⊗ B) = dom A ∪ dom B
lemma union_dom_nonDisjointUnionEnv_disjointUnionEnv:
dom (A ⊗ B + [x |-> m]) = dom A ∪ dom (B + [x |-> m])
lemma def_nonDisjointUnionEnvList_prop1:
def_nonDisjointUnionEnvList (x # xs) -->
def_nonDisjointUnionEnv x (foldl op ⊗ empty xs)
lemma dom_foldl_monotone:
dom (foldl op ⊗ (empty ⊗ snd a) (map snd assert)) =
dom (snd a) ∪ dom (foldl op ⊗ empty (map snd assert))
lemma dom_foldl_disjointUnionEnv_monotone:
dom (foldl op ⊗ (empty ⊗ snd a) (map snd assert) + [x |-> d'']) =
dom (snd a) ∪ dom (foldl op ⊗ empty (map snd assert)) ∪ dom [x |-> d'']
lemma dom_monotone:
i < length assert
==> dom (snd (assert ! i)) ⊆ dom (foldl op ⊗ empty (map snd assert))
lemma dom_monotone_foldl_nonDijointUnionEnv:
i < length assert
==> dom (snd (assert ! i))
⊆ dom (foldl op ⊗ empty (map snd assert) + [x |-> d''])
lemma dom_Γi_subseteq_dom_Γ_case:
0 < length assert
==> ∀i<length assert.
dom (snd (assert ! i)) ⊆ dom (foldl op ⊗ empty (map snd assert))
lemma dom_Γi_subseteq_dom_Γ_cased:
0 < length assert
==> ∀i<length assert.
dom (snd (assert ! i))
⊆ dom (foldl op ⊗ empty (map snd assert) + [x |-> d''])
lemma nonDisjointUnionEnv_prop1:
(G ⊗ G') z = Some m ==> G z = Some m ∨ z ∉ dom G ∧ G' z = Some m
lemma nonDisjointUnionEnv_prop2:
[| def_nonDisjointUnionEnv G G'; (G ⊗ G') z = Some m |]
==> G' z = Some m ∨ z ∉ dom G' ∧ G z = Some m
lemma nonDisjointUnionEnv_prop5:
[| x ∈ dom G; G x ≠ Some m |] ==> (G ⊗ G') x ≠ Some m
lemma nonDisjointUnionEnv_prop6:
[| def_nonDisjointUnionEnv G G'; z ∈ dom G'; G' z ≠ Some m |]
==> (G ⊗ G') z ≠ Some m
lemma nonDisjointUnionEnv_prop6_1:
[| x ∈ dom G; G x = Some m |] ==> (G ⊗ G') x = Some m
lemma nonDisjointUnionEnv_prop6_2:
[| def_nonDisjointUnionEnv G G'; G' z = Some m |] ==> (G ⊗ G') z = Some m
lemma Otimes_prop1:
i < length (map snd assert) -->
0 < length (map snd assert) -->
def_nonDisjointUnionEnvList (map snd assert) -->
foldl op ⊗ empty (map snd assert) z = Some d'' -->
z ∈ dom (snd (assert ! i)) --> snd (assert ! i) z = Some d''
lemma Otimes_prop2:
[| i < length (map snd assert); 0 < length (map snd assert);
def_nonDisjointUnionEnvList (map snd assert); x ∈ dom (snd (assert ! i));
snd (assert ! i) x ≠ Some s'' |]
==> foldl op ⊗ empty (map snd assert) x ≠ Some s''
lemma Otimes_prop3:
i < length (map snd assert) -->
0 < length (map snd assert) -->
def_nonDisjointUnionEnvList (map snd assert) -->
snd (assert ! i) x = Some m --> foldl op ⊗ empty (map snd assert) x = Some m
lemma nonDisjointUnionEnv_disjointUnionEnv_prop1:
[| x ∈ dom G; G x ≠ Some m |] ==> ((G ⊗ G') + G'') x ≠ Some m
lemma nonDisjointUnionEnv_disjointUnionEnv_prop2:
[| def_nonDisjointUnionEnv G G'; z ∈ dom G'; G' z ≠ Some m |]
==> ((G ⊗ G') + G'') z ≠ Some m
lemma nonDisjointUnionEnv_disjointUnionEnv_prop3:
[| x ∈ dom G; G x = Some m |] ==> ((G ⊗ G') + G'') x = Some m
lemma nonDisjointUnionEnv_disjointUnionEnv_prop4:
[| def_nonDisjointUnionEnv G G'; G' z = Some m |]
==> ((G ⊗ G') + G'') z = Some m
lemma Otimes_prop2_not_s:
[| i < length (map snd assert); 0 < length (map snd assert);
def_nonDisjointUnionEnvList (map snd assert); y ∈ dom (snd (assert ! i));
snd (assert ! i) y ≠ Some s'' |]
==> (foldl op ⊗ empty (map snd assert) + [x |-> d'']) y ≠ Some s''
lemma Otimes_prop4:
[| i < length (map snd assert); 0 < length (map snd assert);
def_nonDisjointUnionEnvList (map snd assert); snd (assert ! i) xa = Some m |]
==> (foldl op ⊗ empty (map snd assert) + [x |-> d'']) xa = Some m
lemma empty_nonDisjointUnionSafeEnv:
empty ⊕ A = A
lemma safe_triangle:
[| def_pp Γ1.0 Γ2.0 L2.0; Γ2.0 x = Some s'' |]
==> Γ1.0\<triangleright>Γ2.0 L2.0 x = Some s''
lemma safe_Gamma2_triangle:
[| def_pp Γ1.0 Γ2.0 L2.0; Γ2.0 x = Some s''; x ∈ L2.0 |]
==> Γ1.0 x = Some s'' ∨ x ∉ dom Γ1.0
lemma unsafe_triangle:
[| def_pp Γ1.0 Γ2.0 L2.0; def_disjointUnionEnv Γ2.0 [x1.0 |-> m];
L2.0 ⊆ dom (Γ2.0 + [x1.0 |-> m]); x ≠ x1.0; Γ2.0 x ≠ Some s''; x ∈ L2.0 |]
==> Γ1.0\<triangleright>Γ2.0 L2.0 x ≠ Some s''
lemma safe_Gamma_triangle_3:
[| def_pp Γ1.0 Γ2.0 L2.0; def_disjointUnionEnv Γ2.0 [x1.0 |-> m];
L2.0 ⊆ dom (Γ2.0 + [x1.0 |-> m]); x ≠ x1.0; Γ2.0 x ≠ Some s''; x ∈ L2.0 |]
==> Γ1.0 x = Some s'' ∨ x ∉ dom Γ1.0
lemma unsafe_Gamma2_triangle:
[| def_pp Γ1.0 Γ2.0 L2.0; (Γ2.0 + [x1.0 |-> m]) y ≠ Some s''; y ≠ x1.0 |]
==> Γ2.0 y ≠ Some s''
lemma condemned_Gamma2_triangle:
[| def_pp Γ1.0 Γ2.0 L2.0; (Γ2.0 + [x1.0 |-> s'']) x = Some d'' |]
==> Γ1.0\<triangleright>Γ2.0 L2.0 x = Some d''
lemma unsafe_triangle_unsafe_2:
[| def_pp Γ1.0 Γ2.0 L2.0; Γ1.0\<triangleright>Γ2.0 L2.0 x = Some d'' |]
==> Γ2.0 x ≠ Some s''
lemma triangle_d_Gamma1_s_or_not_dom_Gamma1:
[| def_disjointUnionEnv Γ2.0 [x1.0 |-> m]; L1.0 ⊆ dom Γ1.0;
L2.0 ⊆ dom (Γ2.0 + [x1.0 |-> m]); z ≠ x1.0; def_pp Γ1.0 Γ2.0 L2.0;
Γ1.0\<triangleright>Γ2.0 L2.0 z = Some d''; z ∈ L2.0 |]
==> Γ1.0 z = Some s'' ∨ z ∉ dom Γ1.0
lemma triangle_d_Gamma1_s_Gamma2_d:
[| Γ1.0\<triangleright>Γ2.0 L2.0 z = Some d''; Γ1.0 z = Some s'' |]
==> Γ2.0 z = Some d''
lemma triangle_prop:
[| x ∈ dom Γ1.0; Γ1.0 x ≠ Some s'' |]
==> x ∈ dom Γ1.0\<triangleright>Γ2.0 L2.0 ∧
Γ1.0\<triangleright>Γ2.0 L2.0 x ≠ Some s''
lemma triangle_d_Gamma1_d_or_Gamma2_d:
Γ1.0\<triangleright>Γ2.0 L2.0 z = Some d''
==> Γ1.0 z = Some d'' ∨ Γ2.0 z = Some d''
lemma triangle_d_Gamma2_d_Gamma1_s:
[| L1.0 ⊆ dom Γ1.0; def_pp Γ1.0 Γ2.0 L2.0;
Γ1.0\<triangleright>Γ2.0 L2.0 z = Some d''; Γ2.0 z = Some d''; z ∈ L1.0 |]
==> Γ1.0 z = Some s'' ∧ z ∈ L2.0
lemma Gamma2_d_disjointUnionEnv_m_d:
[| def_disjointUnionEnv Γ2.0 [x1.0 |-> m]; Γ2.0 z = Some d'' |]
==> (Γ2.0 + [x1.0 |-> m]) z = Some d''
lemma dom_Gamma1_dom_triangle:
x ∈ dom Γ1.0 ==> x ∈ dom Γ1.0\<triangleright>Γ2.0 L2.0
lemma safe_triangle_safe_Gamma1:
[| Γ1.0\<triangleright>Γ2.0 L2.0 x = Some s''; x ∈ dom Γ1.0 |]
==> Γ1.0 x = Some s''
lemma dom_Gamma2_dom_triangle:
[| x ≠ x1.0; x ∈ dom (Γ2.0 + [x1.0 |-> m]) |]
==> x ∈ dom Γ1.0\<triangleright>Γ2.0 L2.0
lemma usafe_Gamma2_unsafe_triangle:
[| x ≠ x1.0; x ∈ dom (Γ2.0 + [x1.0 |-> m]);
(Γ2.0 + [x1.0 |-> m]) x ≠ Some s'' |]
==> Γ1.0\<triangleright>Γ2.0 L2.0 x ≠ Some s''
lemma def_disjointUnionEnv_monotone:
def_disjointUnionEnv Γ2.0 [x1.0 |-> d'']
==> (Γ2.0 + [x1.0 |-> d'']) x1.0 = Some d''
lemma disjointUnionEnv_d_Gamma2_d:
[| def_disjointUnionEnv Γ2.0 [x1.0 |-> d''];
(Γ2.0 + [x1.0 |-> d'']) z = Some d''; z ≠ x1.0 |]
==> Γ2.0 z = Some d''
lemma Gamma2_d_disjointUnionEnv_d:
[| def_disjointUnionEnv Γ2.0 [x1.0 |-> d'']; Γ2.0 z = Some d'' |]
==> (Γ2.0 + [x1.0 |-> d'']) z = Some d''
lemma dom_disjointUnionEnv_subset_dom_extend:
[| def_disjointUnionEnv Γ2.0 [x1.0 |-> d''];
dom (Γ2.0 + [x1.0 |-> d'']) ⊆ dom (E1.0(x1.0 |-> v1.0));
(Γ2.0 + [x1.0 |-> d'']) x = Some s'' |]
==> x ∈ dom E1.0
lemma Gamma2_d_triangle_d:
[| def_pp Γ1.0 Γ2.0 L2.0; Γ2.0 x = Some d'' |]
==> Γ1.0\<triangleright>Γ2.0 L2.0 x = Some d''
lemma disjounitUnionEnv_d_triangle_d:
[| x ≠ x1.0; def_pp Γ1.0 Γ2.0 L2.0; (Γ2.0 + [x1.0 |-> d'']) x = Some d'' |]
==> Γ1.0\<triangleright>Γ2.0 L2.0 x = Some d''