Up to index of Isabelle/HOL/CoreSafe
theory SafeDAss_P3(* Title: Safe DAss P3 Author: Javier de Dios and Ricardo Peņa Copyright: March 2008, Universidad Complutense de Madrid *) header {* Derived Assertions. P3. L dom G *} theory SafeDAss_P3 imports SafeDAssBasic begin (* Demostracion de L ⊆ dom Γ *) text{* Lemmas for LET *} lemma dom_Γ2_subseteq_triangle_Γ1_Γ2_L2: "dom Γ2 ⊆ dom (pp Γ1 Γ2 L2)" by (simp add: pp_def, clarsimp) lemma set_atom2var_as_subeteq_Γ1: "∀a∈set as. atom a ==> set (map atom2var as) ⊆ dom (map_of (zip (map atom2var as) (replicate (length as) s'')))" apply (induct as,simp,clarsimp) apply (case_tac a,simp_all) by force lemma P3_LET_e1: "[|L1 ⊆ dom Γ1|] ==> L1 ⊆ dom (pp Γ1 Γ2 L2)" by (simp add: pp_def, auto) lemma P3_LET_e2: "[|def_disjointUnionEnv Γ2 (empty(x1 \<mapsto> m)); L2 ⊆ dom (disjointUnionEnv Γ2 (empty(x1 \<mapsto> m)))|] ==> L2 - {x1} ⊆ dom (pp Γ1 Γ2 L2)" apply (rule subsetI) apply (frule union_dom_disjointUnionEnv) apply (simp add: def_disjointUnionEnv_def) apply (subgoal_tac "dom Γ2 ⊆ dom (pp Γ1 Γ2 L2)",blast) by (rule dom_Γ2_subseteq_triangle_Γ1_Γ2_L2) lemma P3_LET: "[| def_disjointUnionEnv Γ2 (empty(x1 \<mapsto> m)); L1 ⊆ dom Γ1; L2 ⊆ dom (disjointUnionEnv Γ2 (empty(x1 \<mapsto> m)))|] ==> L1 ∪ (L2 - {x1}) ⊆ dom (pp Γ1 Γ2 L2)" apply clarsimp apply (rule conjI) apply (erule P3_LET_e1) by (erule P3_LET_e2,assumption) text{* Lemmas for CASE *} (***************** CASE *****************) lemma P3_CASE: "[| length assert > 0; length alts = length assert; (∀i < length alts. fst (assert ! i) ⊆ dom (snd (assert ! i))); x ∈ dom (nonDisjointUnionEnvList (map snd assert)) |] ==> (\<Union>i < length alts fst (assert ! i) - set (snd (extractP (fst (alts ! i))))) ∪ {x} ⊆ dom (nonDisjointUnionEnvList (map snd assert))" apply (frule dom_Γi_subseteq_dom_Γ_case) by (clarsimp,blast) text{* Lemmas for CASED *} lemma P3_1_CASED: "[| length assert > 0; length assert = length alts; (∀i < length alts. fst (assert ! i) ⊆ dom (snd (assert ! i))) |] ==> x ∈ dom (foldl op ⊗ empty (map (λ(Li, Γi). restrict_neg_map Γi (insert x (set Li))) (zip (map (snd o extractP o fst) alts) (map snd assert))) + [x \<mapsto> d''])" apply (subst dom_disjointUnionEnv_monotone) by (simp add: dom_def) lemma dom_restrict_neg_map: "dom (restrict_neg_map m A) = dom m - (dom m ∩ A)" apply (simp add: restrict_neg_map_def) apply auto by (split split_if_asm,simp_all) lemma dom_foldl_monotone_generic: " dom (foldl op ⊗ (empty ⊗ x) xs) = dom x ∪ dom (foldl op ⊗ empty xs)" apply (subgoal_tac "empty ⊗ x = x ⊗ empty",simp) apply (subgoal_tac "foldl op ⊗ (x ⊗ empty) xs = x ⊗ foldl op ⊗ empty xs",simp) apply (rule union_dom_nonDisjointUnionEnv) apply (rule foldl_prop1) apply (subgoal_tac "def_nonDisjointUnionEnv empty x") apply (erule nonDisjointUnionEnv_conmutative) by (simp add: def_nonDisjointUnionEnv_def) lemma dom_foldl_disjointUnionEnv_monotone_generic_2: " dom (foldl op ⊗ (empty ⊗ y) ys + A) = dom y ∪ dom (foldl op ⊗ empty ys) ∪ dom A" apply (subgoal_tac "empty ⊗ y = y ⊗ empty",simp) apply (subgoal_tac "foldl op ⊗ (y ⊗ empty) ys = y ⊗ foldl op ⊗ empty ys",simp) apply (subst dom_disjointUnionEnv_monotone) apply (subst union_dom_nonDisjointUnionEnv) apply simp apply (rule foldl_prop1) apply (subgoal_tac "def_nonDisjointUnionEnv empty y") apply (erule nonDisjointUnionEnv_conmutative) by (simp add: def_nonDisjointUnionEnv_def) lemma dom_Γi_in_Γcased [rule_format]: "length assert > 0 --> length assert = length alts --> def_disjointUnionEnv (foldl op ⊗ empty (map (λ(Li, Γi). restrict_neg_map Γi (insert x (set Li))) (zip (map (snd o extractP o fst) alts) (map snd assert)))) [x \<mapsto> d''] --> (∀ i < length alts. y ∈ dom (snd (assert ! i)) --> y ∉ set (snd (extractP (fst (alts ! i)))) --> y ∈ dom (foldl op ⊗ empty (map (λ(Li, Γi). restrict_neg_map Γi (insert x (set Li))) (zip (map (snd o extractP o fst) alts) (map snd assert))) + [x \<mapsto> d'']))" apply (induct assert alts rule:list_induct2',simp_all) apply (rule impI)+ apply (case_tac "xs = []",simp) apply (rule impI) apply (subst empty_nonDisjointUnionEnv) apply (subst union_dom_disjointUnionEnv) apply (subst (asm) empty_nonDisjointUnionEnv) apply simp apply (subst dom_restrict_neg_map) apply force apply simp apply (drule mp) apply (simp add: def_disjointUnionEnv_def) apply (subst (asm) dom_foldl_monotone_generic) apply blast apply (rule allI, rule impI) apply (case_tac i,simp_all) apply (rule impI) apply (subst dom_foldl_disjointUnionEnv_monotone_generic_2) apply (subst dom_restrict_neg_map) apply force apply (rule impI) apply (rotate_tac 3) apply (erule_tac x="nat" in allE,simp) apply (subst dom_foldl_disjointUnionEnv_monotone_generic_2) apply (subst (asm) union_dom_disjointUnionEnv) apply (simp add: def_disjointUnionEnv_def) apply (subst (asm) dom_foldl_monotone_generic) apply blast by blast lemma P3_2_CASED: "[| length assert > 0; length assert = length alts; def_disjointUnionEnv (foldl op ⊗ empty (map (λ(Li, Γi). restrict_neg_map Γi (insert x (set Li))) (zip (map (snd o extractP o fst) alts) (map snd assert)))) [x \<mapsto> d'']; ∀ i < length alts. ∀ j < length alts. i ≠ j --> (fst (assert ! i) ∩ set (snd (extractP (fst (alts ! j))))) = {}; (∀i < length alts. fst (assert ! i) ⊆ dom (snd (assert ! i))) |] ==> (\<Union>i < length alts fst (assert ! i) - set (snd (extractP (fst (alts ! i))))) ⊆ dom (foldl op ⊗ empty (map (λ(Li, Γi). restrict_neg_map Γi (insert x (set Li))) (zip (map (snd o extractP o fst) alts) (map snd assert))) + [x \<mapsto> d''])" apply (rule subsetI,simp) apply (rename_tac y) apply (elim bexE, elim conjE) apply (erule_tac x="i" in allE,simp) apply (subgoal_tac "y ∈ dom (snd (assert ! i))") prefer 2 apply blast apply (rule dom_Γi_in_Γcased) by (simp,assumption+) (** APP **) lemma union_dom_nonDisjointUnionSafeEnv: " dom (nonDisjointUnionSafeEnv A B) = dom A ∪ dom B" apply (simp add: nonDisjointUnionSafeEnv_def add: unionEnv_def,auto) by (split split_if_asm,simp_all) lemma nonDisjointUnionSafeEnv_assoc: "nonDisjointUnionSafeEnv (nonDisjointUnionSafeEnv G1 G2) G3 = nonDisjointUnionSafeEnv G1 (nonDisjointUnionSafeEnv G2 G3)" apply (simp add: nonDisjointUnionSafeEnv_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_nonDisjointUnionSafeEnv_prop: "foldl nonDisjointUnionSafeEnv (G' ⊕ G) Gs = G' ⊕ foldl op ⊕ G Gs" apply (induct Gs arbitrary: G) apply simp by (simp_all add: nonDisjointUnionSafeEnv_assoc) lemma nonDisjointUnionSafeEnv_conmutative: "def_nonDisjointUnionSafeEnv G G' ==> (G ⊕ G') = (G' ⊕ G)" apply (simp add: nonDisjointUnionSafeEnv_def add: unionEnv_def) apply (rule ext) apply (simp add: def_nonDisjointUnionSafeEnv_def) apply (simp add: safe_def) by clarsimp lemma dom_foldl_nonDisjointUnionSafeEnv_monotone: " dom (foldl nonDisjointUnionSafeEnv (empty ⊕ x) xs) = dom x ∪ dom (foldl op ⊕ empty xs)" apply (subgoal_tac "empty ⊕ x = x ⊕ empty",simp) apply (subgoal_tac "foldl op ⊕ (x ⊕ empty) xs = x ⊕ foldl op ⊕ empty xs",simp) apply (rule union_dom_nonDisjointUnionSafeEnv) apply (rule foldl_nonDisjointUnionSafeEnv_prop) apply (rule nonDisjointUnionSafeEnv_conmutative) by (simp add: def_nonDisjointUnionSafeEnv_def) lemma nonDisjointUnionSafeEnv_empty: "nonDisjointUnionSafeEnv empty x = x" apply (simp add: nonDisjointUnionSafeEnv_def) by (simp add: unionEnv_def) declare dom_fun_upd [simp del] lemma dom_atom2var_fv: "(∃y. x = VarE y unit) ==> dom [atom2var x \<mapsto> y] = fv x" apply (case_tac x) apply (simp_all add: atom2var.simps) by (simp add: dom_def) declare nonDisjointUnionSafeEnvList.simps [simp del] lemma atom_fvs_VarE: "[| (∀ a ∈ set as. atom a); xa ∈ fvs' as |] ==> (∃ i < length as. ∃ a. as!i = VarE xa a)" apply (induct as,simp_all) apply (case_tac a, simp_all) by force lemma nth_nonDisjointUnionSafeEnvList: "[| length xs = length ms; def_nonDisjointUnionSafeEnvList (maps_of (zip xs ms)) |] ==> (∀ i < length xs . nonDisjointUnionSafeEnvList (maps_of (zip xs ms)) (xs!i) = Some (ms!i))" apply (induct xs ms rule: list_induct2',simp_all) apply clarsimp apply (case_tac i) apply simp apply (simp add: nonDisjointUnionSafeEnvList.simps) apply (subgoal_tac "empty ⊕ [x \<mapsto> y] = [x \<mapsto> y] ⊕ empty",simp) apply (subgoal_tac "foldl op ⊕ ([x \<mapsto> y] ⊕ empty) (maps_of (zip xs ys)) = [x \<mapsto> y] ⊕ foldl op ⊕ empty (maps_of (zip xs ys))",simp) apply (simp add: nonDisjointUnionSafeEnv_def) apply (simp add: unionEnv_def) apply (simp add: dom_def) apply (rule foldl_nonDisjointUnionSafeEnv_prop) apply (subst nonDisjointUnionSafeEnv_empty) apply (subst nonDisjointUnionSafeEnv_conmutative) apply (simp add: def_nonDisjointUnionSafeEnv_def) apply (subst nonDisjointUnionSafeEnv_empty) apply simp apply clarsimp apply (simp add: nonDisjointUnionSafeEnvList.simps) apply (subgoal_tac "empty ⊕ [x \<mapsto> y] = [x \<mapsto> y] ⊕ empty",simp) apply (subgoal_tac "foldl op ⊕ ([x \<mapsto> y] ⊕ empty) (maps_of (zip xs ys)) = [x \<mapsto> y] ⊕ foldl op ⊕ empty (maps_of (zip xs ys))",simp) apply (simp add: Let_def) apply (erule_tac x="nat" in allE,simp) apply (simp add: nonDisjointUnionSafeEnv_def) apply (simp add: unionEnv_def) apply (rule conjI) apply (rule impI)+ apply (elim conjE) apply (simp add: def_nonDisjointUnionSafeEnv_def) apply (erule_tac x="x" in ballE) apply (simp add: safe_def) apply (simp add: dom_def) apply clarsimp apply (rule foldl_nonDisjointUnionSafeEnv_prop) apply (rule nonDisjointUnionSafeEnv_conmutative) by (simp add: def_nonDisjointUnionSafeEnv_def) lemma dom_nonDisjointUnionSafeEnvList_fvs: "[| ∀ a ∈ set xs. atom a; length xs = length ys |] ==> fvs' xs ⊆ dom (nonDisjointUnionSafeEnvList (maps_of (zip (map atom2var xs) ys)))" apply (induct xs ys rule: list_induct2',simp_all) apply (simp add: nonDisjointUnionSafeEnvList.simps) apply (subst dom_foldl_nonDisjointUnionSafeEnv_monotone) apply (rule conjI) apply (case_tac x, simp_all) apply (simp add: dom_def) apply (subst dom_foldl_nonDisjointUnionSafeEnv_monotone) by blast declare nonDisjointUnionSafeEnvList.simps [simp add] declare def_nonDisjointUnionSafeEnvList.simps [simp add] thm dom_map_add declare atom.simps [simp del] lemma nonDisjointUnionSafeEnvList_prop1: "[| nonDisjointUnionSafeEnvList (maps_of (zip (map atom2var as) ms)) ⊆m Γ; xa ∈ fvs' as; Γ xa = Some y; def_nonDisjointUnionSafeEnvList (maps_of (zip (map atom2var as) ms)); (∀ a ∈ set as. atom a); length as = length ms |] ==> ∃ i < length as. ∃ a. as!i = VarE xa a ∧ ms!i = y" apply (frule atom_fvs_VarE,assumption+) apply (elim exE, elim conjE, elim exE) apply (rule_tac x="i" in exI,simp) apply (simp add: map_le_def) apply (erule_tac x="xa" in ballE,simp) apply (subgoal_tac "length (map atom2var as) = length ms") prefer 2 apply simp apply (frule nth_nonDisjointUnionSafeEnvList,assumption+) apply (erule_tac x="i" in allE,simp) apply (frule dom_nonDisjointUnionSafeEnvList_fvs,assumption+,simp) by blast lemma P3_APP: "[| length as = length ms; ∀ a ∈ set as. atom a; nonDisjointUnionSafeEnvList (maps_of (zip (map atom2var as) ms)) ⊆m Γ |] ==> fvs' as ⊆ dom Γ" apply (induct as ms rule: list_induct2',simp_all) apply (elim conjE) apply (frule map_le_implies_dom_le) apply (frule dom_nonDisjointUnionSafeEnvList_fvs,assumption+) apply (subgoal_tac " dom (nonDisjointUnionSafeEnvList ([atom2var x \<mapsto> y] # maps_of (zip (map atom2var xs) ys))) = dom [atom2var x \<mapsto> y] ∪ dom (nonDisjointUnionSafeEnvList (maps_of (zip (map atom2var xs) ys)))") apply simp apply (rule conjI) apply (case_tac x,simp_all add: atom.simps) apply force apply force by (rule dom_foldl_nonDisjointUnionSafeEnv_monotone) (* APP PRIMOP *) lemma P3_APP_PRIMOP: "[| Γ0 = [atom2var a1 \<mapsto> s'', atom2var a2 \<mapsto> s'']; [atom2var a1 \<mapsto> s'', atom2var a2 \<mapsto> s''] ⊆m Γ|] ==> {atom2var a1, atom2var a2} ⊆ dom Γ" apply (simp add: map_le_def) apply (rule conjI) apply (erule_tac x="atom2var a1" in ballE) apply (split split_if_asm) apply (drule_tac t="Γ (atom2var a1)" in sym,force) apply (drule_tac t="Γ (atom2var a1)" in sym, simp add: dom_def) apply (simp add: dom_def) apply (split split_if_asm,simp,simp) apply (erule_tac x="atom2var a2" in ballE) apply (split split_if_asm) apply (drule_tac t="Γ (atom2var a2)" in sym,force) apply (drule_tac t="Γ (atom2var a2)" in sym, simp add: dom_def) by (simp add: dom_def) end
lemma dom_Γ2_subseteq_triangle_Γ1_Γ2_L2:
dom Γ2.0 ⊆ dom Γ1.0\<triangleright>Γ2.0 L2.0
lemma set_atom2var_as_subeteq_Γ1:
∀a∈set as. atom a
==> set (map atom2var as)
⊆ dom (map_of (zip (map atom2var as) (replicate (length as) s'')))
lemma P3_LET_e1:
L1.0 ⊆ dom Γ1.0 ==> L1.0 ⊆ dom Γ1.0\<triangleright>Γ2.0 L2.0
lemma P3_LET_e2:
[| def_disjointUnionEnv Γ2.0 [x1.0 |-> m]; L2.0 ⊆ dom (Γ2.0 + [x1.0 |-> m]) |]
==> L2.0 - {x1.0} ⊆ dom Γ1.0\<triangleright>Γ2.0 L2.0
lemma P3_LET:
[| def_disjointUnionEnv Γ2.0 [x1.0 |-> m]; L1.0 ⊆ dom Γ1.0;
L2.0 ⊆ dom (Γ2.0 + [x1.0 |-> m]) |]
==> L1.0 ∪ (L2.0 - {x1.0}) ⊆ dom Γ1.0\<triangleright>Γ2.0 L2.0
lemma P3_CASE:
[| 0 < length assert; length alts = length assert;
∀i<length alts. fst (assert ! i) ⊆ dom (snd (assert ! i));
x ∈ dom (nonDisjointUnionEnvList (map snd assert)) |]
==> (UN i<length alts.
fst (assert ! i) - set (snd (extractP (fst (alts ! i))))) ∪
{x}
⊆ dom (nonDisjointUnionEnvList (map snd assert))
lemma P3_1_CASED:
[| 0 < length assert; length assert = length alts;
∀i<length alts. fst (assert ! i) ⊆ dom (snd (assert ! i)) |]
==> x ∈ dom (foldl op ⊗ empty
(map (λ(Li, Γi). restrict_neg_map Γi (insert x (set Li)))
(zip (map (snd o extractP o fst) alts) (map snd assert))) +
[x |-> d''])
lemma dom_restrict_neg_map:
dom (restrict_neg_map m A) = dom m - dom m ∩ A
lemma dom_foldl_monotone_generic:
dom (foldl op ⊗ (empty ⊗ x) xs) = dom x ∪ dom (foldl op ⊗ empty xs)
lemma dom_foldl_disjointUnionEnv_monotone_generic_2:
dom (foldl op ⊗ (empty ⊗ y) ys + A) = dom y ∪ dom (foldl op ⊗ empty ys) ∪ dom A
lemma dom_Γi_in_Γcased:
[| 0 < length assert; length assert = length alts;
def_disjointUnionEnv
(foldl op ⊗ empty
(map (λ(Li, Γi). restrict_neg_map Γi (insert x (set Li)))
(zip (map (snd o extractP o fst) alts) (map snd assert))))
[x |-> d''];
i < length alts; y ∈ dom (snd (assert ! i));
y ∉ set (snd (extractP (fst (alts ! i)))) |]
==> y ∈ dom (foldl op ⊗ empty
(map (λ(Li, Γi). restrict_neg_map Γi (insert x (set Li)))
(zip (map (snd o extractP o fst) alts) (map snd assert))) +
[x |-> d''])
lemma P3_2_CASED:
[| 0 < length assert; length assert = length alts;
def_disjointUnionEnv
(foldl op ⊗ empty
(map (λ(Li, Γi). restrict_neg_map Γi (insert x (set Li)))
(zip (map (snd o extractP o fst) alts) (map snd assert))))
[x |-> d''];
∀i<length alts.
∀j<length alts.
i ≠ j -->
fst (assert ! i) ∩ set (snd (extractP (fst (alts ! j)))) = {};
∀i<length alts. fst (assert ! i) ⊆ dom (snd (assert ! i)) |]
==> (UN i<length alts. fst (assert ! i) - set (snd (extractP (fst (alts ! i)))))
⊆ dom (foldl op ⊗ empty
(map (λ(Li, Γi). restrict_neg_map Γi (insert x (set Li)))
(zip (map (snd o extractP o fst) alts) (map snd assert))) +
[x |-> d''])
lemma union_dom_nonDisjointUnionSafeEnv:
dom (A ⊕ B) = dom A ∪ dom B
lemma nonDisjointUnionSafeEnv_assoc:
G1.0 ⊕ G2.0 ⊕ G3.0 = G1.0 ⊕ (G2.0 ⊕ G3.0)
lemma foldl_nonDisjointUnionSafeEnv_prop:
foldl op ⊕ (G' ⊕ G) Gs = G' ⊕ foldl op ⊕ G Gs
lemma nonDisjointUnionSafeEnv_conmutative:
def_nonDisjointUnionSafeEnv G G' ==> G ⊕ G' = G' ⊕ G
lemma dom_foldl_nonDisjointUnionSafeEnv_monotone:
dom (foldl op ⊕ (empty ⊕ x) xs) = dom x ∪ dom (foldl op ⊕ empty xs)
lemma nonDisjointUnionSafeEnv_empty:
empty ⊕ x = x
lemma dom_atom2var_fv:
∃y. x = VarE y unit ==> dom [atom2var x |-> y] = fv x
lemma atom_fvs_VarE:
[| ∀a∈set as. atom a; xa ∈ fvs' as |] ==> ∃i<length as. ∃a. as ! i = VarE xa a
lemma nth_nonDisjointUnionSafeEnvList:
[| length xs = length ms;
def_nonDisjointUnionSafeEnvList (maps_of (zip xs ms)) |]
==> ∀i<length xs.
nonDisjointUnionSafeEnvList (maps_of (zip xs ms)) (xs ! i) =
Some (ms ! i)
lemma dom_nonDisjointUnionSafeEnvList_fvs:
[| ∀a∈set xs. atom a; length xs = length ys |]
==> fvs' xs
⊆ dom (nonDisjointUnionSafeEnvList (maps_of (zip (map atom2var xs) ys)))
lemma nonDisjointUnionSafeEnvList_prop1:
[| nonDisjointUnionSafeEnvList (maps_of (zip (map atom2var as) ms)) ⊆m Γ;
xa ∈ fvs' as; Γ xa = Some y;
def_nonDisjointUnionSafeEnvList (maps_of (zip (map atom2var as) ms));
∀a∈set as. atom a; length as = length ms |]
==> ∃i<length as. ∃a. as ! i = VarE xa a ∧ ms ! i = y
lemma P3_APP:
[| length as = length ms; ∀a∈set as. atom a;
nonDisjointUnionSafeEnvList (maps_of (zip (map atom2var as) ms)) ⊆m Γ |]
==> fvs' as ⊆ dom Γ
lemma P3_APP_PRIMOP:
[| Γ0.0 = [atom2var a1.0 |-> s'', atom2var a2.0 |-> s''];
[atom2var a1.0 |-> s'', atom2var a2.0 |-> s''] ⊆m Γ |]
==> {atom2var a1.0, atom2var a2.0} ⊆ dom Γ