theory PG imports Main Nat List begin (*********************************** PROGRAMS **********************************) types node = nat datatype field = ff | fg | fh | Field nat datatype var = vx | vy | vz | Var nat datatype st = Copy var var node ("[_:=_,_]") | FLoad var var field node ("[_=_.._,_]") | FStore var field var node ("[_.._=_,_]") | New var node ("[_=new,_]") | Branch node node ("[?,_,_]") types prog = "node ~=> st" (*********************************** RUNTIME ***********************************) types addr = nat datatype val = Null | Addr addr ("$_") types heap = "addr ~=> field \ val" types stack = "var ~=> val" (********************************** SEMANTICS **********************************) types action = "addr option" consts filter_addr :: "addr \ (action list) \ (action list)" defs filter_addr[simp]: "filter_addr a A == (map (\x. if x=Some a then None else x) A)" consts accesses :: "(prog * heap * stack * node * (action list)) \ bool" recdef accesses "measure(\(P,h,s,n,A). length A)" "accesses (P, h, s, n, []) = True" "accesses (P, h, s, n, (act#A)) = (case P n of Some st \ (case st of [x:=y, n'] \ (case s y of Some v \ (act=None) & accesses (P,h,(s(x:=Some v)),n',A) | None \ False ) | [x=y .. f, n'] \ (case s y of Some u \ (case u of $a \ (case h a of Some fs \ ((act=Some a) & accesses (P,h,(s(x:=Some (fs f))),n',A)) | None \ False ) | Null \ False ) | None \ False ) | [x .. f=y, n'] \ (case s y of Some y' \ (case s x of Some x' \ (case x' of $a \ (case h a of Some fs \ ( (act=Some a) & accesses (P,(h(a:=Some(fs(f:=y')))),s,n',A) ) | None \ False ) | Null \ False ) | None \ False ) | None \ False ) | [x=new,n'] \ ( (act = None) & (\a. ((h a) = None) & (\A'. accesses (P, (h(a:=Some (\f. Null))), (s(x:=Some $a)), n', A') & A = filter_addr a A') ) ) | [?,n',n''] \ ( (act = None) & (accesses (P, h, s, n', A) | accesses (P, h, s, n'', A)) ) ) | None \ False )" (hints recdef_cong: rev_conj_cong) (* sanity *) consts MyProg :: prog defs MyProg_def[simp]: "MyProg == [1\[vx=new,2], 2\[vx:=vy,3], 3\[vz .. ff=vz,4]]" lemma "(b~=Some a & c~=Some a) \ (filter_addr a [b,c] = [b,c])" by simp lemma "(b~=Some a) \ (filter_addr a [b,Some a] = [b,None])" by (simp) lemma "accesses (MyProg,[a\(\f. Null)],[vz\$a],3,[Some a])" by (simp) lemma always_another_address1[simp]: "(EX aa::addr . a ~= aa)" apply(rule_tac x = "Suc(a)" in exI) apply(simp) done lemma always_another_address2[simp]: "(EX aa::addr . aa ~= a)" apply(rule_tac x = "Suc(a)" in exI) by (simp) lemma "accesses (MyProg,[a\(\f. Null)],[vz\$a,vy\$b],1,[None,None,Some a])" apply(auto) apply(rule_tac ?x="Suc(a)" in exI) apply(auto) apply(rule_tac ?x="[None, Some a]" in exI) apply(simp) done (*********************************** ANALYSIS ***********************************) datatype edge = VarEdge var node (infix "\" 100) | FieldEdge node field node ("_\_\_" 100) types pgraph = "edge set" types analysis = "node \ pgraph" consts access:: "node \ st \ pgraph" defs access_def[simp]: "access n st == case st of [x:=y,n'] \ {} | [x=y .. f,n'] \ {y\n} | [x .. f=y,n'] \ {x\n} | [x=new,n'] \ {} | [?,n',n''] \ {}" consts translate:: "node \ st \ analysis \ pgraph" defs translate_def[simp]: "translate n st X == case st of [x:=y,next] \ ((X next) - {x\n' | n'. x\n'\(X next)}) \ {y\n' | n'. x\n'\(X next)} | [x=y .. f,next] \ ((X next) - {x\n' | n'. x\n'\(X next)}) \ {n\f\n' | n'. x\n'\(X next)} | [x .. f=y,next] \ ((X next) - {e. \n' n''. (e=(n'\f\n'')) & x\n'\(X next) & \(\z.(z~=x) & z\n'\(X next)) & \(\n''' f. (n'''\f\n')\(X next))}) \ {y\n' | n'. (\n'' . (n''\f\n')\(X next))} | [x=new,next] \ (X next) - {x\n' | n'. x\n'\(X next)} | [?,tnext,fnext] \ (X tnext) \ (X fnext) " consts wfpgraph:: "prog \ analysis \ node \ bool" defs wfpgraph_def[simp]: "wfpgraph P X n == case P n of Some st \ (X n) = (access n st) \ (translate n st X) | None \ True" consts wfanalysis:: "prog \ analysis \ bool" (infix "\" 95) defs wfanalysis_def: "P\X == \n. wfpgraph P X n" (* (* sanity *) consts anal0:: analysis defs anal0[simp]: "anal0 == \n.{}" lemma "wfanalysis MyProg (anal0(1:={vz\3}, 2:={vz\3}, 3:={vz\3}))" by (simp add: wfanalysis_def) lemma "wfanalysis [1\[vy=new,2], 2\[vx:=vy,3], 3\[vx .. f=vz,4]] (anal0(2:={vy\3}, 3:={vx\3}))" by (simp add: wfanalysis_def) lemma "wfanalysis [1\[vx=new,2], 2\[vx:=vy,3], 3\[vx .. f=vz,4]] (anal0(1:={vy\3}, 2:={vy\3}, 3:={vx\3}))" by (simp add: wfanalysis_def) *) (*********************************** SOUNDNESS ***********************************) types pgass = "node \ (addr set)" consts pgassle :: "pgass \ pgass \ bool" (infixl "\" 65 ) defs pgassle_def: "\ \ \' == \n. (\ n) \ (\' n)" consts pgassinter :: "pgass \ pgass \ pgass" (infixl "\" 65 ) defs pgassinter_def: "\ \ \' == \n. (\ n) \ (\' n)" consts pgassInter :: "pgass set \ pgass" ("\ _" 65 ) defs pgassInter_def: "\ \s == \n. \ { (\ n) | \. \\\s }" constdefs \0:: "pgass" "\0 == \n. {}" lemma \0_le[simp]: "\0 \ \" apply(simp add: pgassle_def \0_def) done lemma \0_union1[simp]: "\ \ \' \ \" apply(simp add: pgassinter_def subset_def pgassle_def) done lemma \0_union2[simp]: "\ \ \' \ \'" apply(simp add: pgassinter_def subset_def pgassle_def) done lemma \0_union_id[simp]: "\ \ \ = \" apply(simp add: pgassinter_def subset_def) done lemma pgass_ref[simp]: "\ \ \" apply(simp add: pgassle_def) done lemma pgass_id[simp]: "\ \ \0 \ \=\0" apply(simp add: \0_def pgassle_def) apply(rule ext) apply(auto) done consts pgassaddr :: "pgass \ (addr set)" defs pgassaddr_def: "pgassaddr \ == {a. \n. a\(\ n)}" consts wfpgass :: "heap \ stack \ pgraph \ pgass \ bool" ("(_,_\_:_)") defs wfpgass_def: "wfpgass h s G \ == (\x. \n. (x\n)\G \ (\x'.((s x) = x') & (\a.(x'=Some $a)\a\(\ n)))) & (\f. \n. \n'. (n\f\n')\G \ {a. \a'. a'\(\ n) & (\fs. ((h a')=Some fs) & ((fs f)=$a))} \ (\ n'))" consts minpgass :: "heap \ stack \ pgraph \ pgass" ("(\ _ _ _)") defs minpgass_def: "\ h s G == \ { \. wfpgass h s G \ }" (* sanity *) lemma "wfpgass [100\(\f. Null)(f:=$100)] [vx\$100] {vx\1,1\f\1} ((\n.{})(1:={100}))" apply(simp add:wfpgass_def) done lemma "wfpgass [100\((\f. Null)(ff:=$101))] empty {1\ff\2} ((\n.{})(1:={100},2:={101}))" apply(simp add:wfpgass_def) done consts actionlistaddr:: "(action list) \ (addr set)" defs actionlistaddr_def: "actionlistaddr A == {a. (Some a) mem A}" (* sanity *) lemma "actionlistaddr [Some a, None, Some b, Some b] = {a,b}" apply(simp add:actionlistaddr_def) apply(auto) done lemma noaction [simp]: "actionlistaddr (None#A) = actionlistaddr A" apply(simp add: actionlistaddr_def) done lemma someaction [simp]: "actionlistaddr ((Some a)#A) = {a} \ actionlistaddr A" apply(simp add: actionlistaddr_def) apply(auto) done lemma wfpgass_preserved_over_subset: "\ G'\G ; wfpgass h s G \ \ \ wfpgass h s G' \" apply(simp add: wfpgass_def) apply(blast) done (* wellformed assignments can be joined to form another assignment ultimately this can help us find a minimal assignment *) lemma wfpgass_inter: "\ \ \\\s. wfpgass h s G \ \ \ wfpgass h s G (\ \s)" apply(simp add: pgassInter_def subset_def wfpgass_def) apply(safe) apply(blast) apply(blast) done (* clearly the smallest valid assignment is valid *) lemma minpgass_sufficient: "wfpgass h s G (minpgass h s G)" apply(simp add: minpgass_def) apply(insert wfpgass_inter) apply(blast) done lemma wfpgass_always_le: "wfpgass h s G \ \ (\\'. minpgass h s G = \' \ \'\\)" apply(simp add: minpgass_def pgassInter_def pgassle_def) apply(blast) done lemma wfpgass_shrink: "wfpgass h s G \ \ (minpgass h s G) \ \" apply(drule wfpgass_always_le) apply(blast) done lemma source_aux: "\ \x. x \ n \ G \ s x \ Some $a; \n' f. (n'\f\n) \ G \ (\a' fs. h a' = Some fs \ fs f \ $a) \ \ \\. a\\ n \ wfpgass h s G \" apply (rule_tac ?x="(\n . UNIV)(n:=UNIV-{a})" in exI) apply (simp add: wfpgass_def) apply(auto) done lemma source: "a\(minpgass h s G) n \ (\x. x\n\G \ (s x = Some $a)) \ (\n' f a' fs. (n'\f\n)\G \ (h a'=Some fs) \ (fs f = $a))" apply (subgoal_tac "\h s G n a. a\(minpgass h s G) n \ (\x. x\n\G \ (s x = Some $a)) \ (\n' f a' fs. (n'\f\n)\G \ (h a'=Some fs) \ (fs f = $a))") apply(blast) apply(thin_tac "a \ minpgass h s G n") apply(simp add: minpgass_def pgassInter_def) apply(rule classical) apply(simp) apply(clarify) apply(simp) apply(drule_tac ?h="h" and ?s="s" and ?G="G" in source_aux) apply(auto) done lemma thinactionlistaddr: " actionlistaddr L - {a} \ S \ actionlistaddr (map ((\x. x)(Some a := None)) L) \ S" apply(subgoal_tac "actionlistaddr (map ((\x. x)(Some a := None)) L) = actionlistaddr L - {a}") apply(simp) apply(simp add: actionlistaddr_def) apply(thin_tac "{a. Some a mem L} - {a} \ S") apply(induct_tac L) apply(simp) apply(simp,blast) done theorem soundness: "(accesses (P,h,s,n,A)) \ (wfanalysis P X)\ (actionlistaddr A \ pgassaddr (minpgass h s (X n)))" apply(induct_tac P h s n A rule: accesses.induct) apply(simp add: actionlistaddr_def) apply(rule impI|rule allI|erule conjE|rule conjI)+ apply(case_tac "P n") apply(simp) apply(rename_tac st) apply(case_tac st) (*** x=y ***) apply(rename_tac x y n') apply(simp) apply(fold fun_upd_def) apply(case_tac "s y") apply(simp) apply(rename_tac v) apply(simp) apply(erule conjE) apply(simp add: wfanalysis_def) apply(drule_tac ?x="n" in spec) apply(simp) apply(simp only:minpgass_def pgassInter_def) apply(erule subset_trans) apply(simp only:subset_def Ball_def pgassaddr_def wfpgass_def Inter_def) apply(clarify) apply(rename_tac a n'') apply(rule_tac ?x="n''" in exI) apply(simp) apply(clarify) apply(rename_tac z \) apply(drule_tac ?x="\ n''" in spec) apply(erule impE) apply(rule_tac ?x="\" in exI) apply(simp add: wfpgass_def) apply(rule impI|rule allI|rule conjI|erule conjE)+ apply(rename_tac z n'' a) apply(case_tac "y=x") apply(simp) apply(case_tac "z=x") apply(simp) apply(drule_tac ?x="z" in spec) apply(drule_tac ?x="n''" in spec) apply(simp) apply(drule_tac ?x="z" in spec) apply(drule_tac ?x="n''" in spec) apply(simp) apply(assumption) (*** case x=y.f ***) apply(simp) apply(fold fun_upd_def) apply(rename_tac x y f n') apply(case_tac "s y") apply(simp) apply(simp) apply(rename_tac yv) apply(case_tac yv) apply(simp) apply(rename_tac targ) apply(simp) apply(case_tac "h targ") apply(simp) apply(rename_tac fs) apply(simp) apply(erule conjE) apply(subgoal_tac "actionlistaddr A \ pgassaddr (minpgass h s (X n))") apply(rule conjI) apply(thin_tac "accesses (P, h, s(x \ fs f), n', A)") apply(thin_tac "actionlistaddr A \ pgassaddr \ h s (X n)") apply(thin_tac "act = Some targ") apply(thin_tac "actionlistaddr A \ pgassaddr (\ h s(x \ fs f) (X n'))") apply(thin_tac "yv = $targ") apply(thin_tac "st = [x=y.. f,n']") apply(thin_tac "h targ = Some fs") apply(simp add: minpgass_def pgassInter_def wfpgass_def wfanalysis_def pgassaddr_def) apply(drule_tac ?x="n" in spec) apply(rule_tac ?x="n" in exI) apply(simp) apply(rule allI) apply(rename_tac addrs) apply(rule impI) apply(erule exE) apply(erule conjE)+ apply(drule_tac ?x="y" in spec) apply(drule_tac ?x="n" in spec) apply(erule conjE)+ apply(drule mp) apply(simp) apply(simp) apply(simp) apply(erule subset_trans) apply(thin_tac "st = [x=y.. f,n']") apply(thin_tac "yv = $targ") apply(thin_tac "act = Some targ") apply(thin_tac "accesses (P, h, s(x \ fs f), n', A)") apply(simp add: minpgass_def pgassInter_def subset_def pgassaddr_def) apply(rule allI) apply(rename_tac a) apply(rule impI) apply(erule exE) apply(rename_tac n'') apply(rule_tac ?x="n''" in exI) apply(rule allI) apply(rename_tac addrs) apply(rule impI) apply(drule_tac ?x="addrs" in spec) apply(erule exE) apply(rename_tac \) apply(drule mp) apply(rule_tac ?x="\" in exI) apply(erule conjE) apply(erule conjI) apply(simp add: wfanalysis_def wfpgass_def) apply(drule_tac ?x="n" in spec,simp) apply(clarify) apply(rename_tac z) apply(rule conjI) apply(rule impI) apply(rule allI) apply(rename_tac n'') apply(clarify) apply(drule_tac ?x="f" in spec) apply(drule_tac ?x="n" in spec) apply(drule_tac ?x="n''" in spec) apply(erule conjE) apply(drule mp) back apply(simp) apply(simp add: subset_def) apply(drule_tac ?x="a" in spec) apply(drule mp) apply(rule_tac ?x="targ" in exI) apply(rule conjI) apply(blast) apply(blast) apply(assumption) apply(blast) apply(assumption) (*** case x.f=y ***) apply(rename_tac x f y n') apply(simp) apply(fold fun_upd_def) apply(thin_tac "st = [x..f=y,n']") apply(case_tac "s y") apply(simp) apply(rename_tac yv) apply(case_tac "s x") apply(simp) apply(rename_tac xv) apply(simp) apply(case_tac xv) apply(simp) apply(rename_tac a) apply(case_tac "h a") apply(simp) apply(rename_tac fs) apply(simp) apply(thin_tac "xv = $a") apply(erule conjE) apply(subgoal_tac "actionlistaddr A \ pgassaddr (minpgass h s (X n)) ") apply(simp) apply(simp add: pgassaddr_def minpgass_def pgassInter_def) apply(rule_tac ?x="n" in exI) apply(rule allI) apply(rename_tac addrs) apply(rule impI) apply(erule exE) apply(thin_tac "actionlistaddr A \ {aa. \n. \x. (\\. x = \ n \ wfpgass (h(a \ fs(f := yv))) s (X n') \) \ aa \ x}") apply(thin_tac "s y = Some yv") apply(thin_tac "h a = Some fs") apply(thin_tac "act = Some a") apply(thin_tac "accesses (P,(h(a \ fs(f := yv))),s,n',A)") apply(thin_tac "actionlistaddr A \ {a. \na. \x. (\\. x = \ na \ wfpgass h s (X n) \) \ a \ x}") apply(erule conjE) apply(simp add: wfpgass_def wfanalysis_def) apply(drule_tac ?x="n" in spec) apply(simp) apply(blast) apply(thin_tac "act = Some a") apply(thin_tac "accesses(P,(h(a \ fs(f := yv))),s,n',A)") apply(erule subset_trans) apply(simp add:subset_def) apply(clarify) apply(rename_tac a') apply(simp add: pgassaddr_def) apply(clarify) apply(rename_tac n'') apply(rule_tac ?x="n''" in exI) apply(simp add: minpgass_def pgassInter_def) apply(clarify) apply(rename_tac addrs \) apply(simp) apply(drule_tac ?x="(minpgass h s (X n)) n''" in spec) apply(drule mp) apply(rule_tac ?x="minpgass h s (X n)" in exI) apply(simp) prefer 2 apply(drule wfpgass_shrink) apply(unfold pgassle_def) apply(blast) apply(thin_tac "h,s\X n:\") apply(subgoal_tac "h,s\X n:(minpgass h s (X n))") prefer 2 apply(rule minpgass_sufficient) apply(simp only: wfanalysis_def wfpgraph_def) apply(drule_tac ?x="n" in spec) apply(simp|clarify)+ apply(thin_tac "X n = insert (x \ n) (X n' - {e. \n'a. (\n''. e = (n'a\f\n'')) \ x \ n'a \ X n' \ (\z. z = x \ z \ n'a \ X n') \ (\n''' f. (n'''\f\n'a) \ X n')} \ {y \ n'a |n'a. \n''. (n''\f\n'a) \ X n'})") apply(thin_tac "P n = Some [x..f=y,n']") apply(simp (no_asm_simp) only: wfpgass_def) apply(clarify|simp)+ apply(intro conjI impI allI) apply(simp only: wfpgass_def) apply(clarify|simp)+ apply(rename_tac n1 n2 a2 a1) apply(case_tac "a1 = a") apply(simp) apply(clarify) apply(simp (no_asm) add: minpgass_def pgassInter_def) apply(simp (no_asm) only: wfpgass_def) apply(clarify) apply(simp (no_asm_simp)) apply(drule_tac ?x="y" in spec) apply(drule_tac ?x="n2" in spec) apply(drule mp) apply(blast) apply(blast) apply(simp|clarify)+ apply(rename_tac "fs1") apply(frule source) apply(simp|clarify)+ apply(erule disjE) apply(simp|clarify)+ apply(rename_tac z) apply(erule disjE) apply(simp|clarify)+ apply(erule disjE) apply(simp only: wfpgass_def) apply(simp|clarify)+ apply(drule_tac ?x="f" in spec) apply(drule_tac ?x="n1" in spec) apply(drule_tac ?x="n2" in spec) apply(simp|clarify)+ apply(drule mp) apply(subgoal_tac "z\x") apply(blast) apply(simp|clarify)+ apply(drule_tac ?x="z" in spec) apply(drule_tac ?x="n1" in spec) apply(simp|clarify)+ apply(blast) apply(simp|clarify)+ apply(rename_tac n3) apply(simp only: wfpgass_def) apply(simp|clarify)+ apply(drule_tac ?x="f" in spec) apply(drule_tac ?x="n1" in spec) apply(drule_tac ?x="n2" in spec) apply(simp|clarify)+ apply(drule mp) apply(blast) apply(blast) apply(simp|clarify)+ apply(rename_tac n3 f3 a9 fs9) apply(simp only: wfpgass_def) apply(erule conjE) apply(drule_tac ?x="f" in spec) apply(drule_tac ?x="n1" in spec) apply(drule_tac ?x="n2" in spec) apply(drule mp) back apply(blast) apply(simp only: subset_def) apply(simp only: Ball_def) apply(drule_tac ?x="a2" in spec) apply(blast) apply(rename_tac f0 n1 n2) apply(clarify|simp)+ apply(rename_tac a2 a1) apply(subgoal_tac "a1 \ minpgass h s (insert (x \ n) (X n' - {e. \n'a. (\n''. e = (n'a\f\n'')) \ x \ n'a \ X n' \ (\z. z = x \ z \ n'a \ X n') \ (\n''' f. (n'''\f\n'a) \ X n')} \ {y \ n'a |n'a. \n''. (n''\f\n'a) \ X n'})) n1 \ (\fs. (h a1 = Some fs) \ (fs f0 = $a2))") apply(simp|clarify)+ apply(rename_tac fs1) apply(simp only: wfpgass_def) apply(simp|clarify)+ apply(drule_tac ?x="f0" in spec) apply(drule_tac ?x="n1" in spec) apply(drule_tac ?x="n2" in spec) apply(blast) apply(blast) (*** new ***) apply(rename_tac x n') apply(simp) apply(fold fun_upd_def) apply(erule conjE) apply(erule exE) apply(erule conjE) apply(erule exE) apply(rename_tac "A'") apply(drule_tac ?x="a" in spec) apply(drule_tac ?x="A'" in spec) apply(simp) apply(thin_tac "st = [x=new,n']") apply(thin_tac "act = None") apply(thin_tac "h a = None") apply(erule conjE) apply(thin_tac "A = map ((\x. x)(Some a := None)) A'") apply(thin_tac "accesses (P, h(a \ \f. Null), s(x \ $a), n', A')") apply(simp add: wfanalysis_def) apply(drule_tac ?x="n" in spec) apply(simp) apply(thin_tac "P n = Some [x=new,n']") apply(thin_tac "X n = X n' - {x \ n'a |n'a. x \ n'a \ X n'}") apply(simp) apply(rule thinactionlistaddr) apply(simp add: minpgass_def actionlistaddr_def pgassInter_def pgassaddr_def) apply(simp add: subset_def Ball_def) apply(intro allI impI) apply(rename_tac a') apply(erule conjE) apply(drule_tac ?x="a'" in spec) apply(simp) apply(thin_tac "Some a' mem A'") apply(erule exE) apply(rename_tac "n") apply(rule_tac ?x="n" in exI) apply(rule allI) apply(rename_tac "addrs") apply(rule impI) apply(drule_tac ?x="addrs \ {a}" in spec) apply(drule mp) apply(erule exE) apply(erule conjE) apply(thin_tac "a' \ a") apply(simp) apply(rule_tac ?x="\n.{a} \ \ n" in exI) apply(simp) apply(clarify) apply(simp) apply(unfold wfpgass_def) apply(rule conjI) apply(clarify) apply(simp) apply(blast) apply(simp) apply(blast) apply(simp) (*** if ***) apply(rename_tac n' n'') apply(simp) apply(erule conjE) apply(erule disjE) apply(thin_tac "accesses (P, h, s, n'', A) \ actionlistaddr A \ pgassaddr \ h s (X n'')") apply(simp) apply(simp add: wfanalysis_def pgassaddr_def) apply(drule_tac ?x="n" in spec) apply(simp) apply(subgoal_tac "{a. \n. a \ (\ h s (X n')) n} \ {a. \n. a \ (\ h s ((X n') \ (X n''))) n}") apply(blast) apply(thin_tac "accesses (P, h, s, n', A)") apply(thin_tac "act = None") apply(thin_tac "X n = X n' \ X n''") apply(thin_tac "P n = Some [?,n',n'']") apply(thin_tac "actionlistaddr A \ {a. \n. a \ (\ h s (X n')) n}") apply(thin_tac "st = [?,n',n'']") apply(simp add: minpgass_def subset_def pgassInter_def) apply(clarify) apply(rule_tac ?x="n" in exI) apply(clarify) apply(drule_tac ?x="\ n" in spec) apply(drule mp) apply(simp add: subset_def Ball_def) apply(rule_tac ?x="\" in exI) apply(insert wfpgass_preserved_over_subset) apply(blast) apply(blast) apply(thin_tac "accesses (P, h, s, n', A) \ actionlistaddr A \ pgassaddr \ h s (X n')") apply(simp) apply(simp add: wfanalysis_def pgassaddr_def) apply(drule_tac ?x="n" in spec) apply(simp) apply(subgoal_tac "{a. \n. a \ (\ h s (X n'')) n} \ {a. \n. a \ (\ h s ((X n') \ (X n''))) n}") apply(blast) apply(thin_tac "accesses (P, h, s, n'', A)") apply(thin_tac "act = None") apply(thin_tac "X n = X n' \ X n''") apply(thin_tac "P n = Some [?,n',n'']") apply(thin_tac "actionlistaddr A \ {a. \n. a \ (\ h s (X n'')) n}") apply(thin_tac "st = [?,n',n'']") apply(simp add: minpgass_def subset_def pgassInter_def) apply(clarify) apply(rule_tac ?x="n" in exI) apply(clarify) apply(drule_tac ?x="\ n" in spec) apply(drule mp) apply(simp add: subset_def Ball_def) apply(rule_tac ?x="\" in exI) apply(insert wfpgass_preserved_over_subset) apply(blast) apply(blast) done end