Up to index of Isabelle/HOL/JinjaThreads
theory Correctness1(* Title: JinjaThreads/Compiler/Correctness1.thy Author: Andreas Lochbihler, Tobias Nipkow *) header {* \isaheader{Correctness of Stage 1} *} theory Correctness1 imports J1WellForm Compiler1 "../J/DefAssPreservation" "../Framework/FWBisimulation" "../Common/ExternalCallWF" begin lemma [simp]: fixes e :: "('a, 'b) exp" and es :: "('a, 'b) exp list" shows τmove0_compP: "τmove0 (compP f P) h e = τmove0 P h e" and τmoves0_compP: "τmoves0 (compP f P) h es = τmoves0 P h es" by(induct e and es) auto lemma τMove0_compP [simp]: "τMove0 (compP f P) = τMove0 P" by(intro ext) auto lemma [simp]: fixes e :: "('a, 'b) exp" and es :: "('a, 'b) exp list" shows τmove1_compP: "τmove1 (compP f P) h e = τmove1 P h e" and τmoves1_compP: "τmoves1 (compP f P) h es = τmoves1 P h es" by(induct e and es) auto lemma τMove1_compP [simp]: "τMove1 (compP f P) = τMove1 P" by(intro ext) auto lemma index_le_lengthD: "index xs x < length xs ==> x ∈ set xs" by(erule contrapos_pp)(simp) lemma not_hidden_index_nth: "[| i < length Vs; ¬ hidden Vs i |] ==> index Vs (Vs ! i) = i" by(induct Vs arbitrary: i)(auto split: split_if_asm nat.split_asm simp add: nth_Cons hidden_def) lemma hidden_snoc_nth: assumes len: "i < length Vs" shows "hidden (Vs @ [Vs ! i]) i" proof(cases "hidden Vs i") case True thus ?thesis by simp next case False with len have "index Vs (Vs ! i) = i" by(rule not_hidden_index_nth) moreover from len have "hidden (Vs @ [Vs ! i]) (index Vs (Vs ! i))" by(auto intro: hidden_index) ultimately show ?thesis by simp qed lemma τred0r_preserves_defass: assumes wf: "wf_J_prog P" shows "[| τred0r extTA P h (e, xs) (e', xs'); \<D> e ⌊dom xs⌋ |] ==> \<D> e' ⌊dom xs'⌋" by(induct rule: rtranclp_induct2)(auto dest: red_preserves_defass[OF wf]) lemma τred0t_preserves_defass: assumes wf: "wf_J_prog P" shows "[| τred0t extTA P h (e, xs) (e', xs'); \<D> e ⌊dom xs⌋ |] ==> \<D> e' ⌊dom xs'⌋" by(rule τred0r_preserves_defass[OF wf])(rule tranclp_into_rtranclp) section{*Correctness of program compilation *} consts unmod :: "expr1 => nat => bool" unmods :: "expr1 list => nat => bool" primrec "unmod (new C) i = True" "unmod (newA T⌊e⌉) i = unmod e i" "unmod (Cast C e) i = unmod e i" "unmod (Val v) i = True" "unmod (e1 «bop» e2) i = (unmod e1 i ∧ unmod e2 i)" "unmod (Var i) j = True" "unmod (i:=e) j = (i ≠ j ∧ unmod e j)" "unmod (a⌊i⌉) j = (unmod a j ∧ unmod i j)" "unmod (a⌊i⌉:=e) j = (unmod a j ∧ unmod i j ∧ unmod e j)" "unmod (a•length) j = unmod a j" "unmod (e•F{D}) i = unmod e i" "unmod (e1•F{D}:=e2) i = (unmod e1 i ∧ unmod e2 i)" "unmod (e•M(es)) i = (unmod e i ∧ unmods es i)" "unmod {j:T=vo; e} i = ((i = j --> vo = None) ∧ unmod e i)" "unmod (syncV (o') e) i = (unmod o' i ∧ unmod e i ∧ i ≠ V)" "unmod (insyncV (a) e) i = unmod e i" "unmod (e1;;e2) i = (unmod e1 i ∧ unmod e2 i)" "unmod (if (e) e1 else e2) i = (unmod e i ∧ unmod e1 i ∧ unmod e2 i)" "unmod (while (e) c) i = (unmod e i ∧ unmod c i)" "unmod (throw e) i = unmod e i" "unmod (try e1 catch(C i) e2) j = (unmod e1 j ∧ (if i=j then False else unmod e2 j))" "unmods ([]) i = True" "unmods (e#es) i = (unmod e i ∧ unmods es i)" lemma unmods_map_Val [simp]: "unmods (map Val vs) V" by(induct vs) simp_all lemma hidden_unmod: "hidden Vs i ==> unmod (compE1 Vs e) i" and hidden_unmods: "hidden Vs i ==> unmods (compEs1 Vs es) i" apply(induct e and es arbitrary: Vs and Vs) apply (simp_all add:hidden_inacc) apply(auto simp add:hidden_def) done lemma unmod_extRet2J [simp]: "unmod (extRet2J va) i" by(cases va) simp_all lemma red1_preserves_unmod: "[| P \<turnstile>1 〈e, s〉 -ta-> 〈e', s'〉; unmod e i |] ==> (lcl s') ! i = (lcl s) ! i" and reds1_preserves_unmod: "[| P \<turnstile>1 〈es, s〉 [-ta->] 〈es', s'〉; unmods es i |] ==> (lcl s') ! i = (lcl s) ! i" apply(induct rule: red1_reds1.inducts) apply(auto split: split_if_asm) done lemma red1_unmod_preserved: "[| P \<turnstile>1 〈e, s〉 -ta-> 〈e', s'〉; unmod e i |] ==> unmod e' i" and reds1_unmods_preserved: "[| P \<turnstile>1 〈es, s〉 [-ta->] 〈es', s'〉; unmods es i |] ==> unmods es' i" by(induct rule: red1_reds1.inducts)(auto split: split_if_asm) lemma τred1't_unmod_preserved: "[| τred1't P h (e, xs) (e', xs'); unmod e i |] ==> unmod e' i" by(induct rule: tranclp_induct2)(auto intro: red1_unmod_preserved) lemma τred1'r_unmod_preserved: "[| τred1'r P h (e, xs) (e', xs'); unmod e i |] ==> unmod e' i" by(induct rule: rtranclp_induct2)(auto intro: red1_unmod_preserved) lemma τred1't_preserves_unmod: "[|τred1't P h (e, xs) (e', xs'); unmod e i; i < length xs |] ==> xs' ! i = xs ! i" apply(induct rule: tranclp_induct2) apply(auto dest: red1_preserves_unmod) apply(drule red1_preserves_unmod) apply(erule (1) τred1't_unmod_preserved) apply(drule τred1't_preserves_len) apply auto done lemma τred1'r_preserves_unmod: "[|τred1'r P h (e, xs) (e', xs'); unmod e i; i < length xs |] ==> xs' ! i = xs ! i" apply(induct rule: converse_rtranclp_induct2) apply(auto dest: red1_preserves_unmod red1_unmod_preserved red1_preserves_len) apply(frule (1) red1_unmod_preserved) apply(frule red1_preserves_len) apply(frule (1) red1_preserves_unmod) apply auto done lemma max_dest: "(n :: nat) + max a b ≤ c ==> n + a ≤ c ∧ n + b ≤ c" apply(auto simp add: max_def split: split_if_asm) done declare max_dest [dest!] lemma fv_unmod_compE1: "[| i < length Vs; Vs ! i ∉ fv e |] ==> unmod (compE1 Vs e) i" and fvs_unmods_compEs1: "[| i < length Vs; Vs ! i ∉ fvs es |] ==> unmods (compEs1 Vs es) i" proof(induct e and es arbitrary: Vs and Vs) case (Block V ty vo exp) note IH = `!!Vs. [|i < length Vs; Vs ! i ∉ fv exp |] ==> unmod (compE1 Vs exp) i` note len = `i < length Vs` hence i: "i < length (Vs @ [V])" by simp show ?case proof(cases "Vs ! i = V") case True from len have "hidden (Vs @ [Vs ! i]) i" by(rule hidden_snoc_nth) with len True show ?thesis by(auto intro: hidden_unmod) next case False with `Vs ! i ∉ fv {V:ty=vo; exp}` len have "(Vs @ [V]) ! i ∉ fv exp" by(auto simp add: nth_append) from IH[OF i this] len show ?thesis by(auto) qed next case (TryCatch e1 C V e2) note IH1 = `!!Vs. [|i < length Vs; Vs ! i ∉ fv e1 |] ==> unmod (compE1 Vs e1) i` note IH2 = `!!Vs. [|i < length Vs; Vs ! i ∉ fv e2 |] ==> unmod (compE1 Vs e2) i` note len = `i < length Vs` hence i: "i < length (Vs @ [V])" by simp have "unmod (compE1 (Vs @ [V]) e2) i" proof(cases "Vs ! i = V") case True from len have "hidden (Vs @ [Vs ! i]) i" by(rule hidden_snoc_nth) with len True show ?thesis by(auto intro: hidden_unmod) next case False with `Vs ! i ∉ fv (try e1 catch(C V) e2)` len have "(Vs @ [V]) ! i ∉ fv e2" by(auto simp add: nth_append) from IH2[OF i this] len show ?thesis by(auto) qed with IH1[OF len] `Vs ! i ∉ fv (try e1 catch(C V) e2)` len show ?case by(auto) qed(auto dest: index_le_lengthD simp add: nth_append) lemma hidden_lengthD: "hidden Vs i ==> i < length Vs" by(simp add: hidden_def) lemma fv_B_unmod: "[| V ∉ fv e; \<B> e n; V < n |] ==> unmod e V" and fvs_Bs_unmods: "[| V ∉ fvs es; \<B>s es n; V < n |] ==> unmods es V" by(induct e and es arbitrary: n and n) auto lemma assumes fin: "final e'" shows unmod_inline_call: "unmod (inline_call e' e) V <-> unmod e V" and unmods_inline_calls: "unmods (inline_calls e' es) V <-> unmods es V" apply(induct e and es) apply(insert fin) apply(auto simp add: is_vals_conv) done lemma LAss_lem: "[|x ∈ set xs; size xs ≤ size ys |] ==> m1 ⊆m m2(xs[\<mapsto>]ys) ==> m1(x\<mapsto>y) ⊆m m2(xs[\<mapsto>]ys[index xs x := y])" apply(simp add:map_le_def) apply(simp add:fun_upds_apply index_less_aux eq_sym_conv) done lemma Block_lem: fixes l :: "'a \<rightharpoonup> 'b" assumes 0: "l ⊆m [Vs [\<mapsto>] ls]" and 1: "l' ⊆m [Vs [\<mapsto>] ls', V\<mapsto>v]" and hidden: "V ∈ set Vs ==> ls ! index Vs V = ls' ! index Vs V" and size: "size ls = size ls'" "size Vs < size ls'" shows "l'(V := l V) ⊆m [Vs [\<mapsto>] ls']" proof - have "l'(V := l V) ⊆m [Vs [\<mapsto>] ls', V\<mapsto>v](V := l V)" using 1 by(rule map_le_upd) also have "… = [Vs [\<mapsto>] ls'](V := l V)" by simp also have "… ⊆m [Vs [\<mapsto>] ls']" proof (cases "l V") case None thus ?thesis by simp next case (Some w) hence "[Vs [\<mapsto>] ls] V = Some w" using 0 by(force simp add: map_le_def split:if_splits) hence VinVs: "V ∈ set Vs" and w: "w = ls ! index Vs V" using size by(auto simp add:fun_upds_apply split:if_splits) hence "w = ls' ! index Vs V" using hidden[OF VinVs] by simp hence "[Vs [\<mapsto>] ls'](V := l V) = [Vs [\<mapsto>] ls']" using Some size VinVs by(simp add:index_less_aux map_upds_upd_conv_index) thus ?thesis by simp qed finally show ?thesis . qed declare compEs1_conv_map [simp del] section {* The delay bisimulation relation *} text {* Delay bisimulation for expressions *} inductive bisim :: "vname list => expr => expr1 => val list => bool" and bisims :: "vname list => expr list => expr1 list => val list => bool" where bisimNew: "bisim Vs (new C) (new C) xs" | bisimNewArray: "bisim Vs e e' xs ==> bisim Vs (newA T⌊e⌉) (newA T⌊e'⌉) xs" | bisimCast: "bisim Vs e e' xs ==> bisim Vs (Cast T e) (Cast T e') xs" | bisimVal: "bisim Vs (Val v) (Val v) xs" | bisimBinOp1: "[| bisim Vs e e' xs; ¬ is_val e; ¬ contains_insync e'' |] ==> bisim Vs (e «bop» e'') (e' «bop» compE1 Vs e'') xs" | bisimBinOp2: "bisim Vs e e' xs ==> bisim Vs (Val v «bop» e) (Val v «bop» e') xs" | bisimVar: "bisim Vs (Var V) (Var (index Vs V)) xs" | bisimLAss: "bisim Vs e e' xs ==> bisim Vs (V:=e) (index Vs V:=e') xs" | bisimAAcc1: "[| bisim Vs a a' xs; ¬ is_val a; ¬ contains_insync i |] ==> bisim Vs (a⌊i⌉) (a'⌊compE1 Vs i⌉) xs" | bisimAAcc2: "bisim Vs i i' xs ==> bisim Vs (Val v⌊i⌉) (Val v⌊i'⌉) xs" | bisimAAss1: "[| bisim Vs a a' xs; ¬ is_val a; ¬ contains_insync i; ¬ contains_insync e |] ==> bisim Vs (a⌊i⌉:=e) (a'⌊compE1 Vs i⌉:=compE1 Vs e) xs" | bisimAAss2: "[| bisim Vs i i' xs; ¬ is_val i; ¬ contains_insync e |] ==> bisim Vs (Val v⌊i⌉:=e) (Val v⌊i'⌉:=compE1 Vs e) xs" | bisimAAss3: "bisim Vs e e' xs ==> bisim Vs (Val v⌊Val i⌉ := e) (Val v⌊Val i⌉ := e') xs" | bisimALength: "bisim Vs a a' xs ==> bisim Vs (a•length) (a'•length) xs" | bisimFAcc: "bisim Vs e e' xs ==> bisim Vs (e•F{D}) (e'•F{D}) xs" | bisimFAss1: "[| bisim Vs e e' xs; ¬ is_val e; ¬ contains_insync e'' |] ==> bisim Vs (e•F{D}:=e'') (e'•F{D}:=compE1 Vs e'') xs" | bisimFAss2: "bisim Vs e e' xs ==> bisim Vs (Val v•F{D} := e) (Val v•F{D} := e') xs" | bisimCallObj: "[| bisim Vs e e' xs; ¬ is_val e; ¬ contains_insyncs es |] ==> bisim Vs (e•M(es)) (e'•M(compEs1 Vs es)) xs" | bisimCallParams: "bisims Vs es es' xs ==> bisim Vs (Val v•M(es)) (Val v•M(es')) xs" | bisimBlockNone: "bisim (Vs@[V]) e e' xs ==> bisim Vs {V:T=None; e} {(length Vs):T=None; e'} xs" | bisimBlockSome: "[| bisim (Vs@[V]) e e' (xs[length Vs := v]) |] ==> bisim Vs {V:T=⌊v⌋; e} {(length Vs):T=⌊v⌋; e'} xs" | bisimBlockSomeNone: "[| bisim (Vs@[V]) e e' xs; xs ! (length Vs) = v |] ==> bisim Vs {V:T=⌊v⌋; e} {(length Vs):T=None; e'} xs" | bisimSynchronized: "[| bisim Vs o' o'' xs; ¬ contains_insync e |] ==> bisim Vs (sync(o') e) (synclength Vs(o'') (compE1 (Vs@[fresh_var Vs]) e)) xs" | bisimInSynchronized: "[| bisim (Vs@[fresh_var Vs]) e e' xs; xs ! length Vs = Addr a |] ==> bisim Vs (insync(a) e) (insynclength Vs(a) e') xs" | bisimSeq: "[| bisim Vs e e' xs; ¬ contains_insync e'' |] ==> bisim Vs (e;;e'') (e';;compE1 Vs e'') xs" | bisimCond: "[| bisim Vs e e' xs; ¬ contains_insync e1; ¬ contains_insync e2 |] ==> bisim Vs (if (e) e1 else e2) (if (e') (compE1 Vs e1) else (compE1 Vs e2)) xs" | bisimWhile: "[| ¬ contains_insync b; ¬ contains_insync e |] ==> bisim Vs (while (b) e) (while (compE1 Vs b) (compE1 Vs e)) xs" | bisimThrow: "bisim Vs e e' xs ==> bisim Vs (throw e) (throw e') xs" | bisimTryCatch: "[| bisim Vs e e' xs; ¬ contains_insync e'' |] ==> bisim Vs (try e catch(C V) e'') (try e' catch(C (length Vs)) compE1 (Vs@[V]) e'') xs" | bisimsNil: "bisims Vs [] [] xs" | bisimsCons1: "[| bisim Vs e e' xs; ¬ is_val e; ¬ contains_insyncs es |] ==> bisims Vs (e # es) (e' # compEs1 Vs es) xs" | bisimsCons2: "bisims Vs es es' xs ==> bisims Vs (Val v # es) (Val v # es') xs" declare bisimNew [iff] declare bisimVal [iff] declare bisimVar [iff] declare bisimWhile [iff] declare bisimsNil [iff] declare bisim_bisims.intros [intro!] declare bisimsCons1 [rule del, intro] bisimsCons2 [rule del, intro] bisimBinOp1 [rule del, intro] bisimAAcc1 [rule del, intro] bisimAAss1 [rule del, intro] bisimAAss2 [rule del, intro] bisimFAss1 [rule del, intro] bisimCallObj [rule del, intro] inductive_cases bisim_safe_cases [elim!]: "bisim Vs (new C) e' xs" "bisim Vs (newA T⌊e⌉) e' xs" "bisim Vs (Cast T e) e' xs" "bisim Vs (Val v) e' xs" "bisim Vs (Var V) e' xs" "bisim Vs (V:=e) e' xs" "bisim Vs (Val v⌊i⌉) e' xs" "bisim Vs (Val v⌊Val v'⌉ := e) e' xs" "bisim Vs (a•length) e' xs" "bisim Vs (e•F{D}) e' xs" "bisim Vs (sync(o') e) e' xs" "bisim Vs (insync(a) e) e' xs" "bisim Vs (e;;e') e'' xs" "bisim Vs (if (b) e1 else e2) e' xs" "bisim Vs (while (b) e) e' xs" "bisim Vs (throw e) e' xs" "bisim Vs (try e catch(C V) e') e'' xs" "bisim Vs e' (new C) xs" "bisim Vs e' (newA T⌊e⌉) xs" "bisim Vs e' (Cast T e) xs" "bisim Vs e' (Val v) xs" "bisim Vs e' (Var V) xs" "bisim Vs e' (V:=e) xs" "bisim Vs e' (Val v⌊i⌉) xs" "bisim Vs e' (Val v⌊Val v'⌉ := e) xs" "bisim Vs e' (a•length) xs" "bisim Vs e' (e•F{D}) xs" "bisim Vs e' (syncV (o') e) xs" "bisim Vs e' (insyncV (a) e) xs" "bisim Vs e'' (e;;e') xs" "bisim Vs e' (if (b) e1 else e2) xs" "bisim Vs e' (while (b) e) xs" "bisim Vs e' (throw e) xs" "bisim Vs e'' (try e catch(C V) e') xs" inductive_cases bisim_cases [elim]: "bisim Vs (e1 «bop» e2) e' xs" "bisim Vs (a⌊i⌉) e' xs" "bisim Vs (a⌊i⌉:=e) e' xs" "bisim Vs (e•F{D}:=e') e'' xs" "bisim Vs (e•M(es)) e' xs" "bisim Vs {V:T=vo; e} e' xs" "bisim Vs e' (e1 «bop» e2) xs" "bisim Vs e' (a⌊i⌉) xs" "bisim Vs e' (a⌊i⌉:=e) xs" "bisim Vs e'' (e•F{D}:=e') xs" "bisim Vs e' (e•M(es)) xs" "bisim Vs e' {V:T=vo; e} xs" inductive_cases bisims_safe_cases [elim!]: "bisims Vs [] es xs" "bisims Vs es [] xs" inductive_cases bisims_cases [elim]: "bisims Vs (e # es) es' xs" "bisims Vs es' (e # es) xs" lemma bisims_map_Val_conv [simp]: "bisims Vs (map Val vs) es xs = (es = map Val vs)" apply(induct vs arbitrary: es) apply(fastsimp) apply(simp) apply(rule iffI) apply(erule bisims_cases, auto) done lemma bisim_contains_insync: "bisim Vs e e' xs ==> contains_insync e = contains_insync e'" and bisims_contains_insyncs: "bisims Vs es es' xs ==> contains_insyncs es = contains_insyncs es'" by(induct rule: bisim_bisims.inducts) auto lemma bisims_map_Val_Throw: "bisims Vs (map Val vs @ Throw a # es) es' xs <-> es' = map Val vs @ Throw a # compEs1 Vs es ∧ ¬ contains_insyncs es" apply(induct vs arbitrary: es') apply(simp) apply(rule iffI) apply(erule bisims_cases) apply(clarsimp) apply(simp) apply(simp) apply(rule bisimsCons1) apply(fastsimp) apply(fastsimp) apply simp apply(clarsimp) apply(rule iffI) apply(erule bisims_cases) apply(simp) apply(simp) apply(simp) apply(rule bisimsCons2) apply(simp) done lemma compE1_bisim [intro]: "[| fv e ⊆ set Vs; ¬ contains_insync e |] ==> bisim Vs e (compE1 Vs e) xs" and compEs1_bisims [intro]: "[| fvs es ⊆ set Vs; ¬ contains_insyncs es |] ==> bisims Vs es (compEs1 Vs es) xs" proof(induct e and es arbitrary: Vs xs and Vs xs) case (BinOp exp1 bop exp2 Vs x) thus ?case by(cases "is_val exp1")(auto) next case (AAcc exp1 exp2 Vs x) thus ?case by(cases "is_val exp1")(auto) next case (AAss exp1 exp2 exp3 Vs x) thus ?case by(cases "is_val exp1", cases "is_val exp2", fastsimp+) next case (FAss exp1 F D exp2 Vs x) thus ?case by(cases "is_val exp1", auto) next case (Call obj M params Vs x) thus ?case by(cases "is_val obj")(auto) next case (Block V T vo exp Vs xs) from `fv {V:T=vo; exp} ⊆ set Vs` have "fv exp ⊆ set (Vs@[V])" by(auto) with Block show ?case by(cases vo)(auto) next case (Cons_exp exp list Vs x) thus ?case by(cases "is_val exp")(auto intro!: bisimsCons2) qed(auto) lemma bisim_hidden_unmod: "[| bisim Vs e e' xs; hidden Vs i |] ==> unmod e' i" and bisims_hidden_unmods: "[| bisims Vs es es' xs; hidden Vs i |] ==> unmods es' i" by(induct rule: bisim_bisims.inducts)(auto intro: hidden_unmod hidden_unmods dest: hidden_inacc hidden_lengthD) lemma bisim_fv_unmod: "[| bisim Vs e e' xs; i < length Vs; Vs ! i ∉ fv e |] ==> unmod e' i" and bisims_fvs_unmods: "[| bisims Vs es es' xs; i < length Vs; Vs ! i ∉ fvs es |] ==> unmods es' i" proof(induct rule: bisim_bisims.inducts) case (bisimBlockNone Vs V e e' xs T) note len = `i < length Vs` have "unmod e' i" proof(cases "Vs ! i = V") case True from len have "hidden (Vs @ [Vs ! i]) i" by(rule hidden_snoc_nth) with len True `bisim (Vs @ [V]) e e' xs` show ?thesis by(auto intro: bisim_hidden_unmod) next case False with bisimBlockNone show ?thesis by(auto simp add: nth_append) qed thus ?case by simp next case (bisimBlockSome Vs V e e' xs v T) note len = `i < length Vs` show ?case proof(cases "Vs ! i = V") case True from len have "hidden (Vs @ [Vs ! i]) i" by(rule hidden_snoc_nth) with len True `bisim (Vs @ [V]) e e' (xs[length Vs := v])` show ?thesis by(auto intro: bisim_hidden_unmod) next case False with bisimBlockSome show ?thesis by(auto simp add: nth_append) qed next case (bisimBlockSomeNone Vs V e e' xs v T) note len = `i < length Vs` show ?case proof(cases "Vs ! i = V") case True from len have "hidden (Vs @ [Vs ! i]) i" by(rule hidden_snoc_nth) with len True `bisim (Vs @ [V]) e e' xs` show ?thesis by(auto intro: bisim_hidden_unmod) next case False with bisimBlockSomeNone show ?thesis by(auto simp add: nth_append) qed qed(fastsimp dest: fv_unmod_compE1 fvs_unmods_compEs1 index_le_lengthD simp add: nth_append)+ lemma bisim_extRet2J [intro!]: "bisim Vs (extRet2J va) (extRet2J1 va) xs" by(cases va) auto lemma bisims_map_Val_conv2 [simp]: "bisims Vs es (map Val vs) xs = (es = map Val vs)" apply(induct vs arbitrary: es) apply(fastsimp elim!: bisims_cases)+ done lemma bisims_map_Val_Throw2: "bisims Vs es' (map Val vs @ Throw a # es) xs <-> (∃es''. es' = map Val vs @ Throw a # es'' ∧ es = compEs1 Vs es'' ∧ ¬ contains_insyncs es'')" apply(induct vs arbitrary: es') apply(simp) apply(rule iffI) apply(erule bisims_cases) apply(clarsimp) apply(simp) apply(clarsimp) apply(rule bisimsCons1) apply(fastsimp) apply(fastsimp) apply(assumption) apply(clarsimp) apply(rule iffI) apply(erule bisims_cases) apply(fastsimp) apply(simp) apply(clarsimp) apply(rule bisimsCons2) apply(simp) done lemma hidden_bisim_unmod: "[| bisim Vs e e' xs; hidden Vs i |] ==> unmod e' i" and hidden_bisims_unmods: "[| bisims Vs es es' xs; hidden Vs i |] ==> unmods es' i" apply(induct rule: bisim_bisims.inducts) apply(auto simp add:hidden_inacc intro: hidden_unmod hidden_unmods) apply(auto simp add: hidden_def) done text {* Delay bisimulation for call stacks *} inductive bisim01 :: "expr => expr1 × locals1 => bool" where "[| bisim [] e e' xs; fv e = {}; \<D> e ⌊{}⌋; max_vars e' ≤ length xs; call e = ⌊aMvs⌋; call1 e' = ⌊aMvs⌋; this_Block_ok e; this_None_Block e' |] ==> bisim01 e (e', xs)" inductive bisim_list :: "expr list => (expr1 × locals1) list => bool" where bisim_listNil: "bisim_list [] []" | bisim_listCons: "[| bisim_list es exs'; bisim [] e e' xs; fv e = {}; \<D> e ⌊{}⌋; max_vars e' ≤ length xs; call e = ⌊aMvs⌋; call1 e' = ⌊aMvs⌋ |] ==> bisim_list (e # es) ((e', xs) # exs')" inductive_cases bisim_list_cases [elim!]: "bisim_list [] exs'" "bisim_list (ex # exs) exs'" "bisim_list exs (ex' # exs')" lemma bisim_list_list_all2_conv: "bisim_list es exs' <-> list_all2 bisim01 es exs'" proof assume "bisim_list es exs'" thus "list_all2 bisim01 es exs'" by induct(auto intro!: bisim01.intros) next assume "list_all2 bisim01 es exs'" thus "bisim_list es exs'" by(induct es arbitrary: exs')(auto intro!: bisim_listCons bisim_listNil elim!: bisim01.cases simp add: list_all2_Cons1) qed fun bisim_list1 :: "expr × expr list => (expr1 × locals1) × (expr1 × locals1) list => bool" where "bisim_list1 (e, es) ((e1, xs1), exs1) <-> bisim_list es exs1 ∧ bisim [] e e1 xs1 ∧ fv e = {} ∧ \<D> e ⌊{}⌋ ∧ max_vars e1 ≤ length xs1" lemma bisim_list1I[intro?]: "[| bisim_list es exs1; bisim [] e e1 xs1; fv e = {}; \<D> e ⌊{}⌋; max_vars e1 ≤ length xs1 |] ==> bisim_list1 (e, es) ((e1, xs1), exs1)" by simp lemma bisim_list1E[elim?]: assumes "bisim_list1 (e, es) ((e1, xs1), exs1)" obtains "bisim_list es exs1" "bisim [] e e1 xs1" "fv e = {}" "\<D> e ⌊{}⌋" "max_vars e1 ≤ length xs1" using assms by auto lemma bisim_list1_elim: assumes "bisim_list1 es' exs" obtains e es e1 xs1 exs1 where "es' = (e, es)" "exs = ((e1, xs1), exs1)" and "bisim_list es exs1" "bisim [] e e1 xs1" "fv e = {}" "\<D> e ⌊{}⌋" "max_vars e1 ≤ length xs1" using assms by(cases es')(cases exs, fastsimp) declare bisim_list1.simps [simp del] definition bisim_red0_Red1 :: "((expr × expr list) × heap) => (((expr1 × locals1) × (expr1 × locals1) list) × heap) => bool" where "bisim_red0_Red1 ≡ (λ(es, h) (exs, h'). bisim_list1 es exs ∧ h = h')" lemma bisim_list_extTA2J0_extTA2J1: assumes wf: "wf_J_prog P" and sees: "P \<turnstile> C sees M:[]->T = meth in D" and ha: "h a = ⌊Obj C fs⌋" shows "bisim_list1 (extNTA2J0 P (C, M, a)) (extNTA2J1 (compP1 P) (C, M, a))" proof - obtain pns body where "meth = (pns, body)" by(cases meth) with sees have sees: "P \<turnstile> C sees M:[]->T = (pns, body) in D" by simp moreover let ?xs = "Addr a # replicate (max_vars body) undefined" let ?e' = "{0:Class D=None; compE1 (this # pns) body}" have "bisim_list1 ({this:Class D=⌊Addr a⌋; body}, [addr a•M([])]) ((?e', ?xs), [(addr a•M([]), [])])" proof show "bisim_list [addr a•M([])] [(addr a•M([]), [])]" proof show "bisim_list [] []" .. show "bisim [] (addr a•M([])) (addr a•M([])) []" by(rule bisimCallParams)(rule bisimsNil) qed auto from sees_wf_mdecl[OF wf_prog_wwf_prog[OF wf] sees] have "fv body ⊆ set [this]" "pns = []" by(auto simp add: wf_mdecl_def) thus "fv {this:Class D=⌊Addr a⌋; body} = {}" by simp from sees_wf_mdecl[OF wf sees] obtain T' where "P,[this \<mapsto> Class D] \<turnstile> body :: T'" "this ∉ set pns" and "\<D> body ⌊dom [this \<mapsto> Addr a]⌋" by(auto simp add: wf_mdecl_def) hence "¬ contains_insync body" by(auto simp add: contains_insync_conv dest: WT_expr_locks) with `fv body ⊆ set [this]` have "bisim ([] @ [this]) body (compE1 (this # pns) body) ?xs" unfolding append.simps `pns = []` by(rule compE1_bisim) hence "bisim [] {this:Class D=⌊Addr a⌋; body} {length ([] :: String.literal list):Class D=None; compE1 (this # pns) body} ?xs" by(rule bisimBlockSomeNone)(simp) thus "bisim [] {this:Class D=⌊Addr a⌋; body} ?e' ?xs" by simp from `\<D> body ⌊dom [this \<mapsto> Addr a]⌋` show "\<D> {this:Class D=⌊Addr a⌋; body} ⌊{}⌋" by simp show "max_vars ?e' ≤ length ?xs" by simp qed ultimately show ?thesis by(simp) qed abbreviation ta_bisim01 :: "J0_thread_action => J1_thread_action => bool" where "ta_bisim01 ≡ ta_bisim bisim_red0_Red1" subsection {* Correctness proof *} lemma ta_bisim01_extTA2J0_extTA2J1: assumes wf: "wf_J_prog P" and nt: "!!n T C M a h. [| n < length \<lbrace>ta\<rbrace>t; \<lbrace>ta\<rbrace>t ! n = NewThread T (C, M, a) h |] ==> (∃fs. h a = ⌊Obj C fs⌋) ∧ (∃T meth D. P \<turnstile> C sees M:[]->T =meth in D)" shows "ta_bisim01 (extTA2J0 P ta) (extTA2J1 (compP1 P) ta)" apply(simp add: ta_bisim_def) apply(auto intro!: list_all2_all_nthI) apply(case_tac "\<lbrace>ta\<rbrace>t ! n") apply(auto simp add: bisim_red0_Red1_def) apply(drule (1) nt) apply(clarify) apply(erule (1) bisim_list_extTA2J0_extTA2J1[OF wf, simplified]) done lemma red_external_ta_bisim01: "[| wf_J_prog P; P \<turnstile> 〈a•M(vs), h〉 -ta->ext 〈va, h'〉; h a ≠ None |] ==> ta_bisim01 (extTA2J0 P ta) (extTA2J1 (compP1 P) ta)" apply(rule ta_bisim01_extTA2J0_extTA2J1, assumption) apply(drule (1) red_external_new_thread_sees, auto simp add: in_set_conv_nth) apply(drule red_ext_new_thread_heap, auto simp add: in_set_conv_nth) done lemmas τred1't_expr = NewArray_τred1't_xt Cast_τred1't_xt BinOp_τred1't_xt1 BinOp_τred1't_xt2 LAss_τred1't AAcc_τred1't_xt1 AAcc_τred1't_xt2 AAss_τred1't_xt1 AAss_τred1't_xt2 AAss_τred1't_xt3 ALength_τred1't_xt FAcc_τred1't_xt FAss_τred1't_xt1 FAss_τred1't_xt2 Call_τred1't_obj Call_τred1't_param Block_None_τred1't_xt Block_τred1't_Some Sync_τred1't_xt InSync_τred1't_xt Seq_τred1't_xt Cond_τred1't_xt Throw_τred1't_xt Try_τred1't_xt lemmas τred1'r_expr = NewArray_τred1'r_xt Cast_τred1'r_xt BinOp_τred1'r_xt1 BinOp_τred1'r_xt2 LAss_τred1'r AAcc_τred1'r_xt1 AAcc_τred1'r_xt2 AAss_τred1'r_xt1 AAss_τred1'r_xt2 AAss_τred1'r_xt3 ALength_τred1'r_xt FAcc_τred1'r_xt FAss_τred1'r_xt1 FAss_τred1'r_xt2 Call_τred1'r_obj Call_τred1'r_param Block_None_τred1'r_xt Block_τred1'r_Some Sync_τred1'r_xt InSync_τred1'r_xt Seq_τred1'r_xt Cond_τred1'r_xt Throw_τred1'r_xt Try_τred1'r_xt definition sim_move01 :: "J1_prog => J0_thread_action => expr => expr1 => heap => locals1 => external_thread_action => expr1 => heap => locals1 => bool" where "sim_move01 P ta0 e0 e h xs ta e' h' xs' <-> ¬ final e0 ∧ (if τmove0 P h e0 then h' = h ∧ ta0 = ε ∧ ta = ε ∧ τred1't P h (e, xs) (e', xs') else ∃e'' xs''. τred1'r P h (e, xs) (e'', xs'') ∧ P \<turnstile>1 〈e'', (h, xs'')〉 -ta-> 〈e', (h', xs')〉 ∧ ¬ τmove1 P h e'' ∧ ¬ IUF e'' ta e' ∧ ta_bisim01 ta0 (extTA2J1 P ta))" definition sim_moves01 :: "J1_prog => J0_thread_action => expr list => expr1 list => heap => locals1 => external_thread_action => expr1 list => heap => locals1 => bool" where "sim_moves01 P ta0 es0 es h xs ta es' h' xs' <-> ¬ finals es0 ∧ (if τmoves0 P h es0 then h' = h ∧ ta0 = ε ∧ ta = ε ∧ τreds1't P h (es, xs) (es', xs') else ∃es'' xs''. τreds1'r P h (es, xs) (es'', xs'') ∧ P \<turnstile>1 〈es'', (h, xs'')〉 [-ta->] 〈es', (h', xs')〉 ∧ ¬ τmoves1 P h es'' ∧ ¬ IUFs es'' ta es' ∧ ta_bisim01 ta0 (extTA2J1 P ta))" declare τred1't_expr [elim!] τred1'r_expr[elim!] lemma sim_move01_expr: assumes "sim_move01 P ta0 e0 e h xs ta e' h' xs'" shows "sim_move01 P ta0 (newA T⌊e0⌉) (newA T⌊e⌉) h xs ta (newA T⌊e'⌉) h' xs'" "sim_move01 P ta0 (Cast T e0) (Cast T e) h xs ta (Cast T e') h' xs'" "sim_move01 P ta0 (e0 «bop» e2) (e «bop» e2') h xs ta (e' «bop» e2') h' xs'" "sim_move01 P ta0 (Val v «bop» e0) (Val v «bop» e) h xs ta (Val v «bop» e') h' xs'" "sim_move01 P ta0 (V := e0) (V' := e) h xs ta (V' := e') h' xs'" "sim_move01 P ta0 (e0⌊e2⌉) (e⌊e2'⌉) h xs ta (e'⌊e2'⌉) h' xs'" "sim_move01 P ta0 (Val v⌊e0⌉) (Val v⌊e⌉) h xs ta (Val v⌊e'⌉) h' xs'" "sim_move01 P ta0 (e0⌊e2⌉ := e3) (e⌊e2'⌉ := e3') h xs ta (e'⌊e2'⌉ := e3') h' xs'" "sim_move01 P ta0 (Val v⌊e0⌉ := e3) (Val v⌊e⌉ := e3') h xs ta (Val v⌊e'⌉ := e3') h' xs'" "sim_move01 P ta0 (AAss (Val v) (Val v') e0) (AAss (Val v) (Val v') e) h xs ta (AAss (Val v) (Val v') e') h' xs'" "sim_move01 P ta0 (e0•length) (e•length) h xs ta (e'•length) h' xs'" "sim_move01 P ta0 (e0•F{D}) (e•F'{D'}) h xs ta (e'•F'{D'}) h' xs'" "sim_move01 P ta0 (FAss e0 F D e2) (FAss e F' D' e2') h xs ta (FAss e' F' D' e2') h' xs'" "sim_move01 P ta0 (FAss (Val v) F D e0) (FAss (Val v) F' D' e) h xs ta (FAss (Val v) F' D' e') h' xs'" "sim_move01 P ta0 (e0•M(es)) (e•M(es')) h xs ta (e'•M(es')) h' xs'" "sim_move01 P ta0 ({V:T=vo; e0}) ({V':T=None; e}) h xs ta ({V':T=None; e'}) h' xs'" "sim_move01 P ta0 (sync(e0) e2) (syncV'(e) e2') h xs ta (syncV'(e') e2') h' xs'" "sim_move01 P ta0 (insync(a) e0) (insyncV'(a') e) h xs ta (insyncV'(a') e') h' xs'" "sim_move01 P ta0 (e0;;e2) (e;;e2') h xs ta (e';;e2') h' xs'" "sim_move01 P ta0 (if (e0) e2 else e3) (if (e) e2' else e3') h xs ta (if (e') e2' else e3') h' xs'" "sim_move01 P ta0 (throw e0) (throw e) h xs ta (throw e') h' xs'" "sim_move01 P ta0 (try e0 catch(C V) e2) (try e catch(C' V') e2') h xs ta (try e' catch(C' V') e2') h' xs'" using assms by(fastsimp simp add: sim_move01_def final_iff split: split_if_asm intro: red1_reds1.intros)+ lemma sim_moves01_expr: "sim_move01 P ta0 e0 e h xs ta e' h' xs' ==> sim_moves01 P ta0 (e0 # es2) (e # es2') h xs ta (e' # es2') h' xs'" "sim_moves01 P ta0 es0 es h xs ta es' h' xs' ==> sim_moves01 P ta0 (Val v # es0) (Val v # es) h xs ta (Val v # es') h' xs'" apply(auto simp add: sim_move01_def sim_moves01_def final_iff finals_def Cons_eq_append_conv split: split_if_asm intro: red1_reds1.intros τred1't_inj_τreds1't τred1'r_inj_τreds1'r τreds1't_cons_τreds1't τreds1'r_cons_τreds1'r) apply(force elim!: τred1'r_inj_τreds1'r List1Red1) apply(force elim!: τreds1'r_cons_τreds1'r List1Red2) done lemma sim_move01_CallParams: "sim_moves01 P ta0 es0 es h xs ta es' h' xs' ==> sim_move01 P ta0 (Val v•M(es0)) (Val v•M(es)) h xs ta (Val v•M(es')) h' xs'" by(fastsimp simp add: sim_move01_def sim_moves01_def intro: Call_τred1'r_param Call1Params) lemma sim_move01_reds: "[| new_Addr h = ⌊a⌋; P \<turnstile> C has_fields FDTs |] ==> sim_move01 P ε (new C) (new C) h xs ε (addr a) (h(a\<mapsto>(Obj C (init_fields FDTs)))) xs" "new_Addr h = None ==> sim_move01 P ε (new C) (new C) h xs ε (THROW OutOfMemory) h xs" "[| new_Addr h = ⌊a⌋; i ≥ 0; h' = h(a \<mapsto> (Arr T (replicate (nat i) (default_val T)))) |] ==> sim_move01 P ε (newA T⌊Val (Intg i)⌉) (newA T⌊Val (Intg i)⌉) h xs ε (addr a) h' xs" "i < 0 ==> sim_move01 P ε (newA T⌊Val (Intg i)⌉) (newA T⌊Val (Intg i)⌉) h xs ε (THROW NegativeArraySize) h xs" "[| new_Addr h = None; i ≥ 0 |] ==> sim_move01 P ε (newA T⌊Val (Intg i)⌉) (newA T⌊Val (Intg i)⌉) h xs ε (THROW OutOfMemory) h xs" "[| typeofh v = ⌊U⌋; P \<turnstile> U ≤ T |] ==> sim_move01 P ε (Cast T (Val v)) (Cast T (Val v)) h xs ε (Val v) h xs" "[| typeofh v = ⌊U⌋; ¬ P \<turnstile> U ≤ T |] ==> sim_move01 P ε (Cast T (Val v)) (Cast T (Val v)) h xs ε (THROW ClassCast) h xs" "binop bop v1 v2 = Some v ==> sim_move01 P ε ((Val v1) «bop» (Val v2)) (Val v1 «bop» Val v2) h xs ε (Val v) h xs" "[| xs!V = v; V < size xs |] ==> sim_move01 P ε (Var V') (Var V) h xs ε (Val v) h xs" "V < length xs ==> sim_move01 P ε (V' := Val v) (V := Val v) h xs ε unit h (xs[V := v])" "sim_move01 P ε (null⌊Val v⌉) (null⌊Val v⌉) h xs ε (THROW NullPointer) h xs" "[| h a = ⌊Arr T el⌋; i < 0 ∨ i ≥ int (length el) |] ==> sim_move01 P ε (addr a⌊Val (Intg i)⌉) ((addr a)⌊Val (Intg i)⌉) h xs ε (THROW ArrayIndexOutOfBounds) h xs" "[| h a = ⌊Arr T el⌋; i ≥ 0; i < int (length el) |] ==> sim_move01 P ε (addr a⌊Val (Intg i)⌉) ((addr a)⌊Val (Intg i)⌉) h xs ε (Val (el ! nat i)) h xs" "sim_move01 P ε (null⌊Val v⌉ := Val v') (null⌊Val v⌉ := Val v') h xs ε (THROW NullPointer) h xs" "[| h a = ⌊Arr T el⌋; i < 0 ∨ i ≥ int (length el) |] ==> sim_move01 P ε (AAss (addr a) (Val (Intg i)) (Val v)) (AAss (addr a) (Val (Intg i)) (Val v)) h xs ε (THROW ArrayIndexOutOfBounds) h xs" "[| h a = ⌊Arr T el⌋; i ≥ 0; i < int (length el); typeofh v = ⌊U⌋; ¬ (P \<turnstile> U ≤ T) |] ==> sim_move01 P ε (AAss (addr a) (Val (Intg i)) (Val v)) (AAss (addr a) (Val (Intg i)) (Val v)) h xs ε (THROW ArrayStore) h xs" "[| h a = ⌊Arr T el⌋; i ≥ 0; i < int (length el); typeofh v = Some U; P \<turnstile> U ≤ T; h' = h(a \<mapsto> (Arr T (el[nat i := v]))) |] ==> sim_move01 P ε (AAss (addr a) (Val (Intg i)) (Val v)) (AAss (addr a) (Val (Intg i)) (Val v)) h xs ε unit h' xs" "h a = ⌊Arr T elem⌋ ==> sim_move01 P ε (addr a•length) (addr a•length) h xs ε (Val (Intg (int (length elem)))) h xs" "sim_move01 P ε (null•length) (null•length) h xs ε (THROW NullPointer) h xs" "[| h a = ⌊Obj C fs⌋; fs (F,D) = Some v |] ==> sim_move01 P ε (addr a•F{D}) (addr a•F{D}) h xs ε (Val v) h xs" "sim_move01 P ε (null•F{D}) (null•F{D}) h xs ε (THROW NullPointer) h xs" "h a = ⌊Obj C fs⌋ ==> sim_move01 P ε (addr a•F{D} := Val v) (addr a•F{D} := Val v) h xs ε unit (h(a \<mapsto> (Obj C (fs((F,D) \<mapsto> v))))) xs" "sim_move01 P ε (null•F{D} := Val v) (null•F{D} := Val v) h xs ε (THROW NullPointer) h xs" "sim_move01 P ε ({V':T=vo; Val u}) ({V:T=None; Val u}) h xs ε (Val u) h xs" "V < length xs ==> sim_move01 P ε (sync(null) e0) (syncV (null) e1) h xs ε (THROW NullPointer) h (xs[V := Null])" "sim_move01 P ε (Val v;;e0) (Val v;; e1) h xs ε e1 h xs" "sim_move01 P ε (if (true) e0 else e0') (if (true) e1 else e1') h xs ε e1 h xs" "sim_move01 P ε (if (false) e0 else e0') (if (false) e1 else e1') h xs ε e1' h xs" "sim_move01 P ε (throw null) (throw null) h xs ε (THROW NullPointer) h xs" "sim_move01 P ε (try (Val v) catch(C V') e0) (try (Val v) catch(C V) e1) h xs ε (Val v) h xs" "[| h a = ⌊Obj D fs⌋; P \<turnstile> D \<preceq>* C; V < length xs |] ==> sim_move01 P ε (try (Throw a) catch(C V') e0) (try (Throw a) catch(C V) e1) h xs ε ({V:Class C=None; e1}) h (xs[V := Addr a])" "sim_move01 P ε (newA T⌊Throw a⌉) (newA T⌊Throw a⌉) h xs ε (Throw a) h xs" "sim_move01 P ε (Cast T (Throw a)) (Cast T (Throw a)) h xs ε (Throw a) h xs" "sim_move01 P ε ((Throw a) «bop» e0) ((Throw a) «bop» e1) h xs ε (Throw a) h xs" "sim_move01 P ε (Val v «bop» (Throw a)) (Val v «bop» (Throw a)) h xs ε (Throw a) h xs" "sim_move01 P ε (V' := Throw a) (V := Throw a) h xs ε (Throw a) h xs" "sim_move01 P ε (Throw a⌊e0⌉) (Throw a⌊e1⌉) h xs ε (Throw a) h xs" "sim_move01 P ε (Val v⌊Throw a⌉) (Val v⌊Throw a⌉) h xs ε (Throw a) h xs" "sim_move01 P ε (Throw a⌊e0⌉ := e0') (Throw a⌊e1⌉ := e1') h xs ε (Throw a) h xs" "sim_move01 P ε (Val v⌊Throw a⌉ := e0) (Val v⌊Throw a⌉ := e1) h xs ε (Throw a) h xs" "sim_move01 P ε (Val v⌊Val v'⌉ := Throw a) (Val v⌊Val v'⌉ := Throw a) h xs ε (Throw a) h xs" "sim_move01 P ε (Throw a•length) (Throw a•length) h xs ε (Throw a) h xs" "sim_move01 P ε (Throw a•F{D}) (Throw a•F{D}) h xs ε (Throw a) h xs" "sim_move01 P ε (Throw a•F{D} := e0) (Throw a•F{D} := e1) h xs ε (Throw a) h xs" "sim_move01 P ε (Val v•F{D} := Throw a) (Val v•F{D} := Throw a) h xs ε (Throw a) h xs" "sim_move01 P ε (Throw a•M(es0)) (Throw a•M(es1)) h xs ε (Throw a) h xs" "sim_move01 P ε (Val v•M(map Val vs @ Throw a # es0)) (Val v•M(map Val vs @ Throw a # es1)) h xs ε (Throw a) h xs" "sim_move01 P ε ({V':T=vo; Throw a}) ({V:T=None; Throw a}) h xs ε (Throw a) h xs" "sim_move01 P ε (sync(Throw a) e0) (syncV(Throw a) e1) h xs ε (Throw a) h xs" "sim_move01 P ε (Throw a;;e0) (Throw a;;e1) h xs ε (Throw a) h xs" "sim_move01 P ε (if (Throw a) e0 else e0') (if (Throw a) e1 else e1') h xs ε (Throw a) h xs" "sim_move01 P ε (throw (Throw a)) (throw (Throw a)) h xs ε (Throw a) h xs" by(fastsimp simp add: sim_move01_def intro: red1_reds1.intros)+ lemma sim_move01_CallNull: "sim_move01 P ε (null•M(map Val vs)) (null•M(map Val vs)) h xs ε (THROW NullPointer) h xs" by(fastsimp simp add: sim_move01_def map_eq_append_conv intro: red1_reds1.intros) lemma sim_move01_SyncLocks: "[| h a = ⌊arrobj⌋; V < length xs; ta0 = ε\<lbrace>l Lock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace>; ta = ε\<lbrace>l Lock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace> |] ==> sim_move01 P ta0 (sync(addr a) e0) (syncV (addr a) e1) h xs ta (insyncV (a) e1) h (xs[V := Addr a])" "[| xs ! V = Addr a'; V < length xs; ta0 = ε\<lbrace>l Unlock->a' \<rbrace>\<lbrace>o Synchronization a'\<rbrace>; ta = ε\<lbrace>l Unlock->a'\<rbrace>\<lbrace>o Synchronization a'\<rbrace> |] ==> sim_move01 P ta0 (insync(a') (Val v)) (insyncV (a) (Val v)) h xs ta (Val v) h xs" "[| xs ! V = Addr a'; V < length xs; ta0 = ε\<lbrace>l Unlock->a' \<rbrace>\<lbrace>o Synchronization a'\<rbrace>; ta = ε\<lbrace>l Unlock->a' \<rbrace>\<lbrace>o Synchronization a'\<rbrace> |] ==> sim_move01 P ta0 (insync(a') (Throw a'')) (insyncV (a) (Throw a'')) h xs ta (Throw a'') h xs" by(fastsimp simp add: sim_move01_def ta_bisim_def expand_finfun_eq expand_fun_eq finfun_upd_apply intro: red1_reds1.intros[simplified] split: split_if_asm)+ lemma sim_move01_TryFail: "[| h a = ⌊Obj D fs⌋; ¬ P \<turnstile> D \<preceq>* C |] ==> sim_move01 P ε (try (Throw a) catch(C V') e0) (try (Throw a) catch(C V) e1) h xs ε (Throw a) h xs" by(auto simp add: sim_move01_def intro!: Red1TryFail) lemma sim_move01_BlockSome: "[| sim_move01 P ta0 e0 e h (xs[V := v]) ta e' h' xs'; V < length xs |] ==> sim_move01 P ta0 ({V':T=⌊v⌋; e0}) ({V:T=⌊v⌋; e}) h xs ta ({V:T=None; e'}) h' xs'" "V < length xs ==> sim_move01 P ε ({V':T=⌊v⌋; Val u}) ({V:T=⌊v⌋; Val u}) h xs ε (Val u) h (xs[V := v])" "V < length xs ==> sim_move01 P ε ({V':T=⌊v⌋; Throw a}) ({V:T=⌊v⌋; Throw a}) h xs ε (Throw a) h (xs[V := v])" apply(fastsimp simp add: sim_move01_def intro: converse_rtranclp_into_rtranclp Block1Some Block1Red) apply(fastsimp simp add: sim_move01_def intro!: τred1't_2step[OF Block1Some] τred1'r_1step[OF Block1Some] Red1Block Block1Throw)+ done lemmas sim_move01_intros = sim_move01_expr sim_move01_reds sim_move01_CallNull sim_move01_TryFail sim_move01_BlockSome sim_move01_CallParams declare sim_move01_intros[intro] lemma sim_move01_preserves_len: "sim_move01 P ta0 e0 e h xs ta e' h' xs' ==> length xs' = length xs" by(fastsimp simp add: sim_move01_def split: split_if_asm dest: τred1'r_preserves_len τred1't_preserves_len red1_preserves_len) lemma sim_move01_preserves_unmod: "[| sim_move01 P ta0 e0 e h xs ta e' h' xs'; unmod e i; i < length xs |] ==> xs' ! i = xs ! i" apply(auto simp add: sim_move01_def split: split_if_asm dest: τred1't_preserves_unmod) apply(frule (2) τred1'r_preserves_unmod) apply(frule (1) τred1'r_unmod_preserved) apply(frule τred1'r_preserves_len) apply(auto dest: red1_preserves_unmod) done lemma assumes wf: "wf_J_prog P" shows red1_simulates_red_aux: "[| extTA2J0 P,P \<turnstile> 〈e1, S〉 -TA-> 〈e1', S'〉; bisim vs e1 e2 XS; fv e1 ⊆ set vs; lcl S ⊆m [vs [\<mapsto>] XS]; length vs + max_vars e1 ≤ length XS; ∀aMvs. call e1 = ⌊aMvs⌋ --> synthesized_call P (hp S) aMvs |] ==> ∃ta e2' XS'. sim_move01 (compP1 P) TA e1 e2 (hp S) XS ta e2' (hp S') XS' ∧ bisim vs e1' e2' XS' ∧ lcl S' ⊆m [vs [\<mapsto>] XS']" (is "[| _; _; _; _; _; ?synth e1 S |] ==> ?concl e1 e2 S XS e1' S' TA vs") and reds1_simulates_reds_aux: "[| extTA2J0 P,P \<turnstile> 〈es1, S〉 [-TA->] 〈es1', S'〉; bisims vs es1 es2 XS; fvs es1 ⊆ set vs; lcl S ⊆m [vs [\<mapsto>] XS]; length vs + max_varss es1 ≤ length XS; ∀aMvs. calls es1 = ⌊aMvs⌋ --> synthesized_call P (hp S) aMvs |] ==> ∃ta es2' xs'. sim_moves01 (compP1 P) TA es1 es2 (hp S) XS ta es2' (hp S') xs' ∧ bisims vs es1' es2' xs' ∧ lcl S' ⊆m [vs [\<mapsto>] xs']" (is "[| _; _; _; _; _; ?synths es1 S |] ==> ?concls es1 es2 S XS es1' S' TA vs") proof(induct arbitrary: vs e2 XS and vs es2 XS rule: red_reds.inducts) case (BinOpRed1 e s ta e' s' bop e2 Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs e e2 XS; fv e ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars e ≤ length XS; ?synth e s |] ==> ?concl e e2 s XS e' s' ta vs` from `extTA2J0 P,P \<turnstile> 〈e,s〉 -ta-> 〈e',s'〉` have "¬ is_val e" by auto with `bisim Vs (e «bop» e2) E2 xs` obtain E where "E2 = E «bop» compE1 Vs e2" and "bisim Vs e E xs" and "¬ contains_insync e2" by auto with IH[of Vs E xs] `fv (e «bop» e2) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `¬ is_val e` `length Vs + max_vars (e «bop» e2) ≤ length xs` `?synth (e «bop» e2) s` `extTA2J0 P,P \<turnstile> 〈e,s〉 -ta-> 〈e',s'〉` show ?case by(cases "is_val e'")(fastsimp elim!: sim_move01_expr)+ next case (BinOpRed2 e s ta e' s' v bop Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs e e2 XS; fv e ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars e ≤ length XS; ?synth e s |] ==> ?concl e e2 s XS e' s' ta vs` from `bisim Vs (Val v «bop» e) E2 xs` obtain E where "E2 = Val v «bop» E" and "bisim Vs e E xs" by auto with IH[of Vs E xs] `fv (Val v «bop» e) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `length Vs + max_vars (Val v «bop» e) ≤ length xs` `?synth (Val v «bop» e) s` `extTA2J0 P,P \<turnstile> 〈e,s〉 -ta-> 〈e',s'〉` show ?case by(fastsimp elim!: sim_move01_expr) next case RedVar thus ?case by(fastsimp simp add: index_less_aux map_le_def fun_upds_apply intro!: exI dest: bspec) next case RedLAss thus ?case by(fastsimp intro: index_less_aux LAss_lem intro!: exI simp del: fun_upd_apply) next case (AAccRed1 a s ta a' s' i Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs a e2 XS; fv a ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars a ≤ length XS; ?synth a s |] ==> ?concl a e2 s XS a' s' ta vs` from `extTA2J0 P,P \<turnstile> 〈a,s〉 -ta-> 〈a',s'〉` have "¬ is_val a" by auto with `bisim Vs (a⌊i⌉) E2 xs` obtain E where "E2 = E⌊compE1 Vs i⌉" and "bisim Vs a E xs" and "¬ contains_insync i" by auto with IH[of Vs E xs] `fv (a⌊i⌉) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `¬ is_val a` `length Vs + max_vars (a⌊i⌉) ≤ length xs` `?synth (a⌊i⌉) s` `extTA2J0 P,P \<turnstile> 〈a,s〉 -ta-> 〈a',s'〉` show ?case by(cases "is_val a'")(fastsimp elim!: sim_move01_expr)+ next case (AAccRed2 i s ta i' s' a Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs i e2 XS; fv i ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars i ≤ length XS; ?synth i s |] ==> ?concl i e2 s XS i' s' ta vs` from `bisim Vs (Val a⌊i⌉) E2 xs` obtain E where "E2 = Val a⌊E⌉" and "bisim Vs i E xs" by auto with IH[of Vs E xs] `fv (Val a⌊i⌉) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `length Vs + max_vars (Val a⌊i⌉) ≤ length xs` `?synth (Val a⌊i⌉) s` `extTA2J0 P,P \<turnstile> 〈i,s〉 -ta-> 〈i',s'〉` show ?case by(fastsimp elim!: sim_move01_expr) next case RedAAcc thus ?case by(force intro!: exI) next case (AAssRed1 a s ta a' s' i e Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs a e2 XS; fv a ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars a ≤ length XS; ?synth a s |] ==> ?concl a e2 s XS a' s' ta vs` from `extTA2J0 P,P \<turnstile> 〈a,s〉 -ta-> 〈a',s'〉` have "¬ is_val a" by auto with `bisim Vs (a⌊i⌉:=e) E2 xs` obtain E where E2: "E2 = E⌊compE1 Vs i⌉:=compE1 Vs e" and "bisim Vs a E xs" and sync: "¬ contains_insync i" "¬ contains_insync e" by auto with IH[of Vs E xs] `fv (a⌊i⌉:=e) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `¬ is_val a` `extTA2J0 P,P \<turnstile> 〈a,s〉 -ta-> 〈a',s'〉` `length Vs + max_vars (a⌊i⌉:=e) ≤ length xs` `?synth (a⌊i⌉:=e) s` obtain ta' e2' xs' where IH': "sim_move01 (compP1 P) ta a E (hp s) xs ta' e2' (hp s') xs'" "bisim Vs a' e2' xs'" "lcl s' ⊆m [Vs [\<mapsto>] xs']" by auto show ?case proof(cases "is_val a'") case True from `fv (a⌊i⌉:=e) ⊆ set Vs` sync have "bisim Vs i (compE1 Vs i) xs'" "bisim Vs e (compE1 Vs e) xs'" by auto with IH' E2 True sync `¬ is_val a` `extTA2J0 P,P \<turnstile> 〈a,s〉 -ta-> 〈a',s'〉` show ?thesis by(cases "is_val i")(fastsimp elim!: sim_move01_expr)+ next case False with IH' E2 sync `¬ is_val a` `extTA2J0 P,P \<turnstile> 〈a,s〉 -ta-> 〈a',s'〉` show ?thesis by(fastsimp elim!: sim_move01_expr) qed next case (AAssRed2 i s ta i' s' a e Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs i e2 XS; fv i ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars i ≤ length XS; ?synth i s |] ==> ?concl i e2 s XS i' s' ta vs` from `extTA2J0 P,P \<turnstile> 〈i,s〉 -ta-> 〈i',s'〉` have "¬ is_val i" by auto with `bisim Vs (Val a⌊i⌉ := e) E2 xs` obtain E where "E2 = Val a⌊E⌉:=compE1 Vs e" and "bisim Vs i E xs" and "¬ contains_insync e" by auto with IH[of Vs E xs] `fv (Val a⌊i⌉:=e) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `¬ is_val i` `extTA2J0 P,P \<turnstile> 〈i,s〉 -ta-> 〈i',s'〉` `length Vs + max_vars (Val a⌊i⌉:=e) ≤ length xs` `?synth (Val a⌊i⌉:=e) s` show ?case by(cases "is_val i'")(fastsimp elim!: sim_move01_expr)+ next case (AAssRed3 e s ta e' s' a i Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs e e2 XS; fv e ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars e ≤ length XS; ?synth e s |] ==> ?concl e e2 s XS e' s' ta vs` from `bisim Vs (Val a⌊Val i⌉ := e) E2 xs` obtain E where "E2 = Val a⌊Val i⌉:=E" and "bisim Vs e E xs" by auto with IH[of Vs E xs] `fv (Val a⌊Val i⌉:=e) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `extTA2J0 P,P \<turnstile> 〈e,s〉 -ta-> 〈e',s'〉` `length Vs + max_vars (Val a⌊Val i⌉:=e) ≤ length xs` `?synth (Val a⌊Val i⌉:=e) s` show ?case by(fastsimp elim!: sim_move01_expr) next case RedAAssStore thus ?case by(auto intro!: exI) next case (FAssRed1 e s ta e' s' F D e2 Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs e e2 XS; fv e ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars e ≤ length XS; ?synth e s |] ==> ?concl e e2 s XS e' s' ta vs` from `extTA2J0 P,P \<turnstile> 〈e,s〉 -ta-> 〈e',s'〉` have "¬ is_val e" by auto with `bisim Vs (e•F{D} := e2) E2 xs` obtain E where "E2 = E•F{D} := compE1 Vs e2" and "bisim Vs e E xs" and "¬ contains_insync e2" by auto with IH[of Vs E xs] `fv (e•F{D} := e2) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `¬ is_val e` `extTA2J0 P,P \<turnstile> 〈e,s〉 -ta-> 〈e',s'〉` `length Vs + max_vars (e•F{D} := e2) ≤ length xs` `?synth (e•F{D} := e2) s` show ?case by(cases "is_val e'")(fastsimp elim!: sim_move01_expr)+ next case (FAssRed2 e s ta e' s' v F D Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs e e2 XS; fv e ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars e ≤ length XS; ?synth e s |] ==> ?concl e e2 s XS e' s' ta vs` from `bisim Vs (Val v•F{D} := e) E2 xs` obtain E where "E2 = Val v•F{D} := E" and "bisim Vs e E xs" by auto with IH[of Vs E xs] `fv (Val v•F{D} := e) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `extTA2J0 P,P \<turnstile> 〈e,s〉 -ta-> 〈e',s'〉` `length Vs + max_vars (Val v•F{D} := e) ≤ length xs` `?synth (Val v•F{D} := e) s` show ?case by(fastsimp elim!: sim_move01_expr) next case (CallObj e s ta e' s' M es Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs e e2 XS; fv e ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars e ≤ length XS; ?synth e s |] ==> ?concl e e2 s XS e' s' ta vs` from `extTA2J0 P,P \<turnstile> 〈e,s〉 -ta-> 〈e',s'〉` have "¬ is_val e" by auto with `bisim Vs (e•M(es)) E2 xs` obtain E where "E2 = E•M(compEs1 Vs es)" and "bisim Vs e E xs" and "¬ contains_insyncs es" by(auto) with IH[of Vs E xs] `fv (e•M(es)) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `length Vs + max_vars (e•M(es)) ≤ length xs` `?synth (e•M(es)) s` show ?case by(cases "is_val e'")(fastsimp elim!: sim_move01_expr split: split_if_asm)+ next case (CallParams es s ta es' s' v M Vs E2 xs) note IH = `!!vs es2 XS. [|bisims vs es es2 XS; fvs es ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_varss es ≤ length XS; ?synths es s |] ==> ?concls es es2 s XS es' s' ta vs` from `bisim Vs (Val v•M(es)) E2 xs` obtain Es where "E2 = Val v•M(Es)" and "bisims Vs es Es xs" by auto moreover from `extTA2J0 P,P \<turnstile> 〈es,s〉 [-ta->] 〈es',s'〉` have "¬ is_vals es" by auto with `?synth (Val v•M(es)) s` have "?synths es s" by(auto) moreover note IH[of Vs Es xs] `fv (Val v•M(es)) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `length Vs + max_vars (Val v•M(es)) ≤ length xs` ultimately show ?case by(fastsimp elim!: sim_move01_CallParams) next case (RedCall s a C fs M Ts T pns body D vs Vs E2 xs) from `hp s a = ⌊Obj C fs⌋` have "call (addr a•M(map Val vs)) = ⌊(a, M, vs)⌋" by auto with `?synth (addr a•M(map Val vs)) s` have "synthesized_call P (hp s) (a, M, vs)" by auto with `¬ is_external_call P (Class C) M` `hp s a = ⌊Obj C fs⌋` have False by(simp add: synthesized_call_conv) thus ?case .. next case (RedCallExternal s a T M vs ta va h' ta' e' s' Vs E2 xs) from `bisim Vs (addr a•M(map Val vs)) E2 xs` have "E2 = addr a•M(map Val vs)" by auto moreover note `is_external_call P T M` `typeofhp s (Addr a) = ⌊T⌋` `ta' = extTA2J0 P ta` `e' = extRet2J va` `s' = (h', lcl s)` `P \<turnstile> 〈a•M(vs),hp s〉 -ta->ext 〈va,h'〉` `lcl s ⊆m [Vs [\<mapsto>] xs]` moreover from `typeofhp s (Addr a) = ⌊T⌋` have "hp s a ≠ None" by auto with wf `P \<turnstile> 〈a•M(vs),hp s〉 -ta->ext 〈va,h'〉` have "ta_bisim01 (extTA2J0 P ta) (extTA2J1 (compP1 P) ta)" by(rule red_external_ta_bisim01) ultimately show ?case apply(cases va) apply(auto simp del: split_paired_Ex simp add: sim_move01_def map_eq_append_conv) apply(rule exI conjI)+ apply(clarsimp, fastsimp intro: Red1CallExternal simp add: map_eq_append_conv simp del: split_paired_Ex) apply(rule exI conjI)+ apply(clarsimp, fastsimp intro: Red1CallExternal simp add: map_eq_append_conv simp del: split_paired_Ex) done next case (BlockRed e h x V vo ta e' h' x' T Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs e e2 XS; fv e ⊆ set vs; lcl (h, x(V := vo)) ⊆m [vs [\<mapsto>] XS]; length vs + max_vars e ≤ length XS; ?synth e (h, (x(V := vo)))|] ==> ?concl e e2 (h, x(V := vo)) XS e' (h', x') ta vs` note red = `extTA2J0 P,P \<turnstile> 〈e,(h, x(V := vo))〉 -ta-> 〈e',(h', x')〉` note len = `length Vs + max_vars {V:T=vo; e} ≤ length xs` from `fv {V:T=vo; e} ⊆ set Vs` have fv: "fv e ⊆ set (Vs@[V])" by auto from `bisim Vs {V:T=vo; e} E2 xs` show ?case proof(cases rule: bisim_cases(6)[consumes 1, case_names BlockNone BlockSome BlockSomeNone]) case (BlockNone E') with red IH[of "Vs@[V]" E' xs] fv `lcl (h, x) ⊆m [Vs [\<mapsto>] xs]` `length Vs + max_vars {V:T=vo; e} ≤ length xs` `?synth {V:T=vo; e} (h, x)` obtain TA' e2' xs' where red': "sim_move01 (compP1 P) ta e E' h xs TA' e2' h' xs'" and bisim': "bisim (Vs @ [V]) e' e2' xs'" "x' ⊆m [Vs @ [V] [\<mapsto>] xs']" by auto from red' `length Vs + max_vars {V:T=vo; e} ≤ length xs` have "length (Vs@[V]) + max_vars e ≤ length xs'" by(fastsimp simp add: sim_move01_def dest: red1_preserves_len τred1't_preserves_len τred1'r_preserves_len split: split_if_asm) with `x' ⊆m [Vs @ [V] [\<mapsto>] xs']` have "x' ⊆m [Vs [\<mapsto>] xs', V \<mapsto> xs' ! length Vs]" by(simp) moreover { assume "V ∈ set Vs" hence "hidden (Vs @ [V]) (index Vs V)" by(rule hidden_index) with `bisim (Vs @ [V]) e E' xs` have "unmod E' (index Vs V)" by -(rule hidden_bisim_unmod) moreover from `length Vs + max_vars {V:T=vo; e} ≤ length xs` `V ∈ set Vs` have "index Vs V < length xs" by(auto intro: index_less_aux) ultimately have "xs ! index Vs V = xs' ! index Vs V" using sim_move01_preserves_unmod[OF red'] by(simp) } moreover from red' have "length xs = length xs'" by(rule sim_move01_preserves_len[symmetric]) ultimately have rel: "x'(V := x V) ⊆m [Vs [\<mapsto>] xs']" using `lcl (h, x) ⊆m [Vs [\<mapsto>] xs]` `length Vs + max_vars {V:T=vo; e} ≤ length xs` by(auto intro: Block_lem) show ?thesis proof(cases "x' V") case None with red' bisim' BlockNone len show ?thesis by(fastsimp simp del: split_paired_Ex fun_upd_apply intro: rel) next case (Some v) moreover with `x' ⊆m [Vs @ [V] [\<mapsto>] xs']` have "[Vs @ [V] [\<mapsto>] xs'] V = ⌊v⌋" by(auto simp add: map_le_def dest: bspec) moreover from `length Vs + max_vars {V:T=vo; e} ≤ length xs` have "length Vs < length xs" by auto ultimately have "xs' ! length Vs = v" using `length xs = length xs'` by(simp) with red' bisim' BlockNone Some len show ?thesis by(fastsimp simp del: fun_upd_apply intro: rel) qed next case (BlockSome E' v) with red IH[of "Vs@[V]" E' "xs[length Vs := v]"] fv `lcl (h, x) ⊆m [Vs [\<mapsto>] xs]` `length Vs + max_vars {V:T=vo; e} ≤ length xs` `?synth {V:T=vo; e} (h, x)` obtain TA' e2' xs' where red': "sim_move01 (compP1 P) ta e E' h (xs[length Vs := v]) TA' e2' h' xs'" and bisim': "bisim (Vs @ [V]) e' e2' xs'" "x' ⊆m [Vs @ [V] [\<mapsto>] xs']" by auto from red' `length Vs + max_vars {V:T=vo; e} ≤ length xs` have "length (Vs@[V]) + max_vars e ≤ length xs'" by(auto dest: sim_move01_preserves_len) with `x' ⊆m [Vs @ [V] [\<mapsto>] xs']` have "x' ⊆m [Vs [\<mapsto>] xs', V \<mapsto> xs' ! length Vs]" by(simp) moreover { assume "V ∈ set Vs" hence "hidden (Vs @ [V]) (index Vs V)" by(rule hidden_index) with `bisim (Vs @ [V]) e E' (xs[length Vs := v])` have "unmod E' (index Vs V)" by -(rule hidden_bisim_unmod) moreover from `length Vs + max_vars {V:T=vo; e} ≤ length xs` `V ∈ set Vs` have "index Vs V < length xs" by(auto intro: index_less_aux) moreover from `length Vs + max_vars {V:T=vo; e} ≤ length xs` `V ∈ set Vs` have "(xs[length Vs := v]) ! index Vs V = xs ! index Vs V" by(simp) ultimately have "xs ! index Vs V = xs' ! index Vs V" using sim_move01_preserves_unmod[OF red', of "index Vs V"] by(simp) } moreover from red' have "length xs = length xs'" by(auto dest: sim_move01_preserves_len) ultimately have rel: "x'(V := x V) ⊆m [Vs [\<mapsto>] xs']" using `lcl (h, x) ⊆m [Vs [\<mapsto>] xs]` `length Vs + max_vars {V:T=vo; e} ≤ length xs` by(auto intro: Block_lem) from BlockSome red obtain v' where Some: "x' V = ⌊v'⌋" by(auto dest!: red_lcl_incr) with `x' ⊆m [Vs @ [V] [\<mapsto>] xs']` have "[Vs @ [V] [\<mapsto>] xs'] V = ⌊v'⌋" by(auto simp add: map_le_def dest: bspec) moreover from `length Vs + max_vars {V:T=vo; e} ≤ length xs` have "length Vs < length xs" by auto ultimately have "xs' ! length Vs = v'" using `length xs = length xs'` by(simp) with red' bisim' BlockSome Some `length Vs < length xs` show ?thesis by(fastsimp simp del: fun_upd_apply intro: rel) next case (BlockSomeNone E') with red IH[of "Vs@[V]" E' xs] fv `lcl (h, x) ⊆m [Vs [\<mapsto>] xs]` `length Vs + max_vars {V:T=vo; e} ≤ length xs` `?synth {V:T=vo; e} (h, x)` obtain TA' e2' xs' where red': "sim_move01 (compP1 P) ta e E' h xs TA' e2' h' xs'" and IH': "bisim (Vs @ [V]) e' e2' xs'" "x' ⊆m [Vs @ [V] [\<mapsto>] xs']" by auto from red' `length Vs + max_vars {V:T=vo; e} ≤ length xs` have "length (Vs@[V]) + max_vars e ≤ length xs'" by(auto dest: sim_move01_preserves_len) with `x' ⊆m [Vs @ [V] [\<mapsto>] xs']` have "x' ⊆m [Vs [\<mapsto>] xs', V \<mapsto> xs' ! length Vs]" by(simp) moreover { assume "V ∈ set Vs" hence "hidden (Vs @ [V]) (index Vs V)" by(rule hidden_index) with `bisim (Vs @ [V]) e E' xs` have "unmod E' (index Vs V)" by -(rule hidden_bisim_unmod) moreover from `length Vs + max_vars {V:T=vo; e} ≤ length xs` `V ∈ set Vs` have "index Vs V < length xs" by(auto intro: index_less_aux) moreover from `length Vs + max_vars {V:T=vo; e} ≤ length xs` `V ∈ set Vs` have "(xs[length Vs := v]) ! index Vs V = xs ! index Vs V" by(simp) ultimately have "xs ! index Vs V = xs' ! index Vs V" using sim_move01_preserves_unmod[OF red', of "index Vs V"] by(simp) } moreover from red' have "length xs = length xs'" by(auto dest: sim_move01_preserves_len) ultimately have rel: "x'(V := x V) ⊆m [Vs [\<mapsto>] xs']" using `lcl (h, x) ⊆m [Vs [\<mapsto>] xs]` `length Vs + max_vars {V:T=vo; e} ≤ length xs` by(auto intro: Block_lem) from BlockSomeNone red obtain v' where Some: "x' V = ⌊v'⌋" by(auto dest!: red_lcl_incr) with `x' ⊆m [Vs @ [V] [\<mapsto>] xs']` have "[Vs @ [V] [\<mapsto>] xs'] V = ⌊v'⌋" by(auto simp add: map_le_def dest: bspec) moreover from `length Vs + max_vars {V:T=vo; e} ≤ length xs` have "length Vs < length xs" by auto ultimately have "xs' ! length Vs = v'" using `length xs = length xs'` by(simp) with red' IH' BlockSomeNone Some `length Vs < length xs` show ?thesis by(fastsimp simp del: fun_upd_apply intro: rel) qed next case (RedBlock V T vo u s Vs E2 xs) from `bisim Vs {V:T=vo; Val u} E2 xs` obtain vo' where [simp]: "E2 = {length Vs:T=vo'; Val u}" by auto from RedBlock show ?case proof(cases vo) case (Some v) with `bisim Vs {V:T=vo; Val u} E2 xs` have vo': "case vo' of None => xs ! length Vs = v | Some v' => v = v'" by auto have "sim_move01 (compP1 P) ε {V:T=vo; Val u} E2 (hp s) xs ε (Val u) (hp s) (xs[length Vs := v])" proof(cases vo') case None with vo' have "xs[length Vs := v] = xs" by auto thus ?thesis using Some None by auto next case Some from `length Vs + max_vars {V:T=vo; Val u} ≤ length xs` have "length Vs < length xs" by simp with vo' Some show ?thesis using `vo = Some v` by auto qed thus ?thesis using RedBlock by fastsimp qed fastsimp next case SynchronizedNull thus ?case by fastsimp next case (LockSynchronized s a arrobj e Vs E2 xs) from `bisim Vs (sync(addr a) e) E2 xs` have E2: "E2 = synclength Vs (addr a) (compE1 (Vs@[fresh_var Vs]) e)" and sync: "¬ contains_insync e" by auto moreover have "fresh_var Vs ∉ set Vs" by(rule fresh_var_fresh) with `fv (sync(addr a) e) ⊆ set Vs` have "fresh_var Vs ∉ fv e" by auto from E2 `fv (sync(addr a) e) ⊆ set Vs` sync have "bisim (Vs@[fresh_var Vs]) e (compE1 (Vs@[fresh_var Vs]) e) (xs[length Vs := Addr a])" by(auto intro!: compE1_bisim) hence "bisim Vs (insync(a) e) (insynclength Vs (a) (compE1 (Vs@[fresh_var Vs]) e)) (xs[length Vs := Addr a])" using `fresh_var Vs ∉ fv e` `length Vs + max_vars (sync(addr a) e) ≤ length xs` by auto moreover from `hp s a = ⌊arrobj⌋` `length Vs + max_vars (sync(addr a) e) ≤ length xs` have "compP1 P \<turnstile>1 〈synclength Vs (addr a) (compE1 (Vs@[fresh_var Vs]) e), (hp s, xs)〉 -ε\<lbrace>l Lock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace>-> 〈insynclength Vs (a) (compE1 (Vs@[fresh_var Vs]) e), (hp s, xs[length Vs := Addr a])〉" by -(rule Lock1Synchronized, auto) hence "sim_move01 (compP1 P) ε\<lbrace>lLock->a\<rbrace>\<lbrace>o Synchronization a\<rbrace> (sync(addr a) e) E2 (hp s) xs ε\<lbrace>lLock->a\<rbrace>\<lbrace>o Synchronization a\<rbrace> (insynclength Vs (a) (compE1 (Vs@[fresh_var Vs]) e)) (hp s) (xs[length Vs := Addr a])" using E2 by(fastsimp simp add: sim_move01_def ta_bisim_def) moreover have "zip Vs (xs[length Vs := Addr a]) = (zip Vs xs)[length Vs := (arbitrary, Addr a)]" by(rule sym)(simp add: update_zip) hence "zip Vs (xs[length Vs := Addr a]) = zip Vs xs" by simp with `lcl s ⊆m [Vs [\<mapsto>] xs]` have "lcl s ⊆m [Vs [\<mapsto>] xs[length Vs := Addr a]]" by(auto simp add: map_le_def map_upds_def) ultimately show ?case using `lcl s ⊆m [Vs [\<mapsto>] xs]` by fastsimp next case (SynchronizedRed2 e s ta e' s' a Vs E2 xs) note IH = `!!vs e2 XS. [|bisim vs e e2 XS; fv e ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars e ≤ length XS; ?synth e s |] ==> ?concl e e2 s XS e' s' ta vs` from `bisim Vs (insync(a) e) E2 xs` obtain E where E2: "E2 = insynclength Vs (a) E" and bisim: "bisim (Vs@[fresh_var Vs]) e E xs" and xsa: "xs ! length Vs = Addr a" by auto from `fv (insync(a) e) ⊆ set Vs` fresh_var_fresh[of Vs] have fv: "fresh_var Vs ∉ fv e" by auto from `length Vs + max_vars (insync(a) e) ≤ length xs` have "length Vs < length xs" by simp { assume "lcl s (fresh_var Vs) ≠ None" then obtain v where "lcl s (fresh_var Vs) = ⌊v⌋" by auto with `lcl s ⊆m [Vs [\<mapsto>] xs]` have "[Vs [\<mapsto>] xs] (fresh_var Vs) = ⌊v⌋" by(auto simp add: map_le_def dest: bspec) hence "fresh_var Vs ∈ set Vs" by(auto simp add: map_upds_def set_zip dest!: map_of_SomeD ) moreover have "fresh_var Vs ∉ set Vs" by(rule fresh_var_fresh) ultimately have False by contradiction } hence "lcl s (fresh_var Vs) = None" by(cases "lcl s (fresh_var Vs)", auto) hence "(lcl s)(fresh_var Vs := None) = lcl s" by(auto intro: ext) moreover from `lcl s ⊆m [Vs [\<mapsto>] xs]` have "(lcl s)(fresh_var Vs := None) ⊆m [Vs [\<mapsto>] xs, fresh_var Vs \<mapsto> xs ! length Vs]" by(simp) ultimately have "lcl s ⊆m [Vs @ [fresh_var Vs] [\<mapsto>] xs]" using `length Vs < length xs` by(auto) with IH[of "Vs@[fresh_var Vs]" E xs] `fv (insync(a) e) ⊆ set Vs` bisim `length Vs + max_vars (insync(a) e) ≤ length xs` `?synth (insync(a) e) s` obtain TA' e2' xs' where IH': "sim_move01 (compP1 P) ta e E (hp s) xs TA' e2' (hp s') xs'" "bisim (Vs @ [fresh_var Vs]) e' e2' xs'" "lcl s' ⊆m [Vs @ [fresh_var Vs] [\<mapsto>] xs']" by auto from `extTA2J0 P,P \<turnstile> 〈e,s〉 -ta-> 〈e',s'〉` have "dom (lcl s') ⊆ dom (lcl s) ∪ fv e" by(auto dest: red_dom_lcl) with fv `lcl s (fresh_var Vs) = None` have "(fresh_var Vs) ∉ dom (lcl s')" by auto hence "lcl s' (fresh_var Vs) = None" by auto moreover from IH' have "length xs = length xs'" by(auto dest: sim_move01_preserves_len) moreover note `lcl s' ⊆m [Vs @ [fresh_var Vs] [\<mapsto>] xs']` `length Vs < length xs` ultimately have "lcl s' ⊆m [Vs [\<mapsto>] xs']" by(auto simp add: map_le_def dest: bspec) moreover from bisim fv have "unmod E (length Vs)" by(auto intro: bisim_fv_unmod) with IH' `length Vs < length xs` have "xs ! length Vs = xs' ! length Vs" by(auto dest!: sim_move01_preserves_unmod) with xsa have "xs' ! length Vs = Addr a" by simp ultimately show ?case using IH' E2 by(fastsimp) next case (UnlockSynchronized a v s Vs E2 xs) from `bisim Vs (insync(a) Val v) E2 xs` have E2: "E2 = insynclength Vs (a) Val v" and xsa: "xs ! length Vs = Addr a" by auto moreover from `length Vs + max_vars (insync(a) Val v) ≤ length xs` xsa have "compP1 P \<turnstile>1 〈insynclength Vs (a) (Val v), (hp s, xs)〉 -ε\<lbrace>l Unlock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace>-> 〈Val v, (hp s, xs)〉" by-(rule Unlock1Synchronized, auto) hence "sim_move01 (compP1 P) ε\<lbrace>lUnlock->a\<rbrace>\<lbrace>o Synchronization a\<rbrace> (insync(a) Val v) (insynclength Vs (a) Val v) (hp s) xs ε\<lbrace>l Unlock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace> (Val v) (hp s) xs" by(fastsimp simp add: sim_move01_def ta_bisim_def) ultimately show ?case using `lcl s ⊆m [Vs [\<mapsto>] xs]` by fastsimp next case (RedWhile b c s Vs E2 xs) from `bisim Vs (while (b) c) E2 xs` have "E2 = while (compE1 Vs b) (compE1 Vs c)" and sync: "¬ contains_insync b" "¬ contains_insync c" by auto moreover have "compP1 P \<turnstile>1 〈while(compE1 Vs b) (compE1 Vs c), (hp s, xs)〉 -ε-> 〈if (compE1 Vs b) (compE1 Vs c;;while(compE1 Vs b) (compE1 Vs c)) else unit, (hp s, xs)〉" by(rule Red1While) hence "sim_move01 (compP1 P) ε (while (b) c) (while (compE1 Vs b) (compE1 Vs c)) (hp s) xs ε (if (compE1 Vs b) (compE1 Vs c;;while(compE1 Vs b) (compE1 Vs c)) else unit) (hp s) xs" by(auto simp add: sim_move01_def) moreover from `fv (while (b) c) ⊆ set Vs` sync have "bisim Vs (if (b) (c;; while (b) c) else unit) (if (compE1 Vs b) (compE1 Vs (c;; while(b) c)) else (compE1 Vs unit)) xs" by -(rule bisimCond, auto) ultimately show ?case using `lcl s ⊆m [Vs [\<mapsto>] xs]` by(simp)((rule exI)+, erule conjI, auto) next case (RedTryCatch s a D fs C V e2 Vs E2 xs) thus ?case by(auto intro!: exI)(auto intro!: compE1_bisim) next case RedTryFail thus ?case by(auto intro!: exI) next case (ListRed1 e s ta e' s' es Vs ES2 xs) note IH = `!!vs e2 XS. [|bisim vs e e2 XS; fv e ⊆ set vs; lcl s ⊆m [vs [\<mapsto>] XS]; length vs + max_vars e ≤ length XS; ?synth e s|] ==> ?concl e e2 s XS e' s' ta vs` from `extTA2J0 P,P \<turnstile> 〈e,s〉 -ta-> 〈e',s'〉` have "¬ is_val e" by auto with `bisims Vs (e # es) ES2 xs` obtain E' where "bisim Vs e E' xs" and ES2: "ES2 = E' # compEs1 Vs es" and sync: "¬ contains_insyncs es" by(auto) with IH[of Vs E' xs] `fvs (e # es) ⊆ set Vs` `lcl s ⊆m [Vs [\<mapsto>] xs]` `extTA2J0 P,P \<turnstile> 〈e,s〉 -ta-> 〈e',s'〉` `length Vs + max_varss (e # es) ≤ length xs` `?synths (e # es) s` `¬ is_val e` show ?case by(cases "is_val e'")(fastsimp elim!: sim_moves01_expr split: split_if_asm)+ next case (ListRed2 es s ta es' s' v Vs ES2 xs) thus ?case by(fastsimp elim!: bisims_cases elim!: sim_moves01_expr) next case CallThrowParams thus ?case by(fastsimp elim!:bisim_cases simp add: bisims_map_Val_Throw) next case (BlockThrow V T vo a s Vs e2 xs) thus ?case by(cases vo)(fastsimp elim!: bisim_cases)+ next case (SynchronizedThrow2 a ad s Vs E2 xs) from `bisim Vs (insync(a) Throw ad) E2 xs` have "xs ! length Vs = Addr a" by auto with `length Vs + max_vars (insync(a) Throw ad) ≤ length xs` have "compP1 P \<turnstile>1 〈insynclength Vs (a) Throw ad, (hp s, xs)〉 -ε\<lbrace>l Unlock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace>-> 〈Throw ad, (hp s, xs)〉" by-(rule Synchronized1Throw2, auto) hence "sim_move01 (compP1 P) ε\<lbrace>lUnlock->a\<rbrace>\<lbrace>o Synchronization a\<rbrace> (insync(a) Throw ad) (insynclength Vs (a) Throw ad) (hp s) xs ε\<lbrace>lUnlock->a\<rbrace>\<lbrace>o Synchronization a\<rbrace> (Throw ad) (hp s) xs" by(fastsimp simp add: sim_move01_def ta_bisim_def expand_fun_eq expand_finfun_eq finfun_upd_apply split: split_if_asm) moreover note `lcl s ⊆m [Vs [\<mapsto>] xs]` `bisim Vs (insync(a) Throw ad) E2 xs` ultimately show ?case by(fastsimp) qed(fastsimp simp del: fun_upd_apply split: split_if_asm)+ declare max_dest [iff del] lemma map_upds_Some_eq_nth_index: assumes "[Vs [\<mapsto>] vs] V = ⌊v⌋" "length Vs ≤ length vs" shows "vs ! index Vs V = v" proof - from `[Vs [\<mapsto>] vs] V = ⌊v⌋` have "V ∈ set Vs" by -(rule classical, auto) with `[Vs [\<mapsto>] vs] V = ⌊v⌋` `length Vs ≤ length vs` show ?thesis proof(induct Vs arbitrary: vs) case Nil thus ?case by simp next case (Cons x xs ys) note IH = `!!vs. [| [xs [\<mapsto>] vs] V = ⌊v⌋; length xs ≤ length vs; V ∈ set xs |] ==> vs ! index xs V = v` from `[x # xs [\<mapsto>] ys] V = ⌊v⌋` obtain y Ys where "ys = y # Ys" by(cases ys, auto) with `length (x # xs) ≤ length ys` have "length xs ≤ length Ys" by simp show ?case proof(cases "V ∈ set xs") case True with `[x # xs [\<mapsto>] ys] V = ⌊v⌋` `length xs ≤ length Ys` `ys = y # Ys` have "[xs [\<mapsto>] Ys] V = ⌊v⌋" apply(auto simp add: map_upds_def map_of_eq_None_iff set_zip image_Collect split: split_if_asm) apply(clarsimp simp add: in_set_conv_decomp) apply(erule_tac x="length ys" in allE) by(simp) with IH[OF this `length xs ≤ length Ys` True] `ys = y # Ys` True show ?thesis by(simp) next case False with `V ∈ set (x # xs)` have "x = V" by auto with False `[x # xs [\<mapsto>] ys] V = ⌊v⌋` `ys = y # Ys` have "y = v" by(auto) with False `x = V` `ys = y # Ys` show ?thesis by(simp) qed qed qed declare split_paired_Ex [simp del] lemmas τred0r_expr = NewArray_τred0r_xt Cast_τred0r_xt BinOp_τred0r_xt1 BinOp_τred0r_xt2 LAss_τred0r AAcc_τred0r_xt1 AAcc_τred0r_xt2 AAss_τred0r_xt1 AAss_τred0r_xt2 AAss_τred0r_xt3 ALength_τred0r_xt FAcc_τred0r_xt FAss_τred0r_xt1 FAss_τred0r_xt2 Call_τred0r_obj Call_τred0r_param Block_τred0r_xt Sync_τred0r_xt InSync_τred0r_xt Seq_τred0r_xt Cond_τred0r_xt Throw_τred0r_xt Try_τred0r_xt lemmas τred0t_expr = NewArray_τred0t_xt Cast_τred0t_xt BinOp_τred0t_xt1 BinOp_τred0t_xt2 LAss_τred0t AAcc_τred0t_xt1 AAcc_τred0t_xt2 AAss_τred0t_xt1 AAss_τred0t_xt2 AAss_τred0t_xt3 ALength_τred0t_xt FAcc_τred0t_xt FAss_τred0t_xt1 FAss_τred0t_xt2 Call_τred0t_obj Call_τred0t_param Block_τred0t_xt Sync_τred0t_xt InSync_τred0t_xt Seq_τred0t_xt Cond_τred0t_xt Throw_τred0t_xt Try_τred0t_xt declare τred0r_expr [elim!] declare τred0t_expr [elim!] primrec countInitBlock :: "('a, 'b) exp => nat" and countInitBlocks :: "('a, 'b) exp list => nat" where "countInitBlock (new C) = 0" | "countInitBlock (newA T⌊e⌉) = countInitBlock e" | "countInitBlock (Cast T e) = countInitBlock e" | "countInitBlock (Val v) = 0" | "countInitBlock (Var V) = 0" | "countInitBlock (V := e) = countInitBlock e" | "countInitBlock (e «bop» e') = countInitBlock e + countInitBlock e'" | "countInitBlock (a⌊i⌉) = countInitBlock a + countInitBlock i" | "countInitBlock (AAss a i e) = countInitBlock a + countInitBlock i + countInitBlock e" | "countInitBlock (a•length) = countInitBlock a" | "countInitBlock (e•F{D}) = countInitBlock e" | "countInitBlock (FAss e F D e') = countInitBlock e + countInitBlock e'" | "countInitBlock (e•M(es)) = countInitBlock e + countInitBlocks es" | "countInitBlock ({V:T=vo; e}) = (case vo of None => 0 | Some v => 1) + countInitBlock e" | "countInitBlock (syncV' (e) e') = countInitBlock e + countInitBlock e'" | "countInitBlock (insyncV' (ad) e) = countInitBlock e" | "countInitBlock (e;;e') = countInitBlock e + countInitBlock e'" | "countInitBlock (if (e) e1 else e2) = countInitBlock e + countInitBlock e1 + countInitBlock e2" | "countInitBlock (while(b) e) = countInitBlock b + countInitBlock e" | "countInitBlock (throw e) = countInitBlock e" | "countInitBlock (try e catch(C V) e') = countInitBlock e + countInitBlock e'" | "countInitBlocks [] = 0" | "countInitBlocks (e # es) = countInitBlock e + countInitBlocks es" definition sim_move10 :: "J_prog => external_thread_action => expr1 => expr1 => expr => heap => locals => J0_thread_action => expr => heap => locals => bool" where "sim_move10 P ta1 e1 e1' e h xs ta e' h' xs' <-> ¬ final e1 ∧ (if τmove1 P h e1 then (τred0t (extTA2J0 P) P h (e, xs) (e', xs') ∨ countInitBlock e1' < countInitBlock e1 ∧ e' = e ∧ xs' = xs) ∧ h' = h ∧ ta1 = ε ∧ ta = ε else ∃e'' xs''. τred0r (extTA2J0 P) P h (e, xs) (e'', xs'') ∧ extTA2J0 P,P \<turnstile> 〈e'', (h, xs'')〉 -ta-> 〈e', (h', xs')〉 ∧ no_call P h e'' ∧ ¬ τmove0 P h e'' ∧ ta_bisim01 ta (extTA2J1 (compP1 P) ta1))" definition sim_moves10 :: "J_prog => external_thread_action => expr1 list => expr1 list => expr list => heap => locals => J0_thread_action => expr list => heap => locals => bool" where "sim_moves10 P ta1 es1 es1' es h xs ta es' h' xs' <-> ¬ finals es1 ∧ (if τmoves1 P h es1 then (τreds0t (extTA2J0 P) P h (es, xs) (es', xs') ∨ countInitBlocks es1' < countInitBlocks es1 ∧ es' = es ∧ xs' = xs) ∧ h' = h ∧ ta1 = ε ∧ ta = ε else ∃es'' xs''. τreds0r (extTA2J0 P) P h (es, xs) (es'', xs'') ∧ extTA2J0 P,P \<turnstile> 〈es'', (h, xs'')〉 [-ta->] 〈es', (h', xs')〉 ∧ no_calls P h es'' ∧ ¬ τmoves0 P h es'' ∧ ta_bisim01 ta (extTA2J1 (compP1 P) ta1))" lemma sim_move10_expr: assumes "sim_move10 P ta1 e1 e1' e h xs ta e' h' xs'" shows "sim_move10 P ta1 (newA T⌊e1⌉) (newA T⌊e1'⌉) (newA T⌊e⌉) h xs ta (newA T⌊e'⌉) h' xs'" "sim_move10 P ta1 (Cast T e1) (Cast T e1') (Cast T e) h xs ta (Cast T e') h' xs'" "sim_move10 P ta1 (e1 «bop» e2) (e1' «bop» e2) (e «bop» e2') h xs ta (e' «bop» e2') h' xs'" "sim_move10 P ta1 (Val v «bop» e1) (Val v «bop» e1') (Val v «bop» e) h xs ta (Val v «bop» e') h' xs'" "sim_move10 P ta1 (V := e1) (V := e1') (V' := e) h xs ta (V' := e') h' xs'" "sim_move10 P ta1 (e1⌊e2⌉) (e1'⌊e2⌉) (e⌊e2'⌉) h xs ta (e'⌊e2'⌉) h' xs'" "sim_move10 P ta1 (Val v⌊e1⌉) (Val v⌊e1'⌉) (Val v⌊e⌉) h xs ta (Val v⌊e'⌉) h' xs'" "sim_move10 P ta1 (e1⌊e2⌉ := e3) (e1'⌊e2⌉ := e3) (e⌊e2'⌉ := e3') h xs ta (e'⌊e2'⌉ := e3') h' xs'" "sim_move10 P ta1 (Val v⌊e1⌉ := e3) (Val v⌊e1'⌉ := e3) (Val v⌊e⌉ := e3') h xs ta (Val v⌊e'⌉ := e3') h' xs'" "sim_move10 P ta1 (AAss (Val v) (Val v') e1) (AAss (Val v) (Val v') e1') (AAss (Val v) (Val v') e) h xs ta (AAss (Val v) (Val v') e') h' xs'" "sim_move10 P ta1 (e1•length) (e1'•length) (e•length) h xs ta (e'•length) h' xs'" "sim_move10 P ta1 (e1•F{D}) (e1'•F{D}) (e•F'{D'}) h xs ta (e'•F'{D'}) h' xs'" "sim_move10 P ta1 (FAss e1 F D e2) (FAss e1' F D e2) (FAss e F' D' e2') h xs ta (FAss e' F' D' e2') h' xs'" "sim_move10 P ta1 (FAss (Val v) F D e1) (FAss (Val v) F D e1') (FAss (Val v) F' D' e) h xs ta (FAss (Val v) F' D' e') h' xs'" "sim_move10 P ta1 (e1•M(es)) (e1'•M(es)) (e•M(es')) h xs ta (e'•M(es')) h' xs'" "sim_move10 P ta1 (syncV(e1) e2) (syncV(e1') e2) (sync(e) e2') h xs ta (sync(e') e2') h' xs'" "sim_move10 P ta1 (insyncV(a) e1) (insyncV(a) e1') (insync(a') e) h xs ta (insync(a') e') h' xs'" "sim_move10 P ta1 (e1;;e2) (e1';;e2) (e;;e2') h xs ta (e';;e2') h' xs'" "sim_move10 P ta1 (if (e1) e2 else e3) (if (e1') e2 else e3) (if (e) e2' else e3') h xs ta (if (e') e2' else e3') h' xs'" "sim_move10 P ta1 (throw e1) (throw e1') (throw e) h xs ta (throw e') h' xs'" "sim_move10 P ta1 (try e1 catch(C V) e2) (try e1' catch(C V) e2) (try e catch(C' V') e2') h xs ta (try e' catch(C' V') e2') h' xs'" using assms by-(clarsimp simp add: sim_move10_def final_iff,rule conjI,force,fastsimp intro: red_reds.intros)+ lemma sim_moves10_expr: "sim_move10 P ta1 e1 e1' e h xs ta e' h' xs' ==> sim_moves10 P ta1 (e1 # es2) (e1' # es2) (e # es2') h xs ta (e' # es2') h' xs'" "sim_moves10 P ta1 es1 es1' es h xs ta es' h' xs' ==> sim_moves10 P ta1 (Val v # es1) (Val v # es1') (Val v # es) h xs ta (Val v # es') h' xs'" unfolding sim_moves10_def sim_move10_def final_iff finals_def apply(auto simp add: Cons_eq_append_conv) apply(fastsimp intro!: τred0r_inj_τreds0r τreds0r_cons_τreds0r τred0t_inj_τreds0t τreds0t_cons_τreds0t ListRed1 ListRed2)+ done lemma sim_move10_CallParams: "sim_moves10 P ta1 es1 es1' es h xs ta es' h' xs' ==> sim_move10 P ta1 (Val v•M(es1)) (Val v•M(es1')) (Val v•M(es)) h xs ta (Val v•M(es')) h' xs'" by(fastsimp simp add: sim_move10_def sim_moves10_def intro: Call_τred0r_param Call_τred0t_param CallParams) lemma sim_move10_Block: "sim_move10 P ta1 e1 e1' e h (xs(V' := vo)) ta e' h' xs' ==> sim_move10 P ta1 ({V:T=None; e1}) ({V:T=None; e1'}) ({V':T=vo; e}) h xs ta ({V':T=xs' V'; e'}) h' (xs'(V' := xs V'))" proof - assume "sim_move10 P ta1 e1 e1' e h (xs(V' := vo)) ta e' h' xs'" moreover { fix e'' xs'' assume "extTA2J0 P,P \<turnstile> 〈e'',(h, xs'')〉 -ta-> 〈e',(h', xs')〉" hence "extTA2J0 P,P \<turnstile> 〈e'',(h, xs''(V' := xs V', V' := xs'' V'))〉 -ta-> 〈e',(h', xs')〉" by simp from BlockRed[OF this, of T] have "extTA2J0 P,P \<turnstile> 〈{V':T=xs'' V'; e''},(h, xs''(V' := xs V'))〉 -ta-> 〈{V':T=xs' V'; e'},(h', xs'(V' := xs V'))〉" by simp } ultimately show ?thesis by(fastsimp simp add: sim_move10_def final_iff split: split_if_asm) qed lemma sim_move10_reds: "[| new_Addr h = ⌊a⌋; P \<turnstile> C has_fields FDTs |] ==> sim_move10 P ε (new C) e1' (new C) h xs ε (addr a) (h(a\<mapsto>(Obj C (init_fields FDTs)))) xs" "new_Addr h = None ==> sim_move10 P ε (new C) e1' (new C) h xs ε (THROW OutOfMemory) h xs" "[| new_Addr h = ⌊a⌋; i ≥ 0; h' = h(a \<mapsto> (Arr T (replicate (nat i) (default_val T)))) |] ==> sim_move10 P ε (newA T⌊Val (Intg i)⌉) e1' (newA T⌊Val (Intg i)⌉) h xs ε (addr a) h' xs" "i < 0 ==> sim_move10 P ε (newA T⌊Val (Intg i)⌉) e1' (newA T⌊Val (Intg i)⌉) h xs ε (THROW NegativeArraySize) h xs" "[| new_Addr h = None; i ≥ 0 |] ==> sim_move10 P ε (newA T⌊Val (Intg i)⌉) e1' (newA T⌊Val (Intg i)⌉) h xs ε (THROW OutOfMemory) h xs" "[| typeofh v = ⌊U⌋; P \<turnstile> U ≤ T |] ==> sim_move10 P ε (Cast T (Val v)) e1' (Cast T (Val v)) h xs ε (Val v) h xs" "[| typeofh v = ⌊U⌋; ¬ P \<turnstile> U ≤ T |] ==> sim_move10 P ε (Cast T (Val v)) e1' (Cast T (Val v)) h xs ε (THROW ClassCast) h xs" "binop bop v1 v2 = Some v ==> sim_move10 P ε ((Val v1) «bop» (Val v2)) e1' (Val v1 «bop» Val v2) h xs ε (Val v) h xs" "xs V = ⌊v⌋ ==> sim_move10 P ε (Var V') e1' (Var V) h xs ε (Val v) h xs" "sim_move10 P ε (V' := Val v) e1' (V := Val v) h xs ε unit h (xs(V \<mapsto> v))" "sim_move10 P ε (null⌊Val v⌉) e1' (null⌊Val v⌉) h xs ε (THROW NullPointer) h xs" "[| h a = ⌊Arr T el⌋; i < 0 ∨ i ≥ int (length el) |] ==> sim_move10 P ε (addr a⌊Val (Intg i)⌉) e1' ((addr a)⌊Val (Intg i)⌉) h xs ε (THROW ArrayIndexOutOfBounds) h xs" "[| h a = ⌊Arr T el⌋; i ≥ 0; i < int (length el) |] ==> sim_move10 P ε (addr a⌊Val (Intg i)⌉) e1' ((addr a)⌊Val (Intg i)⌉) h xs ε (Val (el ! nat i)) h xs" "sim_move10 P ε (null⌊Val v⌉ := Val v') e1' (null⌊Val v⌉ := Val v') h xs ε (THROW NullPointer) h xs" "[| h a = ⌊Arr T el⌋; i < 0 ∨ i ≥ int (length el) |] ==> sim_move10 P ε (AAss (addr a) (Val (Intg i)) (Val v)) e1' (AAss (addr a) (Val (Intg i)) (Val v)) h xs ε (THROW ArrayIndexOutOfBounds) h xs" "[| h a = ⌊Arr T el⌋; i ≥ 0; i < int (length el); typeofh v = ⌊U⌋; ¬ (P \<turnstile> U ≤ T) |] ==> sim_move10 P ε (AAss (addr a) (Val (Intg i)) (Val v)) e1' (AAss (addr a) (Val (Intg i)) (Val v)) h xs ε (THROW ArrayStore) h xs" "[| h a = ⌊Arr T el⌋; i ≥ 0; i < int (length el); typeofh v = Some U; P \<turnstile> U ≤ T; h' = h(a \<mapsto> (Arr T (el[nat i := v]))) |] ==> sim_move10 P ε (AAss (addr a) (Val (Intg i)) (Val v)) e1' (AAss (addr a) (Val (Intg i)) (Val v)) h xs ε unit h' xs" "h a = ⌊Arr T elem⌋ ==> sim_move10 P ε (addr a•length) e1' (addr a•length) h xs ε (Val (Intg (int (length elem)))) h xs" "sim_move10 P ε (null•length) e1' (null•length) h xs ε (THROW NullPointer) h xs" "[| h a = ⌊Obj C fs⌋; fs (F,D) = Some v |] ==> sim_move10 P ε (addr a•F{D}) e1' (addr a•F{D}) h xs ε (Val v) h xs" "sim_move10 P ε (null•F{D}) e1' (null•F{D}) h xs ε (THROW NullPointer) h xs" "h a = ⌊Obj C fs⌋ ==> sim_move10 P ε (addr a•F{D} := Val v) e1' (addr a•F{D} := Val v) h xs ε unit (h(a \<mapsto> (Obj C (fs((F,D) \<mapsto> v))))) xs" "sim_move10 P ε (null•F{D} := Val v) e1' (null•F{D} := Val v) h xs ε (THROW NullPointer) h xs" "sim_move10 P ε ({V':T=None; Val u}) e1' ({V:T=vo; Val u}) h xs ε (Val u) h xs" "sim_move10 P ε ({V':T=⌊v⌋; e}) ({V':T=None; e}) ({V:T=vo; e'}) h xs ε ({V:T=vo; e'}) h xs" "sim_move10 P ε (syncV'(null) e0) e1' (sync(null) e1) h xs ε (THROW NullPointer) h xs" "sim_move10 P ε (Val v;;e0) e1' (Val v;; e1) h xs ε e1 h xs" "sim_move10 P ε (if (true) e0 else e0') e1' (if (true) e1 else e2) h xs ε e1 h xs" "sim_move10 P ε (if (false) e0 else e0') e1' (if (false) e1 else e2) h xs ε e2 h xs" "sim_move10 P ε (throw null) e1' (throw null) h xs ε (THROW NullPointer) h xs" "sim_move10 P ε (try (Val v) catch(C V') e0) e1' (try (Val v) catch(C V) e1) h xs ε (Val v) h xs" "[| h a = ⌊Obj D fs⌋; P \<turnstile> D \<preceq>* C |] ==> sim_move10 P ε (try (Throw a) catch(C V') e0) e1' (try (Throw a) catch(C V) e1) h xs ε ({V:Class C=⌊Addr a⌋; e1}) h xs" "sim_move10 P ε (newA T⌊Throw a⌉) e1' (newA T⌊Throw a⌉) h xs ε (Throw a) h xs" "sim_move10 P ε (Cast T (Throw a)) e1' (Cast T (Throw a)) h xs ε (Throw a) h xs" "sim_move10 P ε ((Throw a) «bop» e0) e1' ((Throw a) «bop» e1) h xs ε (Throw a) h xs" "sim_move10 P ε (Val v «bop» (Throw a)) e1' (Val v «bop» (Throw a)) h xs ε (Throw a) h xs" "sim_move10 P ε (V' := Throw a) e1' (V := Throw a) h xs ε (Throw a) h xs" "sim_move10 P ε (Throw a⌊e0⌉) e1' (Throw a⌊e1⌉) h xs ε (Throw a) h xs" "sim_move10 P ε (Val v⌊Throw a⌉) e1' (Val v⌊Throw a⌉) h xs ε (Throw a) h xs" "sim_move10 P ε (Throw a⌊e0⌉ := e0') e1' (Throw a⌊e1⌉ := e2) h xs ε (Throw a) h xs" "sim_move10 P ε (Val v⌊Throw a⌉ := e0) e1' (Val v⌊Throw a⌉ := e1) h xs ε (Throw a) h xs" "sim_move10 P ε (Val v⌊Val v'⌉ := Throw a) e1' (Val v⌊Val v'⌉ := Throw a) h xs ε (Throw a) h xs" "sim_move10 P ε (Throw a•length) e1' (Throw a•length) h xs ε (Throw a) h xs" "sim_move10 P ε (Throw a•F{D}) e1' (Throw a•F{D}) h xs ε (Throw a) h xs" "sim_move10 P ε (Throw a•F{D} := e0) e1' (Throw a•F{D} := e1) h xs ε (Throw a) h xs" "sim_move10 P ε (Val v•F{D} := Throw a) e1' (Val v•F{D} := Throw a) h xs ε (Throw a) h xs" "sim_move10 P ε (Throw a•M(es0)) e1' (Throw a•M(es1)) h xs ε (Throw a) h xs" "sim_move10 P ε (Val v•M(map Val vs @ Throw a # es0)) e1' (Val v•M(map Val vs @ Throw a # es1)) h xs ε (Throw a) h xs" "sim_move10 P ε ({V':T=None; Throw a}) e1' ({V:T=vo; Throw a}) h xs ε (Throw a) h xs" "sim_move10 P ε (syncV'(Throw a) e0) e1' (sync(Throw a) e1) h xs ε (Throw a) h xs" "sim_move10 P ε (Throw a;;e0) e1' (Throw a;;e1) h xs ε (Throw a) h xs" "sim_move10 P ε (if (Throw a) e0 else e0') e1' (if (Throw a) e1 else e2) h xs ε (Throw a) h xs" "sim_move10 P ε (throw (Throw a)) e1' (throw (Throw a)) h xs ε (Throw a) h xs" by(fastsimp simp add: sim_move10_def no_calls_def no_call_def intro: red_reds.intros)+ lemma sim_move10_CallNull: "sim_move10 P ε (null•M(map Val vs)) e1' (null•M(map Val vs)) h xs ε (THROW NullPointer) h xs" by(fastsimp simp add: sim_move10_def map_eq_append_conv intro: RedCallNull) lemma sim_move10_SyncLocks: "[| h a = ⌊arrobj⌋; ta1 = ε\<lbrace>l Lock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace>; ta = ε\<lbrace>l Lock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace> |] ==> sim_move10 P ta1 (syncV(addr a) e0) e1' (sync(addr a) e1) h xs ta (insync(a) e1) h xs" "[| ta1 = ε\<lbrace>l Unlock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace>; ta = ε\<lbrace>l Unlock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace> |] ==> sim_move10 P ta1 (insyncV(a') (Val v)) e1' (insync(a) (Val v)) h xs ta (Val v) h xs" "[| ta1 = ε\<lbrace>l Unlock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace>; ta = ε\<lbrace>l Unlock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace> |] ==> sim_move10 P ta1 (insyncV(a') (Throw a'')) e1' (insync(a) (Throw a'')) h xs ta (Throw a'') h xs" by(fastsimp simp add: sim_move10_def ta_bisim_def intro: red_reds.intros[simplified])+ lemma sim_move10_TryFail: "[| h a = ⌊Obj D fs⌋; ¬ P \<turnstile> D \<preceq>* C |] ==> sim_move10 P ε (try (Throw a) catch(C V') e0) e1' (try (Throw a) catch(C V) e1) h xs ε (Throw a) h xs" by(auto simp add: sim_move10_def intro!: RedTryFail) lemmas sim_move10_intros = sim_move10_expr sim_move10_reds sim_move10_CallNull sim_move10_TryFail sim_move10_Block sim_move10_CallParams lemma sim_move10_preserves_defass: assumes wf: "wf_J_prog P" shows "[| sim_move10 P ta1 e1 e1' e h xs ta e' h' xs'; \<D> e ⌊dom xs⌋ |] ==> \<D> e' ⌊dom xs'⌋" by(auto simp add: sim_move10_def split: split_if_asm dest!: τred0r_preserves_defass[OF wf] τred0t_preserves_defass[OF wf] red_preserves_defass[OF wf]) declare sim_move10_intros[intro] lemma assumes wf: "wf_J_prog P" shows red_simulates_red1_aux: "[| compP1 P \<turnstile>1 〈e1, S〉 -TA-> 〈e1', S'〉; bisim vs e2 e1 (lcl S); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl S]; length vs + max_vars e1 ≤ length (lcl S); \<D> e2 ⌊dom x⌋; ¬ IUF e1 TA e1' |] ==> ∃ta e2' x'. sim_move10 P TA e1 e1' e2 (hp S) x ta e2' (hp S') x' ∧ bisim vs e2' e1' (lcl S') ∧ x' ⊆m [vs [\<mapsto>] lcl S']" (is "[| _; _; _; _; _; _; _ |] ==> ?concl e1 e1' e2 S x TA S' e1' vs") and reds_simulates_reds1_aux: "[| compP1 P \<turnstile>1 〈es1, S〉 [-TA->] 〈es1', S'〉; bisims vs es2 es1 (lcl S); fvs es2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl S]; length vs + max_varss es1 ≤ length (lcl S); \<D>s es2 ⌊dom x⌋; ¬ IUFs es1 TA es1' |] ==> ∃ta es2' x'. sim_moves10 P TA es1 es1' es2 (hp S) x ta es2' (hp S') x' ∧ bisims vs es2' es1' (lcl S') ∧ x' ⊆m [vs [\<mapsto>] lcl S']" (is "[| _; _; _; _; _; _; _ |] ==> ?concls es1 es1' es2 S x TA S' es1' vs") proof(induct arbitrary: vs e2 x and vs es2 x rule: red1_reds1.inducts) case (Bin1OpRed1 e s ta e' s' bop e2 Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 e (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars e ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF e ta e'|] ==> ?concl e e' e2 s x ta s' e' vs` from `compP1 P \<turnstile>1 〈e,s〉 -ta-> 〈e',s'〉` have "¬ is_val e" by auto with `bisim Vs E2 (e «bop» e2) (lcl s)` obtain E E2' where E2: "E2 = E «bop» E2'" "e2 = compE1 Vs E2'" and "bisim Vs E e (lcl s)" and sync: "¬ contains_insync E2'" by(auto elim!: bisim_cases) moreover from `¬ IUF (e «bop» e2) ta (e' «bop» e2)` have "¬ IUF e ta e'" by auto moreover note IH[of Vs E X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `length Vs + max_vars (e «bop» e2) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` ultimately obtain TA' e2' x' where "sim_move10 P ta e e' E (hp s) X TA' e2' (hp s') x'" "bisim Vs e2' e' (lcl s')" "x' ⊆m [Vs [\<mapsto>] lcl s']" by(auto) with E2 `fv E2 ⊆ set Vs` sync show ?case by(cases "is_val e2'")(auto intro: BinOpRed1) next case (Bin1OpRed2 e s ta e' s' v bop Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 e (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars e ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF e ta e'|] ==> ?concl e e' e2 s x ta s' e' vs` from `bisim Vs E2 (Val v «bop» e) (lcl s)` obtain E where E2: "E2 = Val v «bop» E" and "bisim Vs E e (lcl s)" by(auto) moreover from `¬ IUF (Val v «bop» e) ta (Val v «bop» e')` have "¬ IUF e ta e'" by auto moreover note IH[of Vs E X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `length Vs + max_vars (Val v «bop» e) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` E2 ultimately show ?case by(auto intro: BinOpRed2) next case (Red1Var s V v Vs E2 X) from `bisim Vs E2 (Var V) (lcl s)` `fv E2 ⊆ set Vs` obtain V' where "E2 = Var V'" "V' = Vs ! V" "V = index Vs V'" by(clarify, simp) from `E2 = Var V'` `\<D> E2 ⌊dom X⌋` obtain v' where "X V' = ⌊v'⌋" by(auto simp add: hyperset_defs) with `X ⊆m [Vs [\<mapsto>] lcl s]` have "[Vs [\<mapsto>] lcl s] V' = ⌊v'⌋" by(rule map_le_SomeD) with `length Vs + max_vars (Var V) ≤ length (lcl s)` have "lcl s ! (index Vs V') = v'" by(auto intro: map_upds_Some_eq_nth_index) with `V = index Vs V'` `lcl s ! V = v` have "v = v'" by simp with `X V' = ⌊v'⌋` `E2 = Var V'` `X ⊆m [Vs [\<mapsto>] lcl s]` show ?case by(fastsimp intro: RedVar) next case (LAss1Red e s ta e' s' V Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 e (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars e ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF e ta e'|] ==> ?concl e e' e2 s x ta s' e' vs` from `bisim Vs E2 (V:=e) (lcl s)` obtain E V' where E2: "E2 = (V':=E)" "V = index Vs V'" and "bisim Vs E e (lcl s)" by auto with IH[of Vs E X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `¬ IUF (V:=e) ta (V:=e')` `length Vs + max_vars (V:=e) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` E2 show ?case by(auto intro: LAssRed) next case (Red1LAss V l v h Vs E2 X) from `bisim Vs E2 (V:=Val v) (lcl (h, l))` obtain V' where "E2 = (V' := Val v)" "V = index Vs V'" by(auto) moreover with `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl (h, l)]` `length Vs + max_vars (V:=Val v) ≤ length (lcl (h, l))` have "X(V' \<mapsto> v) ⊆m [Vs [\<mapsto>] l[index Vs V' := v]]" by(auto intro: LAss_lem) ultimately show ?case by(auto intro: RedLAss simp del: fun_upd_apply) next case (AAcc1Red1 a s ta a' s' i Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 a (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars a ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF a ta a'|] ==> ?concl a a' e2 s x ta s' a' vs` from `compP1 P \<turnstile>1 〈a,s〉 -ta-> 〈a',s'〉` have "¬ is_val a" by auto with `bisim Vs E2 (a⌊i⌉) (lcl s)` obtain E E2' where E2: "E2 = E⌊E2'⌉" "i = compE1 Vs E2'" and "bisim Vs E a (lcl s)" and sync: "¬ contains_insync E2'" by(fastsimp) moreover from `¬ IUF (a⌊i⌉) ta (a'⌊i⌉)` have "¬ IUF a ta a'" by auto moreover note IH[of Vs E X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `length Vs + max_vars (a⌊i⌉) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` ultimately obtain TA' e2' x' where "sim_move10 P ta a a' E (hp s) X TA' e2' (hp s') x'" "bisim Vs e2' a' (lcl s')" "x' ⊆m [Vs [\<mapsto>] lcl s']" by(auto) with E2 `fv E2 ⊆ set Vs` sync show ?case by(cases "is_val e2'")(auto intro: AAccRed1) next case (AAcc1Red2 i s ta i' s' a Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 i (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars i ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF i ta i'|] ==> ?concl i i' e2 s x ta s' i' vs` from `bisim Vs E2 (Val a⌊i⌉) (lcl s)` obtain E where E2: "E2 = Val a⌊E⌉" and "bisim Vs E i (lcl s)" by(auto) moreover from `¬ IUF (Val a⌊i⌉) ta (Val a⌊i'⌉)` have "¬ IUF i ta i'" by auto moreover note IH[of Vs E X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` E2 `length Vs + max_vars (Val a⌊i⌉) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` ultimately show ?case by(auto intro: AAccRed2) next case Red1AAcc thus ?case by(fastsimp intro: RedAAcc simp del: fun_upd_apply) next case (AAss1Red1 a s ta a' s' i e Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 a (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars a ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF a ta a' |] ==> ?concl a a' e2 s x ta s' a' vs` from `compP1 P \<turnstile>1 〈a,s〉 -ta-> 〈a',s'〉` have "¬ is_val a" by auto with `bisim Vs E2 (a⌊i⌉:=e) (lcl s)` obtain E E2' E2'' where E2: "E2 = E⌊E2'⌉:=E2''" "i = compE1 Vs E2'" "e = compE1 Vs E2''" and "bisim Vs E a (lcl s)" and sync: "¬ contains_insync E2'" "¬ contains_insync E2''" by(fastsimp) moreover from `¬ IUF (a⌊i⌉ := e) ta (a'⌊i⌉ := e)` have "¬ IUF a ta a'" by auto moreover note IH[of Vs E X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `length Vs + max_vars (a⌊i⌉:=e) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` ultimately obtain TA' e2' x' where IH': "sim_move10 P ta a a' E (hp s) X TA' e2' (hp s') x'" "bisim Vs e2' a' (lcl s')" "x' ⊆m [Vs [\<mapsto>] lcl s']" by(auto) show ?case proof(cases "is_val e2'") case True from E2 `fv E2 ⊆ set Vs` sync have "bisim Vs E2' i (lcl s')" "bisim Vs E2'' e (lcl s')" by auto with IH' E2 True sync show ?thesis by(cases "is_val E2'")(fastsimp intro: AAssRed1)+ next case False with IH' E2 sync show ?thesis by(auto intro: AAssRed1) qed next case (AAss1Red2 i s ta i' s' a e Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 i (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars i ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF i ta i'|] ==> ?concl i i' e2 s x ta s' i' vs` from `compP1 P \<turnstile>1 〈i,s〉 -ta-> 〈i',s'〉` have "¬ is_val i" by auto with `bisim Vs E2 (Val a⌊i⌉:=e) (lcl s)` obtain E E2' where E2: "E2 = Val a⌊E⌉:=E2'" "e = compE1 Vs E2'" and "bisim Vs E i (lcl s)" and sync: "¬ contains_insync E2'" by(fastsimp) moreover from `¬ IUF (Val a⌊i⌉ := e) ta (Val a⌊i'⌉ := e)` have "¬ IUF i ta i'" by auto moreover note IH[of Vs E X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `length Vs + max_vars (Val a⌊i⌉:=e) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` ultimately obtain TA' e2' x' where "sim_move10 P ta i i' E (hp s) X TA' e2' (hp s') x'" "bisim Vs e2' i' (lcl s')" "x' ⊆m [Vs [\<mapsto>] lcl s']" by(auto) with E2 `fv E2 ⊆ set Vs` sync show ?case by(cases "is_val e2'")(auto intro: AAssRed2) next case (AAss1Red3 e s ta e' s' a i Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 e (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars e ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF e ta e'|] ==> ?concl e e' e2 s x ta s' e' vs` from `bisim Vs E2 (Val a⌊Val i⌉:=e) (lcl s)` obtain E where E2: "E2 = Val a⌊Val i⌉:=E" and "bisim Vs E e (lcl s)" by(fastsimp) moreover from `¬ IUF (Val a⌊Val i⌉ := e) ta (Val a⌊Val i⌉ := e')` have "¬ IUF e ta e'" by auto moreover note IH[of Vs E X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` E2 `length Vs + max_vars (Val a⌊Val i⌉:=e) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` ultimately show ?case by(auto intro: AAssRed3) next case Red1AAssStore thus ?case by(auto)((rule exI conjI)+, auto) next case Red1AAss thus ?case by(fastsimp simp del: fun_upd_apply) next case (FAss1Red1 e s ta e' s' F D e2 Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 e (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars e ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF e ta e' |] ==> ?concl e e' e2 s x ta s' e' vs` from `compP1 P \<turnstile>1 〈e,s〉 -ta-> 〈e',s'〉` have "¬ is_val e" by auto with `bisim Vs E2 (e•F{D}:=e2) (lcl s)` obtain E E2' where E2: "E2 = E•F{D}:=E2'" "e2 = compE1 Vs E2'" and "bisim Vs E e (lcl s)" and sync: "¬ contains_insync E2'" by(fastsimp) with IH[of Vs E X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `¬ IUF (e•F{D} := e2) ta (e'•F{D} := e2)` `length Vs + max_vars (e•F{D}:=e2) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` obtain TA' e2' x' where "sim_move10 P ta e e' E (hp s) X TA' e2' (hp s') x'" "bisim Vs e2' e' (lcl s')" "x' ⊆m [Vs [\<mapsto>] lcl s']" by(fastsimp) with E2 `fv E2 ⊆ set Vs` sync show ?case by(cases "is_val e2'")(auto intro: FAssRed1) next case (FAss1Red2 e s ta e' s' v F D Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 e (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars e ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF e ta e' |] ==> ?concl e e' e2 s x ta s' e' vs` from `bisim Vs E2 (Val v•F{D}:=e) (lcl s)` obtain E where E2: "E2 = (Val v•F{D}:=E)" and "bisim Vs E e (lcl s)" by(fastsimp) with IH[of Vs E X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `¬ IUF (Val v•F{D} := e) ta (Val v•F{D} := e')` `length Vs + max_vars (Val v•F{D}:=e) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` E2 show ?case by(fastsimp intro: FAssRed2) next case (Call1Obj e s ta e' s' M es Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 e (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars e ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF e ta e' |] ==> ?concl e e' e2 s x ta s' e' vs` from `compP1 P \<turnstile>1 〈e,s〉 -ta-> 〈e',s'〉` `bisim Vs E2 (e•M(es)) (lcl s)` obtain E es' where E2: "E2 = E•M(es')" "es = compEs1 Vs es'" and "bisim Vs E e (lcl s)" and sync: "¬ contains_insyncs es'" by(auto elim!: bisim_cases) with IH[of Vs E X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `¬ IUF (e•M(es)) ta (e'•M(es))` `length Vs + max_vars (e•M(es)) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` obtain TA' e2' x' where IH': "sim_move10 P ta e e' E (hp s) X TA' e2' (hp s') x'" "bisim Vs e2' e' (lcl s')" "x' ⊆m [Vs [\<mapsto>] lcl s']" by(fastsimp) with E2 `fv E2 ⊆ set Vs` `E2 = E•M(es')` sync show ?case by(cases "is_val e2'")(auto intro: CallObj) next case (Call1Params es s ta es' s' v M Vs E2 X) note IH = `!!vs es2 x. [| bisims vs es2 es (lcl s); fvs es2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_varss es ≤ length (lcl s); \<D>s es2 ⌊dom x⌋; ¬ IUFs es ta es'|] ==> ?concls es es' es2 s x ta s' es' vs` from `bisim Vs E2 (Val v•M(es)) (lcl s)` obtain Es where "E2 = Val v •M(Es)" "bisims Vs Es es (lcl s)" by(auto) with IH[of Vs Es X] `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `¬ IUF (Val v•M(es)) ta (Val v•M(es'))` `length Vs + max_vars (Val v•M(es)) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` `E2 = Val v •M(Es)` show ?case by(fastsimp intro: CallParams) next case (Red1CallExternal s a T M vs ta va h' e' s' Vs E2 X) from `bisim Vs E2 (addr a•M(map Val vs)) (lcl s)` have E2: "E2 = addr a•M(map Val vs)" by auto moreover from `is_external_call (compP1 P) T M` have "is_external_call P T M" by simp moreover from `compP1 P \<turnstile> 〈a•M(vs),hp s〉 -ta->ext 〈va,h'〉` have "P \<turnstile> 〈a•M(vs),hp s〉 -ta->ext 〈va,h'〉" by simp moreover from `typeofhp s (Addr a) = ⌊T⌋` have "hp s a ≠ None" by auto with wf `P \<turnstile> 〈a•M(vs),hp s〉 -ta->ext 〈va,h'〉` have "ta_bisim01 (extTA2J0 P ta) (extTA2J1 (compP1 P) ta)" by(rule red_external_ta_bisim01) moreover note `typeofhp s (Addr a) = ⌊T⌋` `e' = extRet2J1 va` `s' = (h', lcl s)` ultimately show ?case using `X ⊆m [Vs [\<mapsto>] lcl s]` apply(auto simp add: sim_move10_def) apply(rule exI conjI)+ apply clarify apply(rule conjI, clarsimp simp add: map_eq_append_conv) apply(fastsimp intro: RedCallExternal simp add: map_eq_append_conv synthesized_call_def) done next case (Block1Red e h x ta e' h' x' V T Vs E2 X) note IH = `!!vs e2 xa. [| bisim vs e2 e (lcl (h, x)); fv e2 ⊆ set vs; xa ⊆m [vs [\<mapsto>] lcl (h, x)]; length vs + max_vars e ≤ length (lcl (h, x)); \<D> e2 ⌊dom xa⌋; ¬ IUF e ta e'|] ==> ?concl e e' e2 (h, x) xa ta (h', x') e' vs` from `compP1 P \<turnstile>1 〈e,(h, x)〉 -ta-> 〈e',(h', x')〉` have "length x = length x'" by(auto dest: red1_preserves_len) with `length Vs + max_vars {V:T=None; e} ≤ length (lcl (h, x))` have "length Vs < length x'" by simp from `bisim Vs E2 {V:T=None; e} (lcl (h, x))` show ?case proof(cases rule: bisim_cases(12)[consumes 1, case_names BlockNone BlockSome BlockSomeNone]) case (BlockNone V' E) with `fv E2 ⊆ set Vs` have "fv E ⊆ set (Vs@[V'])" by auto with IH[of "Vs@[V']" E "X(V' := None)"] BlockNone `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl (h, x)]` `length Vs + max_vars {V:T=None; e} ≤ length (lcl (h, x))` `\<D> E2 ⌊dom X⌋` `¬ IUF {V:T=None; e} ta {V:T=None; e'}` obtain TA' e2' X' where IH': "sim_move10 P ta e e' E h (X(V' := None)) TA' e2' h' X'" "bisim (Vs @ [V']) e2' e' x'" "X' ⊆m [Vs @ [V'] [\<mapsto>] x']" by(fastsimp simp del: fun_upd_apply) { assume "V' ∈ set Vs" hence "hidden (Vs @ [V']) (index Vs V')" by(rule hidden_index) with `bisim (Vs @ [V']) E e (lcl (h, x))` have "unmod e (index Vs V')" by(auto intro: hidden_bisim_unmod) moreover from `length Vs + max_vars {V:T=None; e} ≤ length (lcl (h, x))` `V' ∈ set Vs` have "index Vs V' < length x" by(auto intro: index_less_aux) ultimately have "x ! index Vs V' = x' ! index Vs V'" using red1_preserves_unmod[OF `compP1 P \<turnstile>1 〈e,(h, x)〉 -ta-> 〈e',(h', x')〉`] by(simp) } with `length Vs + max_vars {V:T=None; e} ≤ length (lcl (h, x))` `X' ⊆m [Vs @ [V'] [\<mapsto>] x']` `length x = length x'` `X ⊆m [Vs [\<mapsto>] lcl (h, x)]` have rel: "X'(V' := X V') ⊆m [Vs [\<mapsto>] x']" by(auto intro: Block_lem) show ?thesis proof(cases "X' V'") case None with BlockNone IH' rel show ?thesis by(fastsimp intro: BlockRed) next case (Some v) with `X' ⊆m [Vs @ [V'] [\<mapsto>] x']` `length Vs < length x'` have "x' ! length Vs = v" by(auto dest: map_le_SomeD) with BlockNone IH' rel Some show ?thesis by(fastsimp intro: BlockRed) qed next case BlockSome thus ?thesis by simp next case (BlockSomeNone V' E) with `fv E2 ⊆ set Vs` have "fv E ⊆ set (Vs@[V'])" by auto with IH[of "Vs@[V']" E "X(V' \<mapsto> x ! length Vs)"] BlockSomeNone `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl (h, x)]` `length Vs + max_vars {V:T=None; e} ≤ length (lcl (h, x))` `\<D> E2 ⌊dom X⌋` `¬ IUF {V:T=None; e} ta {V:T=None; e'}` obtain TA' e2' X' where IH': "sim_move10 P ta e e' E h (X(V' \<mapsto> x ! length Vs)) TA' e2' h' X'" "bisim (Vs @ [V']) e2' e' x'" "X' ⊆m [Vs @ [V'] [\<mapsto>] x']" by(fastsimp simp del: fun_upd_apply) { assume "V' ∈ set Vs" hence "hidden (Vs @ [V']) (index Vs V')" by(rule hidden_index) with `bisim (Vs @ [V']) E e (lcl (h, x))` have "unmod e (index Vs V')" by(auto intro: hidden_bisim_unmod) moreover from `length Vs + max_vars {V:T=None; e} ≤ length (lcl (h, x))` `V' ∈ set Vs` have "index Vs V' < length x" by(auto intro: index_less_aux) ultimately have "x ! index Vs V' = x' ! index Vs V'" using red1_preserves_unmod[OF `compP1 P \<turnstile>1 〈e,(h, x)〉 -ta-> 〈e',(h', x')〉`] by(simp) } with `length Vs + max_vars {V:T=None; e} ≤ length (lcl (h, x))` `X' ⊆m [Vs @ [V'] [\<mapsto>] x']` `length x = length x'` `X ⊆m [Vs [\<mapsto>] lcl (h, x)]` have rel: "X'(V' := X V') ⊆m [Vs [\<mapsto>] x']" by(auto intro: Block_lem) from `sim_move10 P ta e e' E h (X(V' \<mapsto> x ! length Vs)) TA' e2' h' X'` obtain v' where "X' V' = ⌊v'⌋" by(auto simp: sim_move10_def split: split_if_asm dest!: τred0t_lcl_incr τred0r_lcl_incr red_lcl_incr subsetD) with `X' ⊆m [Vs @ [V'] [\<mapsto>] x']` `length Vs < length x'` have "x' ! length Vs = v'" by(auto dest: map_le_SomeD) with BlockSomeNone IH' rel `X' V' = ⌊v'⌋` show ?thesis by(fastsimp intro: BlockRed) qed next case(Block1Some V xs T v e h) from `bisim vs e2 {V:T=⌊v⌋; e} (lcl (h, xs))` obtain e' V' where "e2 = {V':T=⌊v⌋; e'}" and "V = length vs" "bisim (vs @ [V']) e' e (xs[length vs := v])" by(fastsimp) moreover have "sim_move10 P ε {length vs:T=⌊v⌋; e} {length vs:T=None; e} {V':T=⌊v⌋; e'} h x ε {V':T=⌊v⌋; e'} h x" by(auto) moreover from `bisim (vs @ [V']) e' e (xs[length vs := v])` `length vs + max_vars {V:T=⌊v⌋; e} ≤ length (lcl (h, xs))` have "bisim vs {V':T=⌊v⌋; e'} {length vs:T=None; e} (xs[length vs := v])" by auto moreover from `x ⊆m [vs [\<mapsto>] lcl (h, xs)]` `length vs + max_vars {V:T=⌊v⌋; e} ≤ length (lcl (h, xs))` have "x ⊆m [vs [\<mapsto>] xs[length vs := v]]" by auto ultimately show ?case by auto next case (Lock1Synchronized h a arrobj V xs e Vs E2 X) note len = `length Vs + max_vars (syncV (addr a) e) ≤ length (lcl (h, xs))` from `bisim Vs E2 (syncV (addr a) e) (lcl (h, xs))` obtain E where E2: "E2 = sync(addr a) E" "e = compE1 (Vs@[fresh_var Vs]) E" and sync: "¬ contains_insync E" and [simp]: "V = length Vs" by auto moreover from `h a = ⌊arrobj⌋` have "extTA2J0 P,P \<turnstile> 〈sync(addr a) E, (h, X)〉 -ε\<lbrace>l Lock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace>-> 〈insync(a) E, (h, X)〉" by-(rule LockSynchronized, auto) moreover from `fv E2 ⊆ set Vs` fresh_var_fresh[of Vs] sync len have "bisim Vs (insync(a) E) (insynclength Vs (a) e) (xs[length Vs := Addr a])" unfolding `e = compE1 (Vs@[fresh_var Vs]) E` `E2 = sync(addr a) E` by -(rule bisimInSynchronized,rule compE1_bisim, auto) moreover have "zip Vs (xs[length Vs := Addr a]) = (zip Vs xs)[length Vs := (arbitrary, Addr a)]" by(rule sym)(simp add: update_zip) hence "zip Vs (xs[length Vs := Addr a]) = zip Vs xs" by simp with `X ⊆m [Vs [\<mapsto>] (lcl (h, xs))]` have "X ⊆m [Vs [\<mapsto>] xs[length Vs := Addr a]]" by(auto simp add: map_le_def map_upds_def) ultimately show ?case using `h a = ⌊arrobj⌋` by(fastsimp intro: sim_move10_SyncLocks) next case (Synchronized1Red2 e s ta e' s' V a Vs E2 X) note IH = `!!vs e2 x. [| bisim vs e2 e (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars e ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF e ta e' |] ==> ?concl e e' e2 s x ta s' e' vs` from `bisim Vs E2 (insyncV (a) e) (lcl s)` obtain E where E2: "E2 = insync(a) E" and bisim: "bisim (Vs@[fresh_var Vs]) E e (lcl s)" and xsa: "lcl s ! length Vs = Addr a" and [simp]: "V = length Vs" by auto with `fv E2 ⊆ set Vs` fresh_var_fresh[of Vs] have fv: "(fresh_var Vs) ∉ fv E" by auto from `length Vs + max_vars (insyncV (a) e) ≤ length (lcl s)` have "length Vs < length (lcl s)" by simp { assume "X (fresh_var Vs) ≠ None" then obtain v where "X (fresh_var Vs) = ⌊v⌋" by auto with `X ⊆m [Vs [\<mapsto>] lcl s]` have "[Vs [\<mapsto>] lcl s] (fresh_var Vs) = ⌊v⌋" by(auto simp add: map_le_def dest: bspec) hence "(fresh_var Vs) ∈ set Vs" by(auto simp add: map_upds_def set_zip dest!: map_of_SomeD ) moreover have "(fresh_var Vs) ∉ set Vs" by(rule fresh_var_fresh) ultimately have False by contradiction } hence "X (fresh_var Vs) = None" by(cases "X (fresh_var Vs)", auto) hence "X(fresh_var Vs := None) = X" by(auto intro: ext) moreover from `X ⊆m [Vs [\<mapsto>] lcl s]` have "X(fresh_var Vs := None) ⊆m [Vs [\<mapsto>] lcl s, (fresh_var Vs) \<mapsto> (lcl s) ! length Vs]" by(simp) ultimately have "X ⊆m [Vs @ [fresh_var Vs] [\<mapsto>] lcl s]" using `length Vs < length (lcl s)` by(auto) moreover from `¬ IUF (insyncV (a) e) ta (insyncV (a) e')` have "¬ IUF e ta e'" by(auto) moreover note IH[of "Vs@[fresh_var Vs]" E X] bisim E2 `fv E2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `length Vs + max_vars (insyncV (a) e) ≤ length (lcl s)` `\<D> E2 ⌊dom X⌋` ultimately obtain TA' e2' x' where IH': "sim_move10 P ta e e' E (hp s) X TA' e2' (hp s') x'" "bisim (Vs @ [fresh_var Vs]) e2' e' (lcl s')" "x' ⊆m [Vs @ [fresh_var Vs] [\<mapsto>] lcl s']" by auto hence "dom x' ⊆ dom X ∪ fv E" apply(auto simp add: sim_move10_def dest: τred0r_dom_lcl[OF wf_prog_wwf_prog[OF wf]] τred0t_dom_lcl[OF wf_prog_wwf_prog[OF wf]] split: split_if_asm) apply(frule red_dom_lcl) apply(frule τred0r_dom_lcl[OF wf_prog_wwf_prog[OF wf]]) apply(frule τred0r_fv_subset[OF wf_prog_wwf_prog[OF wf]]) apply(simp, blast) done with fv `X (fresh_var Vs) = None` have "(fresh_var Vs) ∉ dom x'" by auto hence "x' (fresh_var Vs) = None" by auto moreover from `compP1 P \<turnstile>1 〈e,s〉 -ta-> 〈e',s'〉` have "length (lcl s) = length (lcl s')" by(auto dest: red1_preserves_len) moreover note `x' ⊆m [Vs @ [fresh_var Vs] [\<mapsto>] lcl s']` `length Vs < length (lcl s)` ultimately have "x' ⊆m [Vs [\<mapsto>] lcl s']" by(auto simp add: map_le_def dest: bspec) moreover from bisim fv have "unmod e (length Vs)" by(auto intro: bisim_fv_unmod) with `compP1 P \<turnstile>1 〈e,s〉 -ta-> 〈e',s'〉` `length Vs < length (lcl s)` have "lcl s ! length Vs = lcl s' ! length Vs" by(auto dest!: red1_preserves_unmod) with xsa have "lcl s' ! length Vs = Addr a" by simp ultimately show ?case using IH' E2 by(auto intro: SynchronizedRed2) next case (Unlock1Synchronized xs V a' a v h Vs E2 X) from `bisim Vs E2 (insyncV (a) Val v) (lcl (h, xs))` have E2: "E2 = insync(a) Val v" "V = length Vs" "xs ! length Vs = Addr a" by auto moreover with `xs ! V = Addr a'` have [simp]: "a' = a" by simp have "extTA2J0 P,P \<turnstile> 〈insync(a) (Val v), (h, X)〉 -ε\<lbrace>l Unlock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace>-> 〈Val v, (h, X)〉" by(rule UnlockSynchronized) ultimately show ?case using `X ⊆m [Vs [\<mapsto>] lcl (h, xs)]` by(fastsimp intro: sim_move10_SyncLocks) next case (Unlock1SynchronizedNull xs V a v h Vs E2 X) from `bisim Vs E2 (insyncV (a) Val v) (lcl (h, xs))` have "V = length Vs" "xs ! length Vs = Addr a" by(auto) with `xs ! V = Null` have False by simp thus ?case .. next case (Unlock1SynchronizedFail xs V A' a' v h Vs E2 X) from `bisim Vs E2 (insyncV (a') Val v) (lcl (h, xs))` `xs ! V = Addr A'` have "A' = a'" by auto with `¬ IUF (insyncV (a') Val v) ε\<lbrace>lUnlockFail->A'\<rbrace> (THROW IllegalMonitorState)` have False by(auto simp del: ta_update_locks.simps) thus ?case .. next case (Red1While b c s Vs E2 X) from `bisim Vs E2 (while (b) c) (lcl s)` obtain B C where E2: "E2 = while (B) C" "b = compE1 Vs B" "c = compE1 Vs C" and sync: "¬ contains_insync B" "¬ contains_insync C" by auto moreover have "extTA2J0 P,P \<turnstile> 〈while (B) C, (hp s, X)〉 -ε-> 〈if (B) (C;;while (B) C) else unit, (hp s, X)〉" by(rule RedWhile) hence "sim_move10 P ε (while (compE1 Vs B) (compE1 Vs C)) (if (compE1 Vs B) (compE1 Vs C;;while (compE1 Vs B) (compE1 Vs C)) else unit) (while (B) C) (hp s) X ε (if (B) (C;;while (B) C) else unit) (hp s) X" by(auto simp add: sim_move10_def) moreover from `fv E2 ⊆ set Vs` E2 sync have "bisim Vs (if (B) (C;; while (B) C) else unit) (if (compE1 Vs B) (compE1 Vs (C;; while(B) C)) else (compE1 Vs unit)) (lcl s)" by -(rule bisimCond, auto) ultimately show ?case using `X ⊆m [Vs [\<mapsto>] lcl s]` by(simp)(rule exI, rule exI, rule exI, erule conjI, auto) next case (Red1TryCatch h a D fs C V x e2 Vs E2 X) from `bisim Vs E2 (try Throw a catch(C V) e2) (lcl (h, x))` obtain E2' V' where "E2 = try Throw a catch(C V') E2'" "V = length Vs" "e2 = compE1 (Vs @ [V']) E2'" and sync: "¬ contains_insync E2'" by(auto) with `fv E2 ⊆ set Vs` have "fv E2' ⊆ set (Vs @[V'])" by auto with `e2 = compE1 (Vs @ [V']) E2'` sync have "bisim (Vs @[V']) E2' e2 (x[V := Addr a])" by(auto intro!: compE1_bisim) with `V = length Vs` `length Vs + max_vars (try Throw a catch(C V) e2) ≤ length (lcl (h, x))` have "bisim Vs {V':Class C=⌊Addr a⌋; E2'} {length Vs:Class C=None; e2} (x[V := Addr a])" by(auto intro: bisimBlockSomeNone) moreover from `length Vs + max_vars (try Throw a catch(C V) e2) ≤ length (lcl (h, x))` have "[Vs [\<mapsto>] x[length Vs := Addr a]] = [Vs [\<mapsto>] x]" by simp with `X ⊆m [Vs [\<mapsto>] lcl (h, x)]` have "X ⊆m [Vs [\<mapsto>] x[length Vs := Addr a]]" by simp moreover note `e2 = compE1 (Vs @ [V']) E2'` `E2 = try Throw a catch(C V') E2'` `h a = ⌊Obj D fs⌋` `compP1 P \<turnstile> D \<preceq>* C` `V = length Vs` ultimately show ?case by(auto intro!: exI) next case Red1TryFail thus ?case by(auto intro!: exI sim_move10_TryFail) next case (List1Red1 e s ta e' s' es Vs ES2 X) note IH = `!!vs e2 x. [| bisim vs e2 e (lcl s); fv e2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_vars e ≤ length (lcl s); \<D> e2 ⌊dom x⌋; ¬ IUF e ta e'|] ==> ∃TA' e2' x'. sim_move10 P ta e e' e2 (hp s) x TA' e2' (hp s') x' ∧ bisim vs e2' e' (lcl s') ∧ x' ⊆m [vs [\<mapsto>] lcl s']` from `bisims Vs ES2 (e # es) (lcl s)` `compP1 P \<turnstile>1 〈e,s〉 -ta-> 〈e',s'〉` obtain E ES where "ES2 = E # ES" "¬ is_val E" "es = compEs1 Vs ES" "bisim Vs E e (lcl s)" and sync: "¬ contains_insyncs ES" by(auto elim!: bisims_cases) with IH[of Vs E X] `fvs ES2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `¬ IUFs (e # es) ta (e' # es)` `length Vs + max_varss (e # es) ≤ length (lcl s)` `\<D>s ES2 ⌊dom X⌋` obtain TA' e2' x' where IH': "sim_move10 P ta e e' E (hp s) X TA' e2' (hp s') x'" "bisim Vs e2' e' (lcl s')" "x' ⊆m [Vs [\<mapsto>] lcl s']" by fastsimp show ?case proof(cases "is_val e2'") case False with IH' `ES2 = E # ES` `es = compEs1 Vs ES` sync show ?thesis by(auto intro: sim_moves10_expr) next case True from `fvs ES2 ⊆ set Vs` `ES2 = E # ES` `es = compEs1 Vs ES` sync have "bisims Vs ES es (lcl s')" by(auto intro: compEs1_bisims) with IH' True `ES2 = E # ES` `es = compEs1 Vs ES` show ?thesis by(auto intro: sim_moves10_expr) qed next case (List1Red2 es s ta es' s' v Vs ES2 X) note IH = `!!vs es2 x. [|bisims vs es2 es (lcl s); fvs es2 ⊆ set vs; x ⊆m [vs [\<mapsto>] lcl s]; length vs + max_varss es ≤ length (lcl s); \<D>s es2 ⌊dom x⌋; ¬ IUFs es ta es'|] ==> ∃TA' es2' x'. sim_moves10 P ta es es' es2 (hp s) x TA' es2' (hp s') x' ∧ bisims vs es2' es' (lcl s') ∧ x' ⊆m [vs [\<mapsto>] lcl s']` from `bisims Vs ES2 (Val v # es) (lcl s)` obtain ES where "ES2 = Val v # ES" "bisims Vs ES es (lcl s)" by(auto elim!: bisims_cases) with IH[of Vs ES X] `fvs ES2 ⊆ set Vs` `X ⊆m [Vs [\<mapsto>] lcl s]` `¬ IUFs (Val v # es) ta (Val v # es')` `length Vs + max_varss (Val v # es) ≤ length (lcl s)` `\<D>s ES2 ⌊dom X⌋` `ES2 = Val v # ES` show ?case by(fastsimp intro: sim_moves10_expr) next case Call1ThrowParams thus ?case by(fastsimp intro: CallThrowParams elim!: bisim_cases simp add: bisims_map_Val_Throw2) next case (Synchronized1Throw2 xs V a' a ad h Vs E2 X) from `bisim Vs E2 (insyncV (a) Throw ad) (lcl (h, xs))` have "xs ! length Vs = Addr a" and "V = length Vs" by auto with `xs ! V = Addr a'` have [simp]: "a' = a" by simp have "extTA2J0 P,P \<turnstile> 〈insync(a) Throw ad, (h, X)〉 -ε\<lbrace>l Unlock->a \<rbrace>\<lbrace>o Synchronization a\<rbrace>-> 〈Throw ad, (h, X)〉" by(rule SynchronizedThrow2) with `X ⊆m [Vs [\<mapsto>] lcl (h, xs)]` `bisim Vs E2 (insyncV (a) Throw ad) (lcl (h, xs))` show ?case by(auto intro: sim_move10_SyncLocks intro!: exI) next case (Synchronized1Throw2Null xs V a a' h Vs E2 X) from `bisim Vs E2 (insyncV (a) Throw a') (lcl (h, xs))` have "V = length Vs" "xs ! length Vs = Addr a" by(auto) with `xs ! V = Null` have False by simp thus ?case .. next case (Synchronized1Throw2Fail xs V A' a' a h Vs E2 X) from `bisim Vs E2 (insyncV (a') Throw a) (lcl (h, xs))` `xs ! V = Addr A'` have "A' = a'" by auto with `¬ IUF (insyncV (a') Throw a) ε\<lbrace>lUnlockFail->A'\<rbrace> (THROW IllegalMonitorState)` have False by(auto simp del: ta_update_locks.simps) thus ?case .. qed(simp_all del: fun_upd_apply, (fastsimp intro: red_reds.intros simp del: fun_upd_apply simp add: finfun_upd_apply)+) lemma bisim_max_vars: "bisim Vs e e' xs ==> max_vars e = max_vars e'" and bisims_max_varss: "bisims Vs es es' xs ==> max_varss es = max_varss es'" apply(induct rule: bisim_bisims.inducts) apply(auto simp add: max_vars_compE1 max_varss_compEs1) done lemma bisim_call: "bisim Vs e e' xs ==> call e = call e'" and bisims_calls: "bisims Vs es es' xs ==> calls es = calls es'" apply(induct rule: bisim_bisims.inducts) apply(auto simp add: is_vals_conv) done lemma bisim_call_None_call1: "[| bisim Vs e e' xs; call e = None |] ==> call1 e' = None" and bisims_calls_None_calls1: "[| bisims Vs es es' xs; calls es = None |] ==> calls1 es' = None" by(induct rule: bisim_bisims.inducts)(auto simp add: is_vals_conv split: split_if_asm) lemma bisim_call_Some_call1: "[| bisim Vs e e' xs; call e = ⌊aMvs⌋; length Vs + max_vars e' ≤ length xs |] ==> ∃e'' xs'. τred1'r P h (e', xs) (e'', xs') ∧ call1 e'' = ⌊aMvs⌋ ∧ bisim Vs e e'' xs' ∧ take (length Vs) xs = take (length Vs) xs'" and bisims_calls_Some_calls1: "[| bisims Vs es es' xs; calls es = ⌊aMvs⌋; length Vs + max_varss es' ≤ length xs |] ==> ∃es'' xs'. τreds1'r P h (es', xs) (es'', xs') ∧ calls1 es'' = ⌊aMvs⌋ ∧ bisims Vs es es'' xs' ∧ take (length Vs) xs = take (length Vs) xs'" proof(induct rule: bisim_bisims.inducts) case bisimCallParams thus ?case by(fastsimp simp add: is_vals_conv split: split_if_asm) next case bisimBlockNone thus ?case by(fastsimp intro: take_eq_take_le_eq) next case (bisimBlockSome Vs V e e' xs v T) from `length Vs + max_vars {length Vs:T=⌊v⌋; e'} ≤ length xs` have "τred1'r P h ({length Vs:T=⌊v⌋; e'}, xs) ({length Vs:T=None; e'}, xs[length Vs := v])" by(auto intro!: τred1'r_1step Block1Some) also from bisimBlockSome obtain e'' xs' where "τred1'r P h (e', xs[length Vs := v]) (e'', xs')" and "call1 e'' = ⌊aMvs⌋" "bisim (Vs @ [V]) e e'' xs'" and "take (length (Vs @ [V])) (xs[length Vs := v]) = take (length (Vs @ [V])) xs'" by auto hence "τred1'r P h ({length Vs:T=None; e'}, xs[length Vs := v]) ({length Vs:T=None; e''}, xs')" by auto also from `call1 e'' = ⌊aMvs⌋` have "call1 {length Vs:T=None; e''} = ⌊aMvs⌋" by simp moreover from `take (length (Vs @ [V])) (xs[length Vs := v]) = take (length (Vs @ [V])) xs'` have "take (length Vs) xs = take (length Vs) xs'" by(auto dest: take_eq_take_le_eq[where m="length Vs"] simp add: take_list_update_beyond) moreover { have "xs' ! length Vs = take (length (Vs @ [V])) xs' ! length Vs" by simp also note `take (length (Vs @ [V])) (xs[length Vs := v]) = take (length (Vs @ [V])) xs'`[symmetric] also have "take (length (Vs @ [V])) (xs[length Vs := v]) ! length Vs = v" using `length Vs + max_vars {length Vs:T=⌊v⌋; e'} ≤ length xs` by simp finally have "bisim Vs {V:T=⌊v⌋; e} {length Vs:T=None; e''} xs'" using `bisim (Vs @ [V]) e e'' xs'` by auto } ultimately show ?case by blast next case (bisimBlockSomeNone Vs V e e' xs v T) then obtain e'' xs' where "τred1'r P h (e', xs) (e'', xs')" "call1 e'' = ⌊aMvs⌋" "bisim (Vs @ [V]) e e'' xs'" and "take (length (Vs @ [V])) xs = take (length (Vs @ [V])) xs'" by auto hence "τred1'r P h ({length Vs:T=None; e'}, xs) ({length Vs:T=None; e''}, xs')" by auto moreover from `call1 e'' = ⌊aMvs⌋` have "call1 ({length Vs:T=None; e''}) = ⌊aMvs⌋" by simp moreover from `take (length (Vs @ [V])) xs = take (length (Vs @ [V])) xs'` have "take (length Vs) xs = take (length Vs) xs'" by(auto intro: take_eq_take_le_eq) moreover { have "xs' ! length Vs = take (length (Vs @ [V])) xs' ! length Vs" by simp also note `take (length (Vs @ [V])) xs = take (length (Vs @ [V])) xs'`[symmetric] also have "take (length (Vs @ [V])) xs ! length Vs = v" using `xs ! length Vs = v` by simp finally have "bisim Vs {V:T=⌊v⌋; e} {length Vs:T=None; e''} xs'" using `bisim (Vs @ [V]) e e'' xs'` by auto } ultimately show ?case by blast next case (bisimInSynchronized Vs e e' xs a) then obtain e'' xs' where "τred1'r P h (e', xs) (e'', xs')" "call1 e'' = ⌊aMvs⌋" "bisim (Vs @ [fresh_var Vs]) e e'' xs'" and "take (Suc (length Vs)) xs = take (Suc (length Vs)) xs'" by auto hence "τred1'r P h (insynclength Vs (a) e', xs) (insynclength Vs (a) e'', xs')" by auto moreover from `call1 e'' = ⌊aMvs⌋` have "call1 (insynclength Vs (a) e'') = ⌊aMvs⌋" by simp moreover from `take (Suc (length Vs)) xs = take (Suc (length Vs)) xs'` have "take (length Vs) xs = take (length Vs) xs'" by(auto intro: take_eq_take_le_eq) moreover { have "xs' ! length Vs = take (Suc (length Vs)) xs' ! length Vs" by simp also note `take (Suc (length Vs)) xs = take (Suc (length Vs)) xs'`[symmetric] also have "take (Suc (length Vs)) xs ! length Vs = Addr a" using `xs ! length Vs = Addr a` by simp finally have "bisim Vs (insync(a) e) (insynclength Vs (a) e'') xs'" using `bisim (Vs @ [fresh_var Vs]) e e'' xs'` by auto } ultimately show ?case by blast next case bisimsCons1 thus ?case by(fastsimp intro!: τred1'r_inj_τreds1'r) next case bisimsCons2 thus ?case by(fastsimp intro!: τreds1'r_cons_τreds1'r) qed fastsimp+ lemma bisim_call1_Some_call: "[| bisim Vs e e' xs; call1 e' = ⌊aMvs⌋ |] ==> call e = ⌊aMvs⌋" and bisims_calls1_Some_calls: "[| bisims Vs es es' xs; calls1 es' = ⌊aMvs⌋ |] ==> calls es = ⌊aMvs⌋" by(induct rule: bisim_bisims.inducts)(auto simp add: is_vals_conv split: split_if_asm) lemma blocks_bisim: assumes bisim: "bisim (Vs @ pns) e e' xs" and length: "length vs = length pns" "length Ts = length pns" and xs: "∀i. i < length vs --> xs ! (i + length Vs) = vs ! i" shows "bisim Vs (blocks (pns, Ts, vs, e)) (blocks1 (length Vs) Ts e') xs" using bisim length xs proof(induct pns Ts vs e arbitrary: e' Vs rule: blocks.induct) case (5 V Vs T Ts v vs e e' VS) note IH = `!!e' Vsa. [|bisim (Vsa @ Vs) e e' xs; length vs = length Vs; length Ts = length Vs; ∀i<length vs. xs ! (i + length Vsa) = vs ! i|] ==> bisim Vsa (blocks (Vs, Ts, vs, e)) (blocks1 (length Vsa) Ts e') xs` note xs = `∀i<length (v # vs). xs ! (i + length VS) = (v # vs) ! i` hence xs': "∀i<length vs. xs ! (i + length (VS @ [V])) = vs ! i" and v: "xs ! length VS = v" by(auto) from `bisim (VS @ V # Vs) e e' xs` have "bisim ((VS @ [V]) @ Vs) e e' xs" by simp from IH[OF this _ _ xs'] `length (v # vs) = length (V # Vs)` `length (T # Ts) = length (V # Vs)` have "bisim (VS @ [V]) (blocks (Vs, Ts, vs, e)) (blocks1 (length (VS @ [V])) Ts e') xs" by auto hence "bisim VS ({V:T=⌊v⌋; blocks (Vs, Ts, vs, e)}) {length VS:T=None; blocks1 (length (VS @ [V])) Ts e'} xs" using v by(rule bisimBlockSomeNone) thus ?case by simp qed(auto) lemma blocks_max_vars: "[| length vs = length pns; length Ts = length pns |] ==> max_vars (blocks (pns, Ts, vs, e)) = max_vars e + length pns" by(induct pns Ts vs e rule: blocks.induct)(auto) lemma blocks1_max_vars: "max_vars (blocks1 n Ts e) = max_vars e + length Ts" by(induct n Ts e rule: blocks1.induct)(auto) lemma fixes e :: "('a,'b) exp" and es :: "('a,'b) exp list" shows inline_call_max_vars: "call e = ⌊aMvs⌋ ==> max_vars (inline_call e' e) ≤ max_vars e + max_vars e'" and inline_calls_max_varss: "calls es = ⌊aMvs⌋ ==> max_varss (inline_calls e' es) ≤ max_varss es + max_vars e'" by(induct e and es)(auto) lemma assumes "final E" "bisim VS E E' xs" shows inline_call_compE1: "call e = ⌊aMvs⌋ ==> inline_call E' (compE1 Vs e) = compE1 Vs (inline_call E e)" and inline_calls_compEs1: "calls es = ⌊aMvs⌋ ==> inline_calls E' (compEs1 Vs es) = compEs1 Vs (inline_calls E es)" proof(induct e and es arbitrary: Vs and Vs) case (Call obj M params Vs) note IHobj = `!!Vs. call obj = ⌊aMvs⌋ ==> inline_call E' (compE1 Vs obj) = compE1 Vs (inline_call E obj)` note IHparams = `!!Vs. calls params = ⌊aMvs⌋ ==> inline_calls E' (compEs1 Vs params) = compEs1 Vs (inline_calls E params)` obtain a M' vs where [simp]: "aMvs = (a, M', vs)" by (cases aMvs, auto) with `call (obj•M(params)) = ⌊aMvs⌋` have "call (obj•M(params)) = ⌊(a, M', vs)⌋" by simp thus ?case proof(induct rule: call_callE) case CallObj with IHobj[of Vs] have "inline_call E' (compE1 Vs obj) = compE1 Vs (inline_call E obj)" by auto with CallObj show ?case by auto next case (CallParams v) with IHparams[of Vs] have "inline_calls E' (compEs1 Vs params) = compEs1 Vs (inline_calls E params)" by auto with CallParams show ?case by(auto simp add: is_vals_conv) next case Call with `final E` `bisim VS E E' xs` show ?case by(auto simp add: is_vals_conv) qed qed(auto split: split_if_asm) lemma assumes bisim: "bisim VS E E' XS" and final: "final E" shows bisim_inline_call: "[| bisim Vs e e' xs; call e = ⌊aMvs⌋; fv e ⊆ set Vs |] ==> bisim Vs (inline_call E e) (inline_call E' e') xs" and bisims_inline_calls: "[| bisims Vs es es' xs; calls es = ⌊aMvs⌋; fvs es ⊆ set Vs |] ==> bisims Vs (inline_calls E es) (inline_calls E' es') xs" proof(induct rule: bisim_bisims.inducts) case (bisimBinOp1 Vs e e' xs bop e'') thus ?case by(cases "is_val (inline_call E e)")(fastsimp)+ next case (bisimAAcc1 Vs a a' xs i) thus ?case by(cases "is_val (inline_call E a)")(fastsimp)+ next case (bisimAAss1 Vs a a' xs i e) thus ?case by(cases "is_val (inline_call E a)", cases "is_val i")(fastsimp)+ next case (bisimAAss2 Vs i i' xs a e) thus ?case by(cases "is_val (inline_call E i)")(fastsimp)+ next case (bisimFAss1 Vs e e' xs F D e'') thus ?case by(cases "is_val (inline_call E e)")(fastsimp)+ next case (bisimCallObj Vs e e' xs es M) obtain a M' vs where "aMvs = (a, M', vs)" by(cases aMvs, auto) with `call (e•M(es)) = ⌊aMvs⌋` have "call (e•M(es)) = ⌊(a, M', vs)⌋" by simp thus ?case proof(induct rule: call_callE) case CallObj with `fv (e•M(es)) ⊆ set Vs` `aMvs = (a, M', vs)` `[|call e = ⌊aMvs⌋; fv e ⊆ set Vs|] ==> bisim Vs (inline_call E e) (inline_call E' e') xs` have IH': "bisim Vs (inline_call E e) (inline_call E' e') xs" by(auto) with `bisim Vs e e' xs` `fv (e•M(es)) ⊆ set Vs` CallObj `¬ contains_insyncs es` show ?thesis by(cases "is_val (inline_call E e)")(fastsimp)+ next case (CallParams v) hence "inline_calls E' (compEs1 Vs es) = compEs1 Vs (inline_calls E es)" by -(rule inline_calls_compEs1[OF final bisim]) moreover from `fv (e•M(es)) ⊆ set Vs` final fvs_inline_calls[OF `calls es = ⌊(a, M', vs)⌋`, of E] have "fvs (inline_calls E es) ⊆ set Vs" by(auto elim!: final.cases) moreover note CallParams `bisim Vs e e' xs` `fv (e•M(es)) ⊆ set Vs` `¬ contains_insyncs es` final ultimately show ?case by(auto simp add: is_vals_conv final_iff) next case Call with final bisim `bisim Vs e e' xs` show ?case by(auto simp add: is_vals_conv) qed next case (bisimCallParams Vs es es' xs v M) obtain a M' vs where [simp]: "aMvs = (a, M', vs)" by(cases aMvs, auto) with `call (Val v•M(es)) = ⌊aMvs⌋` have "call (Val v•M(es)) = ⌊(a, M', vs)⌋" by simp thus ?case proof(induct rule: call_callE) case CallObj thus ?case by simp next case (CallParams v') with ` [|calls es = ⌊aMvs⌋; fvs es ⊆ set Vs|] ==> bisims Vs (inline_calls E es) (inline_calls E' es') xs` `fv (Val v•M(es)) ⊆ set Vs` have "bisims Vs (inline_calls E es) (inline_calls E' es') xs" by(auto) with final bisim `bisims Vs es es' xs` show ?case by(auto simp add: is_vals_conv) next case Call with final bisim `bisims Vs es es' xs` show ?case by(auto) qed next case (bisimsCons1 Vs e e' xs es) thus ?case by(cases "is_val (inline_call E e)")(fastsimp)+ qed(fastsimp)+ declare hyperUn_ac [simp del] lemma A_inline_call: "call e = ⌊aMvs⌋ ==> \<A> e \<sqsubseteq> \<A> (inline_call e' e)" and As_inline_calls: "calls es = ⌊aMvs⌋ ==> \<A>s es \<sqsubseteq> \<A>s (inline_calls e' es)" proof(induct e and es) case (Call obj M params) obtain a M' vs where [simp]: "aMvs = (a, M', vs)" by(cases aMvs, auto) with `call (obj•M(params)) = ⌊aMvs⌋` have "call (obj•M(params)) = ⌊(a, M', vs)⌋" by simp thus ?case proof(induct rule: call_callE) case CallObj with `call obj = ⌊aMvs⌋ ==> \<A> obj \<sqsubseteq> \<A> (inline_call e' obj)` show ?case by(auto intro: sqUn_lem) next case CallParams with `calls params = ⌊aMvs⌋ ==> \<A>s params \<sqsubseteq> \<A>s (inline_calls e' params)` show ?case by(auto intro: sqUn_lem) next case Call thus ?case by(auto simp add: hyperset_defs) qed next case (Block V ty vo exp) thus ?case by(fastsimp intro: diff_lem) next case throw thus ?case by(simp add: hyperset_defs) next case TryCatch thus ?case by(auto intro: sqInt_lem) qed(fastsimp intro: sqUn_lem sqUn_lem2)+ lemma assumes "\<D> e' ⌊{}⌋" shows defass_inline_call: "[| call e = ⌊aMvs⌋; \<D> e A |] ==> \<D> (inline_call e' e) A" and defasss_inline_calls: "[| calls es = ⌊aMvs⌋; \<D>s es A |] ==> \<D>s (inline_calls e' es) A" proof(induct e and es arbitrary: A and A) case (Call obj M params A) obtain a M' vs where [simp]: "aMvs = (a, M', vs)" by(cases aMvs, auto) with `call (obj•M(params)) = ⌊aMvs⌋` have "call (obj•M(params)) = ⌊(a, M', vs)⌋" by simp thus ?case proof(induct rule: call_callE) case CallObj with `\<D> (obj•M(params)) A` `[|call obj = ⌊aMvs⌋; \<D> obj A|] ==> \<D> (inline_call e' obj) A` have "\<D> (inline_call e' obj) A" by simp moreover from A_inline_call[OF CallObj, of e'] have "A \<squnion> \<A> obj \<sqsubseteq> A \<squnion> \<A> (inline_call e' obj)" by(rule sqUn_lem2) with `\<D> (obj•M(params)) A` have "\<D>s params (A \<squnion> \<A> (inline_call e' obj))" by(auto elim: Ds_mono') ultimately show ?case using CallObj by auto next case (CallParams v) with `\<D> (obj•M(params)) A` `[|calls params = ⌊aMvs⌋; \<D>s params A|] ==> \<D>s (inline_calls e' params) A` have "\<D>s (inline_calls e' params) A" by(simp) with CallParams show ?case by(auto) next case Call with `\<D> e' ⌊{}⌋` show ?case by(auto elim!: D_mono' simp add: hyperset_defs) qed next case (Cons_exp exp exps A) show ?case proof(cases "is_val exp") case True with `\<D>s (exp # exps) A` `[|calls exps = ⌊aMvs⌋; \<D>s exps A|] ==> \<D>s (inline_calls e' exps) A` `calls (exp # exps) = ⌊aMvs⌋` have "\<D>s (inline_calls e' exps) A" by(auto) with True show ?thesis by(auto) next case False with `[|call exp = ⌊aMvs⌋; \<D> exp A|] ==> \<D> (inline_call e' exp) A` `calls (exp # exps) = ⌊aMvs⌋` `\<D>s (exp # exps) A` have "\<D> (inline_call e' exp) A" by auto moreover from False `calls (exp # exps) = ⌊aMvs⌋` have "\<A> exp \<sqsubseteq> \<A> (inline_call e' exp)" by(auto intro: A_inline_call) hence "A \<squnion> \<A> exp \<sqsubseteq> A \<squnion> \<A> (inline_call e' exp)" by(rule sqUn_lem2) with `\<D>s (exp # exps) A` have "\<D>s exps (A \<squnion> \<A> (inline_call e' exp))" by(auto intro: Ds_mono') ultimately show ?thesis using False by(auto) qed qed(fastsimp split: split_if_asm elim: D_mono' intro: sqUn_lem2 sqUn_lem A_inline_call)+ lemma \<B>: "size Vs = n ==> \<B> (compE1 Vs e) n" and \<B>s: "size Vs = n ==> \<B>s (compEs1 Vs es) n" apply(induct e and es arbitrary: Vs n and Vs n) apply auto done lemma bisim_B: "bisim Vs e E xs ==> \<B> E (length Vs)" and bisims_Bs: "bisims Vs es Es xs ==> \<B>s Es (length Vs)" apply(induct rule: bisim_bisims.inducts) apply(auto intro: \<B> \<B>s) done lemma map_upds_xchg_snd: "[| length xs ≤ length ys; length xs ≤ length zs; ∀i. i < length xs --> ys ! i = zs ! i |] ==> f(xs [\<mapsto>] ys) = f(xs [\<mapsto>] zs)" proof(induct xs arbitrary: ys zs f) case Nil thus ?case by simp next case (Cons x xs) note IH = `!!f ys zs. [| length xs ≤ length ys; length xs ≤ length zs; ∀i<length xs. ys ! i = zs ! i|] ==> f(xs [\<mapsto>] ys) = f(xs [\<mapsto>] zs)` note leny = `length (x # xs) ≤ length ys` note lenz = `length (x # xs) ≤ length zs` note nth = `∀i<length (x # xs). ys ! i = zs ! i` from lenz obtain z zs' where zs [simp]: "zs = z # zs'" by(cases zs, auto) from leny obtain y ys' where ys [simp]: "ys = y # ys'" by(cases ys, auto) from lenz leny nth have "(f(x \<mapsto> y))(xs [\<mapsto>] ys') = (f(x \<mapsto> y))(xs [\<mapsto>] zs')" by-(rule IH, auto) moreover from nth have "y = z" by auto ultimately show ?case by(simp add: map_upds_def) qed lemma [simp]: fixes e :: "('a, 'b) exp" and es :: "('a, 'b) exp list" shows IUF_extTA2J1: "IUF e (convert_extTA f ta) e' <-> IUF e ta e'" and IUFs_extTA2J1: "IUFs es (convert_extTA f ta) es' <-> IUFs es ta es'" proof - have "IUF e (convert_extTA f ta) e' ==> IUF e ta e'" and "IUFs es (convert_extTA f ta) es' ==> IUFs es ta es'" proof(induct e ta'≡"convert_extTA f ta" e' and es ta'≡"convert_extTA f ta" es' rule: IUF_IUFs.inducts) case (IUFFail e v a l) from `ε\<lbrace>lUnlockFail->l\<rbrace> = convert_extTA f ta` have "ta = ε\<lbrace>lUnlockFail->l\<rbrace>" by(cases ta) auto with `final e` show ?case by(clarify) qed auto moreover have "IUF e ta e' ==> IUF e (convert_extTA f ta) e'" and "IUFs es ta es' ==> IUFs es (convert_extTA f ta) es'" proof(induct rule: IUF_IUFs.inducts) case (IUFFail e v a l) have eq: "convert_extTA f ε\<lbrace>lUnlockFail->l\<rbrace> = ε\<lbrace>lUnlockFail->l\<rbrace>" by simp from IUFFail show ?case by(subst eq) clarify qed auto ultimately show "IUF e (convert_extTA f ta) e' <-> IUF e ta e'" and "IUFs es (convert_extTA f ta) es' <-> IUFs es ta es'" by blast+ qed lemma sim_move01_into_Red1: "sim_move01 P ta e E' h xs ta' e2' h' xs' ==> if τMove0 P h (e, es1) then τRed1't P h ((E', xs), exs2) ((e2', xs'), exs2) ∧ ta = ε ∧ h = h' else ∃ex2' exs2' ta'. τRed1'r P h ((E', xs), exs2) (ex2', exs2') ∧ P \<turnstile>1 〈ex2'/exs2',h〉 -ta'-> 〈(e2', xs')/exs2,h'〉 ∧ ¬ τMove1 P h (ex2', exs2') ∧ ¬ IUFL ex2' exs2' ta' (e2', xs') exs2 ∧ ta_bisim01 ta ta'" apply(auto simp add: sim_move01_def IUFL_def intro: τred1't_into_τRed1't τred1'r_into_τRed1'r red1Red) apply(rule exI conjI)+ apply(rule τred1'r_into_τRed1'r) apply(fastsimp simp add: IUFL_def intro: red1Red) apply(rule exI conjI)+ apply(auto intro: red1Red) done lemma sim_move01_max_vars_decr: "sim_move01 P ta e0 e h xs ta' e' h' xs' ==> max_vars e' ≤ max_vars e" by(fastsimp simp add: sim_move01_def split: split_if_asm dest: τred1't_max_vars red1_max_vars_decr τred1'r_max_vars) lemma Red1_simulates_red0: assumes wf: "wf_J_prog P" and red: "P \<turnstile>0 〈e1/es1, h〉 -ta-> 〈e1'/es1', h'〉" and bisiml: "bisim_list1 (e1, es1) (ex2, exs2)" shows "∃ex2'' exs2''. bisim_list1 (e1', es1') (ex2'', exs2'') ∧ (if τMove0 P h (e1, es1) then τRed1't (compP1 P) h (ex2, exs2) (ex2'', exs2'') ∧ ta = ε ∧ h = h' else ∃ex2' exs2' ta'. τRed1'r (compP1 P) h (ex2, exs2) (ex2', exs2') ∧ compP1 P \<turnstile>1 〈ex2'/exs2', h〉 -ta'-> 〈ex2''/exs2'', h'〉 ∧ ¬ τMove1 P h (ex2', exs2') ∧ ¬ IUFL ex2' exs2' ta' ex2'' exs2'' ∧ ta_bisim01 ta ta')" (is "∃ex2'' exs2'' . _ ∧ ?red ex2'' exs2''") using red proof(cases) case (red0Red e H TA e' H' XS' es) hence e1: "e1 = e" and e1': "e1' = e'" and [simp]: "H = h" "TA = ta" "es = es1" "H' = h'" "es1' = es1" and red: "extTA2J0 P,P \<turnstile> 〈e,(h, empty)〉 -TA-> 〈e',(h', XS')〉" and notsynth: "∀aMvs. call e = ⌊aMvs⌋ --> synthesized_call P h aMvs" by simp_all from bisiml e1 obtain E xs where ex2: "ex2 = (E, xs)" and bisim: "bisim [] e E xs" and fv: "fv e1 = {}" and length: "max_vars E ≤ length xs" and bsl: "bisim_list es exs2" and D: "\<D> e1 ⌊{}⌋" by(auto elim!: bisim_list1_elim) from bisim_max_vars[OF bisim] length red1_simulates_red_aux[OF wf red bisim] fv e1 notsynth obtain ta' e2' xs' where sim: "sim_move01 (compP1 P) TA e E h xs ta' e2' h' xs'" and bisim': "bisim [] e' e2' xs'" and XS': "XS' ⊆m empty" by auto from sim_move01_into_Red1[OF sim, of es1 exs2] have "?red (e2', xs') exs2" unfolding e1 ex2 by auto moreover { note bsl bisim' moreover from fv e1 red_fv_subset[OF wf_prog_wwf_prog[OF wf] red] have "fv e' = {}" by simp moreover from red D e1 have "\<D> e' ⌊dom XS'⌋" by(auto dest: red_preserves_defass[OF wf] split: split_if_asm) with red_dom_lcl[OF red] `fv e1 = {}` e1 have "\<D> e' ⌊{}⌋" by(auto elim!: D_mono' simp add: hyperset_defs) moreover from sim have "length xs = length xs'" "max_vars e2' ≤ max_vars E" by(auto dest: sim_move01_preserves_len sim_move01_max_vars_decr) with length have length': "max_vars e2' ≤ length xs'" by(auto) ultimately have "bisim_list1 (e1', es) ((e2', xs'), exs2)" unfolding e1' by(rule bisim_list1I) } ultimately show ?thesis using ex2 by(simp split del: split_if)(rule exI conjI|assumption)+ next case (red0Call e a M vs H C fs Ts T pns body D es) hence [simp]: "es1 = es" "H = h" "ta = ε" "h' = h" and es1': "es1' = e # es" and e1: "e1 = e" and e1': "e1' = blocks (this#pns, Class D#Ts, Addr a#vs, body)" and call: "call e = ⌊(a, M, vs)⌋" and ha: "h a = ⌊Obj C fs⌋" and nec: "¬ is_external_call P (Class C) M" and sees: "P \<turnstile> C sees M: Ts->T = (pns, body) in D" and len: "length vs = length pns" "length Ts = length pns" by simp_all from bisiml e1 obtain E xs where ex2: "ex2 = (E, xs)" and bisim: "bisim [] e E xs" and fv: "fv e1 = {}" and length: "max_vars E ≤ length xs" and bsl: "bisim_list es exs2" and D: "\<D> e1 ⌊{}⌋" by(auto elim!: bisim_list1_elim) from bisim_call_Some_call1[OF bisim call, of "compP1 P" h] length obtain e' xs' where red: "τred1'r (compP1 P) h (E, xs) (e', xs')" and "call1 e' = ⌊(a, M, vs)⌋" "bisim [] e e' xs'" and "take 0 xs = take 0 xs'" by auto let ?e1' = "blocks (this#pns, Class D#Ts, Addr a#vs, body)" let ?e2' = "blocks1 0 (Class D#Ts) (compE1 (this # pns) body)" let ?xs2' = "Addr a # vs @ replicate (max_vars (compE1 (this # pns) body)) undefined" let ?exs2' = "(e', xs') # exs2" have "τRed1'r (compP1 P) h ((E, xs), exs2) ((e', xs'), exs2)" using red by(rule τred1'r_into_τRed1'r) moreover { note `call1 e' = ⌊(a, M, vs)⌋` moreover note ha moreover from nec have "¬ is_external_call (compP1 P) (Class C) M" by simp moreover have "compP1 P \<turnstile> C sees M:Ts -> T = (λ(pns, body). compE1 (this # pns) body) (pns, body) in D" using sees unfolding compP1_def by(rule sees_method_compP) hence sees': "compP1 P \<turnstile> C sees M:Ts -> T = compE1 (this # pns) body in D" by simp moreover from len have "length vs = length Ts" by simp ultimately have "compP1 P \<turnstile>1 〈(e', xs')/exs2,h〉 -ε-> 〈(?e2', ?xs2')/?exs2', h〉" by(rule red1Call) moreover have "τMove1 P h ((e', xs'), exs2)" using `call1 e' = ⌊(a, M, vs)⌋` nec ha by(auto simp add: τmove1_not_call1 synthesized_call_def) moreover have "¬ IUFL (e', xs') exs2 ε (?e2', ?xs2') ?exs2'" by(simp add: IUFL_def) ultimately have "τRed1' (compP1 P) h ((e', xs'), exs2) ((?e2', ?xs2'), ?exs2')" by auto } ultimately have "τRed1't (compP1 P) h ((E, xs), exs2) ((?e2', ?xs2'), ?exs2')" by(rule rtranclp_into_tranclp1) moreover from bsl `bisim [] e e' xs'` have "bisim_list (e1 # es) ?exs2'" using fv D unfolding e1 proof(rule bisim_listCons) from red have "length xs' = length xs" by(rule τred1'r_preserves_len) moreover from red have "max_vars e' ≤ max_vars E" by(rule τred1'r_max_vars) ultimately show "max_vars e' ≤ length xs'" using length by simp from `call e = ⌊(a, M, vs)⌋` show "call e = ⌊(a, M, vs)⌋" by simp from `call1 e' = ⌊(a, M, vs)⌋` show "call1 e' = ⌊(a, M, vs)⌋" by simp qed hence "bisim_list1 (e1', es1') ((?e2', ?xs2'), ?exs2')" unfolding e1' es1' e1 proof(rule bisim_list1I) from wf_prog_wwf_prog[OF wf] `P \<turnstile> C sees M: Ts->T = (pns, body) in D` have "wf_mdecl wwf_J_mdecl P D (M,Ts,T,pns,body)" by(rule sees_wf_mdecl) hence fv': "fv body ⊆ set pns ∪ {this}" by(auto simp add: wf_mdecl_def) moreover from `P \<turnstile> C sees M: Ts->T = (pns, body) in D` have "¬ contains_insync body" by(auto dest!: sees_wf_mdecl[OF wf] WT_expr_locks simp add: wf_mdecl_def contains_insync_conv) ultimately have "bisim ([this] @ pns) body (compE1 ([this] @ pns) body) ?xs2'" by -(rule compE1_bisim, auto) with `length vs = length pns` `length Ts = length pns` have "bisim ([] @ [this]) (blocks (pns, Ts, vs, body)) (blocks1 (Suc 0) Ts (compE1 (this # pns) body)) ?xs2'" by -(drule blocks_bisim,auto simp add: nth_append) from bisimBlockSomeNone[OF this, of "Addr a" "Class D"] show "bisim [] ?e1' ?e2' ?xs2'" by simp from fv' len show "fv ?e1' = {}" by auto from wf `P \<turnstile> C sees M: Ts->T = (pns, body) in D` have "wf_mdecl wf_J_mdecl P D (M,Ts,T,pns,body)" by(rule sees_wf_mdecl) hence "\<D> body ⌊set pns ∪ {this}⌋" by(auto simp add: wf_mdecl_def) with `length vs = length pns` `length Ts = length pns` have "\<D> (blocks (pns, Ts, vs, body)) ⌊dom [this \<mapsto> Addr a]⌋" by(auto) thus "\<D> ?e1' ⌊{}⌋" by auto from len show "max_vars ?e2' ≤ length ?xs2'" by(auto simp add: blocks1_max_vars) qed moreover have "τMove0 P h (e1, es1)" using call e1 nec ha by(auto simp add: τmove0_callD synthesized_call_def) ultimately show ?thesis using ex2 `call e = ⌊(a, M, vs)⌋` by(simp del: τMove1.simps)(rule exI conjI|assumption)+ next case (red0Return e' e es H) hence e1: "e1 = e'" and es1: "es1 = e # es" and e1': "e1' = inline_call e' e" and [simp]: "H = h" "ta = ε" "es1' = es" "h' = h" and fin: "final e'" by(simp_all) from bisiml e1 es1 obtain E' xs' E xs exs' aMvs where ex2: "ex2 = (E', xs')" and exs2: "exs2 = (E, xs) # exs'" and bisim': "bisim [] e' E' xs'" and bisim: "bisim [] e E xs" and fv: "fv e = {}" and length: "max_vars E ≤ length xs" and bisiml: "bisim_list es exs'" and D: "\<D> e ⌊{}⌋" and call: "call e = ⌊aMvs⌋" and call1: "call1 E = ⌊aMvs⌋" by(fastsimp elim: bisim_list1_elim) let ?e2' = "inline_call E' E" from `final e'` bisim' have "final E'" by(auto) hence red': "compP1 P \<turnstile>1 〈ex2/exs2, H〉 -ε-> 〈(?e2', xs)/exs', H〉" unfolding ex2 exs2 by(rule red1Return) moreover have "¬ IUFL ex2 exs2 ε (?e2', xs) exs'" using exs2 by(simp add: IUFL_def) moreover have "τMove0 P h (e1, es1) = τMove1 P h ((E', xs'), exs2)" using e1 `final e'` `final E'` by auto moreover { note bisiml moreover from bisim' fin bisim have "bisim [] (inline_call e' e) (inline_call E' E) xs" using call by(rule bisim_inline_call)(simp add: fv) moreover from fv_inline_call[OF call, of e'] fv fin have "fv (inline_call e' e) = {}" by auto moreover from fin have "\<D> e' ⌊{}⌋" by auto hence "\<D> (inline_call e' e) ⌊{}⌋" using call D by(rule defass_inline_call) moreover from `call1 E = ⌊aMvs⌋` have "max_vars ?e2' ≤ max_vars E + max_vars E'" by(rule inline_call_max_vars1) with `final E'` length have "max_vars ?e2' ≤ length xs" by(auto elim!: final.cases) ultimately have "bisim_list1 (inline_call e' e, es) ((?e2', xs), exs')" by(rule bisim_list1I) } ultimately show ?thesis using e1' `final e'` `final E'` e1 ex2 apply(simp del: τMove0.simps τMove1.simps) apply(rule exI conjI impI|assumption)+ apply(rule tranclp.r_into_trancl, simp) apply blast done qed lemma sim_move10_into_red0: assumes wwf: "wwf_J_prog P" and sim: "sim_move10 P ta e2 e2' e h empty ta' e' h' x'" and fv: "fv e = {}" shows "if τmove1 P h e2 then (τRed0t P h (e, es) (e', es) ∨ countInitBlock e2' < countInitBlock e2 ∧ e' = e ∧ x' = empty) ∧ ta = ε ∧ h = h' else ∃e'' ta'. τRed0r P h (e, es) (e'', es) ∧ P \<turnstile>0 〈e''/es,h〉 -ta'-> 〈e'/es,h'〉 ∧ ¬ τMove0 P h (e'', es) ∧ ta_bisim01 ta' (extTA2J1 (compP1 P) ta)" proof(cases "τmove1 P h e2") case True with sim have "¬ final e2" and red: "τred0t (extTA2J0 P) P h (e, empty) (e', x') ∨ countInitBlock e2' < countInitBlock e2 ∧ e' = e ∧ x' = empty" and [simp]: "h' = h" "ta = ε" "ta' = ε" by(simp_all add: sim_move10_def) from red have "τRed0t P h (e, es) (e', es) ∨ countInitBlock e2' < countInitBlock e2 ∧ e' = e ∧ x' = empty" proof assume red: "τred0t (extTA2J0 P) P h (e, empty) (e', x')" from τred0t_fv_subset[OF wwf red] τred0t_dom_lcl[OF wwf red] fv have "dom x' ⊆ {}" by(auto split: split_if_asm) hence "x' = empty" by auto with red have "τred0t (extTA2J0 P) P h (e, empty) (e', empty)" by simp with wwf have "τRed0t P h (e, es) (e', es)" using fv by(rule τred0t_into_τRed0t) thus ?thesis .. qed simp with True show ?thesis by simp next case False with sim obtain e'' xs'' where "¬ final e2" and τred: "τred0r (extTA2J0 P) P h (e, empty) (e'', xs'')" and red: "extTA2J0 P,P \<turnstile> 〈e'',(h, xs'')〉 -ta'-> 〈e',(h', x')〉" and "¬ τmove0 P h e''" "ta_bisim01 ta' (extTA2J1 (compP1 P) ta)" "no_call P h e''" by(auto simp add: sim_move10_def) from τred0r_fv_subset[OF wwf τred] τred0r_dom_lcl[OF wwf τred] fv have "dom xs'' ⊆ {}" by(auto) hence "xs'' = empty" by(auto) with τred have "τred0r (extTA2J0 P) P h (e, empty) (e'', empty)" by simp with wwf have "τRed0r P h (e, es) (e'', es)" using fv by(rule τred0r_into_τRed0r) moreover from red `xs'' = empty` have "extTA2J0 P,P \<turnstile> 〈e'',(h, empty)〉 -ta'-> 〈e',(h', x')〉" by simp from red0Red[OF this] `no_call P h e''` have "P \<turnstile>0 〈e''/es,h〉 -ta'-> 〈e'/es,h'〉" by(simp add: no_call_def) moreover from `¬ τmove0 P h e''` red have "¬ τMove0 P h (e'', es)" by auto ultimately show ?thesis using False `ta_bisim01 ta' (extTA2J1 (compP1 P) ta)` by(simp del: τMove0.simps) blast qed lemma red0_simulates_Red1: assumes wf: "wf_J_prog P" and red: "compP1 P \<turnstile>1 〈ex2/exs2, h〉 -ta-> 〈ex2'/exs2', h'〉" and bisiml: "bisim_list1 (e, es) (ex2, exs2)" and IUFL: "¬ IUFL ex2 exs2 ta ex2' exs2'" shows "∃e' es'. bisim_list1 (e', es') (ex2', exs2') ∧ (if τMove1 P h (ex2, exs2) then (τRed0t P h (e, es) (e', es') ∨ countInitBlock (fst ex2') < countInitBlock (fst ex2) ∧ exs2' = exs2 ∧ e' = e ∧ es' = es) ∧ ta = ε ∧ h = h' else ∃e'' es'' ta'. τRed0r P h (e, es) (e'', es'') ∧ P \<turnstile>0 〈e''/es'', h〉 -ta'-> 〈e'/es', h'〉 ∧ ¬ τMove0 P h (e'', es'') ∧ ta_bisim01 ta' ta)" (is "∃e' es' . _ ∧ ?red e' es'") using red proof(cases) case (red1Red E H xs TA E' H' xs' exs) hence red: "compP1 P \<turnstile>1 〈E,(H, xs)〉 -TA-> 〈E',(H', xs')〉" and ex2: "ex2 = (E, xs)" and ex2': "ex2' = (E', xs')" and [simp]: "ta = extTA2J1 (compP1 P) TA" "h = H" "exs2 = exs" "exs2' = exs" "h' = H'" by simp_all from bisiml ex2 have bisim: "bisim [] e E xs" and fv: "fv e = {}" and length: "max_vars E ≤ length xs" and bsl: "bisim_list es exs" and D: "\<D> e ⌊{}⌋" by(auto elim: bisim_list1_elim) from IUFL ex2 ex2' have IUF: "¬ IUF E TA E'" by(auto simp add: IUFL_def) from red_simulates_red1_aux[OF wf red, simplified, OF bisim, of empty] fv length IUF D obtain TA' e2' x' where red': "sim_move10 P TA E E' e H empty TA' e2' H' x'" and bisim'': "bisim [] e2' E' xs'" and lcl': "x' ⊆m empty" by auto from red have "¬ final E" by auto with sim_move10_into_red0[OF wf_prog_wwf_prog[OF wf] red', of es] fv ex2 ex2' have red'': "?red e2' es" by fastsimp moreover { note bsl bisim'' moreover from red' fv have "fv e2' = {}" by(fastsimp simp add: sim_move10_def split: split_if_asm dest: τred0r_fv_subset[OF wf_prog_wwf_prog[OF wf]] τred0t_fv_subset[OF wf_prog_wwf_prog[OF wf]] red_fv_subset[OF wf_prog_wwf_prog[OF wf]]) moreover from red' have "dom x' ⊆ dom (empty) ∪ fv e" unfolding sim_move10_def apply(auto split: split_if_asm del: subsetI dest: τred0r_dom_lcl[OF wf_prog_wwf_prog[OF wf]] τred0t_dom_lcl[OF wf_prog_wwf_prog[OF wf]]) apply(frule τred0r_fv_subset[OF wf_prog_wwf_prog[OF wf]]) apply(auto dest!: τred0r_dom_lcl[OF wf_prog_wwf_prog[OF wf]] red_dom_lcl del: subsetI, blast)[1] done with fv have "dom x' ⊆ {}" by(auto) hence "x' = empty" by(auto) with D red' have "\<D> e2' ⌊{}⌋" by(auto dest!: sim_move10_preserves_defass[OF wf] split: split_if_asm) moreover from red have "length xs' = length xs" by(auto dest: red1_preserves_len) with red1_max_vars[OF red] length have "max_vars E' ≤ length xs'" by simp ultimately have "bisim_list1 (e2', es) ((E', xs'), exs)" by(rule bisim_list1I) } ultimately show ?thesis using ex2' by(clarsimp split: split_if_asm)(rule exI conjI|assumption|simp)+ next case (red1Call E a M vs H C fs Ts T body D xs exs) hence [simp]: "ex2 = (E, xs)" "exs2 = exs" "h = H" "ta = ε" "h' = H" and ex2': "ex2' = (blocks1 0 (Class D#Ts) body, Addr a # vs @ replicate (max_vars body) undefined)" and exs': "exs2' = (E, xs) # exs" and call: "call1 E = ⌊(a, M, vs)⌋" and ha: "H a = ⌊Obj C fs⌋" and nec: "¬ is_external_call (compP1 P) (Class C) M" and sees: "compP1 P \<turnstile> C sees M: Ts->T = body in D" and len: "length vs = length Ts" by simp_all let ?e2' = "blocks1 0 (Class D#Ts) body" let ?xs2' = "Addr a # vs @ replicate (max_vars body) undefined" from bisiml have bisim: "bisim [] e E xs" and fv: "fv e = {}" and length: "max_vars E ≤ length xs" and bsl: "bisim_list es exs" and D: "\<D> e ⌊{}⌋" by(auto elim: bisim_list1_elim) from bisim `call1 E = ⌊(a, M, vs)⌋` have "call e = ⌊(a, M, vs)⌋" by(rule bisim_call1_Some_call) moreover note ha moreover from `¬ is_external_call (compP1 P) (Class C) M` have "¬ is_external_call P (Class C) M" by simp moreover from `compP1 P \<turnstile> C sees M: Ts->T = body in D` obtain pns Jbody where sees': "P \<turnstile> C sees M: Ts->T = (pns, Jbody) in D" and body: "body = compE1 (this # pns) Jbody" by(auto dest: sees_method_compPD) let ?e' = "blocks(this#pns, Class D#Ts, Addr a#vs, Jbody)" note sees' moreover from wf sees' have "length Ts = length pns" by(auto dest!: sees_wf_mdecl simp add: wf_mdecl_def) with len have "length vs = length pns" "length Ts = length pns" by simp_all ultimately have red': "P \<turnstile>0 〈e/es, H〉 -ε-> 〈?e'/e#es, H〉" by(rule red0Call) moreover from `call e = ⌊(a, M, vs)⌋` ha `¬ is_external_call P (Class C) M` have "τMove0 P h (e, es)" by(auto simp add: τmove0_callD synthesized_call_def) ultimately have "τRed0t P H (e, es) (?e', e#es)" by auto moreover from bsl bisim fv D length `call e = ⌊(a, M, vs)⌋` `call1 E = ⌊(a, M, vs)⌋` have "bisim_list (e # es) ((E, xs) # exs)" by(rule bisim_list.intros) hence "bisim_list1 (?e', e # es) (ex2', (E, xs) # exs)" unfolding ex2' proof(rule bisim_list1I) from wf_prog_wwf_prog[OF wf] sees' have "wf_mdecl wwf_J_mdecl P D (M,Ts,T,pns,Jbody)" by(rule sees_wf_mdecl) hence "fv Jbody ⊆ set pns ∪ {this}" by(auto simp add: wf_mdecl_def) moreover from sees' have "¬ contains_insync Jbody" by(auto dest!: sees_wf_mdecl[OF wf] WT_expr_locks simp add: wf_mdecl_def contains_insync_conv) ultimately have "bisim ([] @ this # pns) Jbody (compE1 ([] @ this # pns) Jbody) ?xs2'" by -(rule compE1_bisim, auto) with `length vs = length Ts` `length Ts = length pns` body have "bisim [] (blocks (this # pns, Class D # Ts, Addr a # vs, Jbody)) (blocks1 (length ([] :: vname list)) (Class D # Ts) body) ?xs2'" by -(rule blocks_bisim, auto simp add: nth_append nth_Cons') thus "bisim [] ?e' ?e2' ?xs2'" by simp from `length vs = length Ts` `length Ts = length pns` `fv Jbody ⊆ set pns ∪ {this}` show "fv ?e' = {}" by auto from wf sees' have "wf_mdecl wf_J_mdecl P D (M,Ts,T,pns,Jbody)" by(rule sees_wf_mdecl) hence "\<D> Jbody ⌊set pns ∪ {this}⌋" by(auto simp add: wf_mdecl_def) with `length vs = length Ts` `length Ts = length pns` have "\<D> (blocks (pns, Ts, vs, Jbody)) ⌊dom [this \<mapsto> Addr a]⌋" by(auto) thus "\<D> ?e' ⌊{}⌋" by simp from len show "max_vars ?e2' ≤ length ?xs2'" by(simp add: blocks1_max_vars) qed moreover have "τMove1 P h (ex2, exs2)" using ha `call1 E = ⌊(a, M, vs)⌋` `¬ is_external_call (compP1 P) (Class C) M` by(auto simp add: τmove1_not_call1 synthesized_call_def) ultimately show ?thesis using exs' by(simp del: τMove1.simps τMove0.simps)(rule exI conjI rtranclp.rtrancl_refl|assumption)+ next case (red1Return E' x' E x exs H) hence [simp]: "h = H" "ta = ε" "exs2' = exs" "h' = H" and ex2: "ex2 = (E', x')" and exs2: "exs2 = (E, x) # exs" and ex2': "ex2' = (inline_call E' E, x)" and fin: "final E'" by simp_all from bisiml ex2 exs2 obtain e' es' aMvs where es: "es = e' # es'" and bsl: "bisim_list es' exs" and bisim: "bisim [] e E' x'" and bisim': "bisim [] e' E x" and fv: "fv e' = {}" and length: "max_vars E ≤ length x" and D: "\<D> e' ⌊{}⌋" and call: "call e' = ⌊aMvs⌋" and call1: "call1 E = ⌊aMvs⌋" by(fastsimp elim!: bisim_list1_elim) from `final E'` bisim have fin': "final e" by(auto) hence "P \<turnstile>0 〈e/e' # es',H〉 -ε-> 〈inline_call e e'/es',H〉" by(rule red0Return) moreover from bisim fin' bisim' call have "bisim [] (inline_call e e') (inline_call E' E) x" by(rule bisim_inline_call)(simp add: fv) with bsl have "bisim_list1 (inline_call e e', es') (ex2', exs)" unfolding ex2' proof(rule bisim_list1I) from fin' fv_inline_call[OF call, of e] fv show "fv (inline_call e e') = {}" by auto from fin' have "\<D> e ⌊{}⌋" by auto thus "\<D> (inline_call e e') ⌊{}⌋" using call D by(rule defass_inline_call) from call1_imp_call[OF call1] have "max_vars (inline_call E' E) ≤ max_vars E + max_vars E'" by(rule inline_call_max_vars) with fin length show "max_vars (inline_call E' E) ≤ length x" by(auto elim!: final.cases) qed moreover have "τMove1 P h (ex2, exs2) = τMove0 P h (e, es)" using ex2 call1 call fin fin' by(auto) ultimately show ?thesis using es by(simp del: τMove1.simps τMove0.simps) blast qed lemma bisim_expr_locks_eq: "bisim Vs e e' xs ==> expr_locks e = expr_locks e'" and bisims_expr_lockss_eq: "bisims Vs es es' xs ==> expr_lockss es = expr_lockss es'" by(induct rule: bisim_bisims.inducts)(auto intro!: ext) lemma bisim_list_expr_lockss_eq: "bisim_list es exs' ==> expr_lockss es = expr_lockss (map fst exs')" apply(induct rule: bisim_list.induct) apply(auto dest: bisim_expr_locks_eq) done interpretation red0_Red1_FWwbase: FWdelay_bisimulation_base final_expr0 "mred0 P" final_expr1 "mred1 (compP1 P)" "bisim_red0_Red1" "τMOVE0 P" "τMOVE1 (compP1 P)" for P . lemma τRed1't_into_Red1'_τmthr_silent_movet: "τRed1't P h (ex2, exs2) (ex2'', exs2'') ==> Red1'_τmthr.silent_movet P ((ex2, exs2), h) ((ex2'', exs2''), h)" apply(induct rule: tranclp_induct2) apply clarsimp apply(rule tranclp.r_into_trancl) apply(simp add: Red1'_τmthr.silent_move_iff) apply(erule tranclp.trancl_into_trancl) apply(simp add: Red1'_τmthr.silent_move_iff) done lemmas τRed1't_into_Red1'_τmthr_silent_moves = tranclp_into_rtranclp[OF τRed1't_into_Red1'_τmthr_silent_movet] lemma τRed0r_into_red0_τmthr_silent_moves: "τRed0r P h (e, es) (e'', es'') ==> red0_τmthr.silent_moves P ((e, es), h) ((e'', es''), h)" apply(induct rule: rtranclp_induct2) apply blast apply(erule rtranclp.rtrancl_into_rtrancl) apply(simp add: red0_τmthr.silent_move_iff) done lemma τRed0t_into_red0_τmthr_silent_movet: "τRed0t P h (e, es) (e'', es'') ==> red0_τmthr.silent_movet P ((e, es), h) ((e'', es''), h)" apply(induct rule: tranclp_induct2) apply(fastsimp simp add: red0_τmthr.silent_move_iff elim: tranclp.trancl_into_trancl)+ done lemma τRed1'r_into_Red1'_τmthr_silent_moves: "τRed1'r P h (ex, exs) (ex', exs') ==> Red1'_τmthr.silent_moves P ((ex, exs), h) ((ex', exs'), h)" apply(induct rule: rtranclp_induct2) apply blast apply(erule rtranclp.rtrancl_into_rtrancl) apply(simp add: Red1'_τmthr.silent_move_iff) done lemma delay_bisimulation_red0_Red1: assumes wf: "wf_J_prog P" shows "delay_bisimulation_measure (mred0 P) (mred1' (compP1 P)) bisim_red0_Red1 (ta_bisim bisim_red0_Red1) (τMOVE0 P) (τMOVE1 (compP1 P)) (λes es'. False) (λ(((e', xs'), exs'), h') (((e, xs), exs), h). countInitBlock e'< countInitBlock e)" (is "delay_bisimulation_measure _ _ _ _ _ _ ?μ1 ?μ2") proof(unfold_locales) fix s1 s2 s1' assume "bisim_red0_Red1 s1 s2" "red0_τmthr.silent_move P s1 s1'" moreover obtain ex1 exs1 h1 where s1: "s1 = ((ex1, exs1), h1)" by(cases s1, auto) moreover obtain ex1' exs1' h1' where s1': "s1' = ((ex1', exs1'), h1')" by(cases s1', auto) moreover obtain ex2 exs2 h2 where s2: "s2 = ((ex2, exs2), h2)" by(cases s2, auto) ultimately have bisim: "bisim_list1 (ex1, exs1) (ex2, exs2)" and heap: "h1 = h2" and red: "P \<turnstile>0 〈ex1/exs1,h1〉 -ε-> 〈ex1'/exs1',h1'〉" and τ: "τMove0 P h1 (ex1, exs1)" by(auto simp add: bisim_red0_Red1_def red0_τmthr.silent_move_iff) from Red1_simulates_red0[OF wf red bisim] τ obtain ex2'' exs2'' where bisim': "bisim_list1 (ex1', exs1') (ex2'', exs2'')" and red': "τRed1't (compP1 P) h1 (ex2, exs2) (ex2'', exs2'')" and [simp]: "h1' = h1" by auto from τRed1't_into_Red1'_τmthr_silent_movet[OF red'] bisim' heap have "∃s2'. Red1'_τmthr.silent_movet (compP1 P) s2 s2' ∧ bisim_red0_Red1 s1' s2'" unfolding s2 s1' by(auto simp add: bisim_red0_Red1_def) thus "bisim_red0_Red1 s1' s2 ∧ ?μ1^++ s1' s1 ∨ (∃s2'. Red1'_τmthr.silent_movet (compP1 P) s2 s2' ∧ bisim_red0_Red1 s1' s2')" .. next fix s1 s2 s2' assume "bisim_red0_Red1 s1 s2" "Red1'_τmthr.silent_move (compP1 P) s2 s2'" moreover obtain ex1 exs1 h1 where s1: "s1 = ((ex1, exs1), h1)" by(cases s1, auto) moreover obtain ex2 exs2 h2 where s2: "s2 = ((ex2, exs2), h2)" by(cases s2, auto) moreover obtain ex2' exs2' h2' where s2': "s2' = ((ex2', exs2'), h2')" by(cases s2', auto) ultimately have bisim: "bisim_list1 (ex1, exs1) (ex2, exs2)" and heap: "h1 = h2" and red: "compP1 P \<turnstile>1 〈ex2/exs2,h2〉 -ε-> 〈ex2'/exs2',h2'〉" and τ: "τMove1 P h2 (ex2, exs2)" and IUF: "¬ IUFL ex2 exs2 (ε:: J1_thread_action) ex2' exs2'" by(fastsimp simp add: bisim_red0_Red1_def Red1'_τmthr.silent_move_iff)+ from red0_simulates_Red1[OF wf red bisim IUF] τ obtain e' es' where bisim': "bisim_list1 (e', es') (ex2', exs2')" and red': "τRed0t P h2 (ex1, exs1) (e', es') ∨ countInitBlock (fst ex2') < countInitBlock (fst ex2) ∧ exs2' = exs2 ∧ e' = ex1 ∧ es' = exs1" and [simp]: "h2' = h2" by auto from red' show "bisim_red0_Red1 s1 s2' ∧ ?μ2^++ s2' s2 ∨ (∃s1'. red0_τmthr.silent_movet P s1 s1' ∧ bisim_red0_Red1 s1' s2')" (is "?refl ∨ ?step") proof assume "τRed0t P h2 (ex1, exs1) (e', es')" from τRed0t_into_red0_τmthr_silent_movet[OF this] bisim' heap have ?step unfolding s1 s2' by(auto simp add: bisim_red0_Red1_def) thus ?thesis .. next assume "countInitBlock (fst ex2') < countInitBlock (fst ex2) ∧ exs2' = exs2 ∧ e' = ex1 ∧ es' = exs1" hence ?refl using bisim' heap unfolding s1 s2' s2 by (auto simp add: bisim_red0_Red1_def split_beta) thus ?thesis .. qed next fix s1 s2 ta1 s1' assume "bisim_red0_Red1 s1 s2" and "mred0 P s1 ta1 s1'" and τ: "¬ τMOVE0 P s1 ta1 s1'" moreover obtain ex1 exs1 h1 where s1: "s1 = ((ex1, exs1), h1)" by(cases s1, auto) moreover obtain ex1' exs1' h1' where s1': "s1' = ((ex1', exs1'), h1')" by(cases s1', auto) moreover obtain ex2 exs2 h2 where s2: "s2 = ((ex2, exs2), h2)" by(cases s2, auto) ultimately have heap: "h2 = h1" and bisim: "bisim_list1 (ex1, exs1) (ex2, exs2)" and red: "P \<turnstile>0 〈ex1/exs1,h1〉 -ta1-> 〈ex1'/exs1',h1'〉" by(auto simp add: bisim_red0_Red1_def) from τ have "¬ τMove0 P h1 (ex1, exs1)" unfolding s1 using red by(auto elim!: red0.cases dest: red_τ_taD) with Red1_simulates_red0[OF wf red bisim] obtain ex2'' exs2'' ex2' exs2' ta' where bisim': "bisim_list1 (ex1', exs1') (ex2'', exs2'')" and red': "τRed1'r (compP1 P) h1 (ex2, exs2) (ex2', exs2')" and red'': "compP1 P \<turnstile>1 〈ex2'/exs2',h1〉 -ta'-> 〈ex2''/exs2'',h1'〉" and τ': "¬ τMove1 P h1 (ex2', exs2')" and IUF: "¬ IUFL ex2' exs2' ta' ex2'' exs2''" and ta: "ta_bisim01 ta1 ta'" by auto from red'' IUF have "mred1' (compP1 P) ((ex2', exs2'), h1) ta' ((ex2'', exs2''), h1')" by auto moreover from τ' have "¬ τMOVE1 (compP1 P) ((ex2', exs2'), h1) ta' ((ex2'', exs2''), h1')" by simp moreover from red' have "Red1'_τmthr.silent_moves (compP1 P) s2 ((ex2', exs2'), h1)" unfolding s2 heap by(rule τRed1'r_into_Red1'_τmthr_silent_moves) moreover from bisim' have "bisim_red0_Red1 ((ex1', exs1'), h1') ((ex2'', exs2''), h1')" by(auto simp add: bisim_red0_Red1_def) ultimately show "∃s2' s2'' ta2. Red1'_τmthr.silent_moves (compP1 P) s2 s2' ∧ mred1' (compP1 P) s2' ta2 s2'' ∧ ¬ τMOVE1 (compP1 P) s2' ta2 s2'' ∧ bisim_red0_Red1 s1' s2'' ∧ ta_bisim01 ta1 ta2" using ta unfolding s1' by blast next fix s1 s2 ta2 s2' assume "bisim_red0_Red1 s1 s2" and "mred1' (compP1 P) s2 ta2 s2'" and τ: "¬ τMOVE1 (compP1 P) s2 ta2 s2'" moreover obtain ex1 exs1 h1 where s1: "s1 = ((ex1, exs1), h1)" by(cases s1, auto) moreover obtain ex2 exs2 h2 where s2: "s2 = ((ex2, exs2), h2)" by(cases s2, auto) moreover obtain ex2' exs2' h2' where s2': "s2' = ((ex2', exs2'), h2')" by(cases s2', auto) ultimately have heap: "h2 = h1" and bisim: "bisim_list1 (ex1, exs1) (ex2, exs2)" and red: "compP1 P \<turnstile>1 〈ex2/exs2,h1〉 -ta2-> 〈ex2'/exs2',h2'〉" and IUF: "¬ IUFL ex2 exs2 ta2 ex2' exs2'" by(auto simp add: bisim_red0_Red1_def) from τ heap have "¬ τMove1 P h2 (ex2, exs2)" unfolding s2 using red by(fastsimp elim!: Red1.cases dest: red1_τ_taD) with red0_simulates_Red1[OF wf red bisim IUF] obtain e' es' e'' es'' ta' where bisim': "bisim_list1 (e', es') (ex2', exs2')" and red': "τRed0r P h1 (ex1, exs1) (e'', es'')" and red'': "P \<turnstile>0 〈e''/es'',h1〉 -ta'-> 〈e'/es',h2'〉" and τ': "¬ τMove0 P h1 (e'', es'')" and ta: "ta_bisim01 ta' ta2" using heap by auto from red'' have "mred0 P ((e'', es''), h1) ta' ((e', es'), h2')" by auto moreover from red' have "red0_τmthr.silent_moves P ((ex1, exs1), h1) ((e'', es''), h1)" by(rule τRed0r_into_red0_τmthr_silent_moves) moreover from τ' have "¬ τMOVE0 P ((e'', es''), h1) ta' ((e', es'), h2')" by simp moreover from bisim' have "bisim_red0_Red1 ((e', es'), h2') ((ex2', exs2'), h2')" by(auto simp add: bisim_red0_Red1_def) ultimately show "∃s1' s1'' ta1. red0_τmthr.silent_moves P s1 s1' ∧ mred0 P s1' ta1 s1'' ∧ ¬ τMOVE0 P s1' ta1 s1'' ∧ bisim_red0_Red1 s1'' s2' ∧ ta_bisim01 ta1 ta2" using ta unfolding s1 s2' by blast next show "wfP ?μ1" by auto next have "wf (measure countInitBlock)" .. hence "wf (inv_image (measure countInitBlock) (λ(((e', xs'), exs'), h'). e'))" .. also have "inv_image (measure countInitBlock) (λ(((e', xs'), exs'), h'). e') = {(s2', s2). ?μ2 s2' s2}" by(simp add: inv_image_def split_beta) finally show "wfP ?μ2" by(simp add: wfP_def) qed subsection{*Preservation of well-formedness*} text{* The compiler preserves well-formedness. Is less trivial than it may appear. We start with two simple properties: preservation of well-typedness *} lemma length_compEs2 [simp]: "length (compEs1 Vs es) = length es" by(induct es) simp_all lemma assumes wf: "wf_prog wfmd P" shows compE1_pres_wt: "[| P,[Vs[\<mapsto>]Ts] \<turnstile> e :: U; size Ts = size Vs |] ==> compP f P,Ts \<turnstile>1 compE1 Vs e :: U" and compEs1_pres_wt: "[| P,[Vs[\<mapsto>]Ts] \<turnstile> es [::] Us; size Ts = size Vs |] ==> compP f P,Ts \<turnstile>1 compEs1 Vs es [::] Us" proof(induct e and es arbitrary: Vs Ts U and Vs Ts Us) case Var thus ?case by(fastsimp simp:map_upds_apply_eq_Some split:split_if_asm) next case LAss thus ?case by(fastsimp simp:map_upds_apply_eq_Some split:split_if_asm) next case Call thus ?case by(fastsimp dest: sees_method_compP[where f = f]) next case Block thus ?case by(fastsimp simp:nth_append) next case (Synchronized V exp1 exp2 Vs Ts U) note IH1 = `!!Vs Ts U. [|P,[Vs [\<mapsto>] Ts] \<turnstile> exp1 :: U; length Ts = length Vs|] ==> compP f P,Ts \<turnstile>1 compE1 Vs exp1 :: U` note IH2 = `!!Vs Ts U. [|P,[Vs [\<mapsto>] Ts] \<turnstile> exp2 :: U; length Ts = length Vs|] ==> compP f P,Ts \<turnstile>1 compE1 Vs exp2 :: U` note length = `length Ts = length Vs` from `P,[Vs [\<mapsto>] Ts] \<turnstile> syncV (exp1) exp2 :: U` obtain U1 where wt1: "P,[Vs [\<mapsto>] Ts] \<turnstile> exp1 :: U1" and wt2: "P,[Vs [\<mapsto>] Ts] \<turnstile> exp2 :: U" and U1: "is_refT U1" "U1 ≠ NT" by(auto) from IH1[of Vs Ts U1] wt1 length have wt1': "compP f P,Ts \<turnstile>1 compE1 Vs exp1 :: U1" by simp from length fresh_var_fresh[of Vs] have "[Vs [\<mapsto>] Ts] ⊆m [Vs @ [fresh_var Vs] [\<mapsto>] Ts @ [Class Object]]" by(auto simp add: map_le_def fun_upd_def) with wt2 have "P,[Vs@[fresh_var Vs] [\<mapsto>] Ts @ [Class Object]] \<turnstile> exp2 :: U" by(rule wt_env_mono) with length IH2[of "Vs@[fresh_var Vs]" "Ts @ [Class Object]" U] have "compP f P,Ts @ [Class Object] \<turnstile>1 compE1 (Vs @ [fresh_var Vs]) exp2 :: U" by simp with wt1' U1 show ?case by(auto) next case (TryCatch exp1 C V exp2) note IH1 = `!!Vs Ts U. [|P,[Vs [\<mapsto>] Ts] \<turnstile> exp1 :: U; length Ts = length Vs|] ==> compP f P,Ts \<turnstile>1 compE1 Vs exp1 :: U` note IH2 = `!!Vs Ts U. [|P,[Vs [\<mapsto>] Ts] \<turnstile> exp2 :: U; length Ts = length Vs|] ==> compP f P,Ts \<turnstile>1 compE1 Vs exp2 :: U` note length = `length Ts = length Vs` with `P,[Vs [\<mapsto>] Ts] \<turnstile> try exp1 catch(C V) exp2 :: U` have wt1: "P,[Vs [\<mapsto>] Ts] \<turnstile> exp1 :: U" and wt2: "P,[(Vs@[V]) [\<mapsto>] (Ts@[Class C])] \<turnstile> exp2 :: U" and C: "P \<turnstile> C \<preceq>* Throwable" by(auto simp add: nth_append) from wf have "is_class P Throwable" by(auto simp add: wf_prog_def wf_syscls_def is_class_def class_def map_of_SomeI) with C have "is_class P C" by(rule subcls_is_class1) with IH1[OF wt1 length] IH2[OF wt2] length show ?case by(auto) qed(fastsimp)+ text{*\noindent and the correct block numbering: *} text{* The main complication is preservation of definite assignment @{term"\<D>"}. *} lemma image_index: "A ⊆ set(xs@[x]) ==> index (xs @ [x]) ` A = (if x ∈ A then insert (size xs) (index xs ` (A-{x})) else index xs ` A)" (*<*) apply(auto simp:image_def) apply(rule bexI) prefer 2 apply blast apply simp apply(rule ccontr) apply(erule_tac x=xa in ballE) prefer 2 apply blast apply(fastsimp simp add:neq_commute) apply(subgoal_tac "x ≠ xa") prefer 2 apply blast apply(fastsimp simp add:neq_commute) apply(subgoal_tac "x ≠ xa") prefer 2 apply blast apply(force) done (*>*) lemma A_compE1_None[simp]: "\<A> e = None ==> \<A> (compE1 Vs e) = None" and As_compEs1_None: "\<A>s es = None ==> \<A>s (compEs1 Vs es) = None" apply(induct e and es arbitrary: Vs and Vs) apply(auto simp:hyperset_defs) done lemma A_compE1: "[| \<A> e = ⌊A⌋; fv e ⊆ set Vs |] ==> \<A> (compE1 Vs e) = ⌊index Vs ` A⌋" and As_compEs1: "[| \<A>s es = ⌊A⌋; fvs es ⊆ set Vs |] ==> \<A>s (compEs1 Vs es) = ⌊index Vs ` A⌋" proof(induct e and es arbitrary: A Vs and A Vs) case (Block V' T vo e) hence "fv e ⊆ set (Vs@[V'])" by fastsimp moreover obtain B where "\<A> e = ⌊B⌋" using Block.prems by(simp add: hyperset_defs) moreover from calculation have "B ⊆ set (Vs@[V'])" by(auto dest!:A_fv) ultimately show ?case using Block by(auto simp add: hyperset_defs image_index) next case (Synchronized V exp1 exp2 A Vs) have IH1: "!!A Vs. [|\<A> exp1 = ⌊A⌋; fv exp1 ⊆ set Vs|] ==> \<A> (compE1 Vs exp1) = ⌊index Vs ` A⌋" by fact have IH2: "!!A Vs. [|\<A> exp2 = ⌊A⌋; fv exp2 ⊆ set Vs|] ==> \<A> (compE1 Vs exp2) = ⌊index Vs ` A⌋" by fact from `fv (syncV (exp1) exp2) ⊆ set Vs` have fv1: "fv exp1 ⊆ set Vs" and fv2: "fv exp2 ⊆ set Vs" by auto from `\<A> (syncV (exp1) exp2) = ⌊A⌋` have A: "\<A> exp1 \<squnion> \<A> exp2 = ⌊A⌋" by(simp) then obtain A1 A2 where A1: "\<A> exp1 = ⌊A1⌋" and A2: "\<A> exp2 = ⌊A2⌋" by(auto simp add: hyperset_defs) from A2 fv2 have "A2 ⊆ set Vs" by(auto dest: A_fv del: subsetI) with fresh_var_fresh[of Vs] have "(fresh_var Vs) ∉ A2" by(auto) from fv2 have "fv exp2 ⊆ set (Vs @ [fresh_var Vs])" by auto with IH2[OF A2, of "Vs @ [fresh_var Vs]"] have "\<A> (compE1 (Vs @ [fresh_var Vs]) exp2) = ⌊index (Vs @ [fresh_var Vs]) ` A2⌋" by(auto) with IH1[OF A1 fv1] A[symmetric] `A2 ⊆ set Vs` `(fresh_var Vs) ∉ A2` A1 A2 show ?case by(auto simp add: image_index) next case (InSynchronized V a exp A Vs) have IH: "!!A Vs. [|\<A> exp = ⌊A⌋; fv exp ⊆ set Vs|] ==> \<A> (compE1 Vs exp) = ⌊index Vs ` A⌋" by fact from `\<A> (insyncV (a) exp) = ⌊A⌋` have A: "\<A> exp = ⌊A⌋" by simp from `fv (insyncV (a) exp) ⊆ set Vs` have fv: "fv exp ⊆ set Vs" by simp from A fv have "A ⊆ set Vs" by(auto dest: A_fv del: subsetI) with fresh_var_fresh[of Vs] have "(fresh_var Vs) ∉ A" by(auto) from fv IH[OF A, of "Vs @ [fresh_var Vs]"] have " \<A> (compE1 (Vs @ [fresh_var Vs]) exp) = ⌊index (Vs @ [fresh_var Vs]) ` A⌋" by simp with `A ⊆ set Vs` `(fresh_var Vs) ∉ A` show ?case by(simp add: image_index) next case (TryCatch e1 C V' e2) hence fve2: "fv e2 ⊆ set (Vs@[V'])" by auto show ?case proof (cases "\<A> e1") assume A1: "\<A> e1 = None" then obtain A2 where A2: "\<A> e2 = ⌊A2⌋" using TryCatch by(simp add:hyperset_defs) hence "A2 ⊆ set (Vs@[V'])" using TryCatch.prems A_fv[OF A2] by simp blast thus ?thesis using TryCatch fve2 A1 A2 by(auto simp add:hyperset_defs image_index) next fix A1 assume A1: "\<A> e1 = ⌊A1⌋" show ?thesis proof (cases "\<A> e2") assume A2: "\<A> e2 = None" then show ?case using TryCatch A1 by(simp add:hyperset_defs) next fix A2 assume A2: "\<A> e2 = ⌊A2⌋" have "A1 ⊆ set Vs" using TryCatch.prems A_fv[OF A1] by simp blast moreover have "A2 ⊆ set (Vs@[V'])" using TryCatch.prems A_fv[OF A2] by simp blast ultimately show ?thesis using TryCatch A1 A2 by(fastsimp simp add: hyperset_defs image_index Diff_subset_conv inj_on_image_Int[OF inj_on_index]) qed qed next case (Cond e e1 e2) { assume "\<A> e = None ∨ \<A> e1 = None ∨ \<A> e2 = None" hence ?case using Cond by(auto simp add:hyperset_defs image_Un) } moreover { fix A A1 A2 assume "\<A> e = ⌊A⌋" and A1: "\<A> e1 = ⌊A1⌋" and A2: "\<A> e2 = ⌊A2⌋" moreover have "A1 ⊆ set Vs" using Cond.prems A_fv[OF A1] by simp blast moreover have "A2 ⊆ set Vs" using Cond.prems A_fv[OF A2] by simp blast ultimately have ?case using Cond by(auto simp add:hyperset_defs image_Un inj_on_image_Int[OF inj_on_index]) } ultimately show ?case by fastsimp qed (auto simp add:hyperset_defs) lemma fixes e :: "('a,'b) exp" and es :: "('a,'b) exp list" shows D_None [iff]: "\<D> e None" and Ds_None [iff]: "\<D>s es None" by(induct e and es)(simp_all) lemma D_index_compE1: "[| A ⊆ set Vs; fv e ⊆ set Vs |] ==> \<D> e ⌊A⌋ ==> \<D> (compE1 Vs e) ⌊index Vs ` A⌋" and Ds_index_compEs1: "[| A ⊆ set Vs; fvs es ⊆ set Vs |] ==> \<D>s es ⌊A⌋ ==> \<D>s (compEs1 Vs es) ⌊index Vs ` A⌋" proof(induct e and es arbitrary: A Vs and A Vs) case (BinOp e1 bop e2) hence IH1: "\<D> (compE1 Vs e1) ⌊index Vs ` A⌋" by simp show ?case proof (cases "\<A> e1") case None thus ?thesis using BinOp by simp next case (Some A1) have indexA1: "\<A> (compE1 Vs e1) = ⌊index Vs ` A1⌋" using A_compE1[OF Some] BinOp.prems by auto have "A ∪ A1 ⊆ set Vs" using BinOp.prems A_fv[OF Some] by auto hence "\<D> (compE1 Vs e2) ⌊index Vs ` (A ∪ A1)⌋" using BinOp Some by auto hence "\<D> (compE1 Vs e2) ⌊index Vs ` A ∪ index Vs ` A1⌋" by(simp add: image_Un) thus ?thesis using IH1 indexA1 by auto qed next case (AAcc a i A Vs) have IH1: "!!A Vs. [|A ⊆ set Vs; fv a ⊆ set Vs; \<D> a ⌊A⌋|] ==> \<D> (compE1 Vs a) ⌊index Vs ` A⌋" by fact have IH2: "!!A Vs. [|A ⊆ set Vs; fv i ⊆ set Vs; \<D> i ⌊A⌋|] ==> \<D> (compE1 Vs i) ⌊index Vs ` A⌋" by fact from `\<D> (a⌊i⌉) ⌊A⌋` have D1: "\<D> a ⌊A⌋" and D2: "\<D> i (⌊A⌋ \<squnion> \<A> a)" by auto from `fv (a⌊i⌉) ⊆ set Vs` have fv1: "fv a ⊆ set Vs" and fv2: "fv i ⊆ set Vs" by auto show ?case proof(cases "\<A> a") case None thus ?thesis using AAcc by simp next case (Some A1) with fv1 have "\<A> (compE1 Vs a) = ⌊index Vs ` A1⌋" by-(rule A_compE1) moreover from A_fv[OF Some] fv1 `A ⊆ set Vs` have "A ∪ A1 ⊆ set Vs" by auto from IH2[OF this fv2] Some D2 have "\<D> (compE1 Vs i) ⌊index Vs ` A ∪ index Vs ` A1⌋" by(simp add: image_Un) ultimately show ?thesis using IH1[OF `A ⊆ set Vs` fv1 D1] by(simp) qed next case (AAss a i e A Vs) have IH1: "!!A Vs. [|A ⊆ set Vs; fv a ⊆ set Vs; \<D> a ⌊A⌋|] ==> \<D> (compE1 Vs a) ⌊index Vs ` A⌋" by fact have IH2: "!!A Vs. [|A ⊆ set Vs; fv i ⊆ set Vs; \<D> i ⌊A⌋|] ==> \<D> (compE1 Vs i) ⌊index Vs ` A⌋" by fact have IH3: "!!A Vs. [|A ⊆ set Vs; fv e ⊆ set Vs; \<D> e ⌊A⌋|] ==> \<D> (compE1 Vs e) ⌊index Vs ` A⌋" by fact from `\<D> (a⌊i⌉:=e) ⌊A⌋` have D1: "\<D> a ⌊A⌋" and D2: "\<D> i (⌊A⌋ \<squnion> \<A> a)" and D3: "\<D> e (⌊A⌋ \<squnion> \<A> a \<squnion> \<A> i)" by auto from `fv (a⌊i⌉ := e) ⊆ set Vs` have fv1: "fv a ⊆ set Vs" and fv2: "fv i ⊆ set Vs" and fv3: "fv e ⊆ set Vs" by auto show ?case proof(cases "\<A> a") case None thus ?thesis using AAss by simp next case (Some A1) with fv1 have A1: "\<A> (compE1 Vs a) = ⌊index Vs ` A1⌋" by-(rule A_compE1) from A_fv[OF Some] fv1 `A ⊆ set Vs` have "A ∪ A1 ⊆ set Vs" by auto from IH2[OF this fv2] Some D2 have D2': "\<D> (compE1 Vs i) ⌊index Vs ` A ∪ index Vs ` A1⌋" by(simp add: image_Un) show ?thesis proof(cases "\<A> i") case None thus ?thesis using AAss D2' Some A1 by simp next case (Some A2) with fv2 have A2: "\<A> (compE1 Vs i) = ⌊index Vs ` A2⌋" by-(rule A_compE1) moreover from A_fv[OF Some] fv2 `A ∪ A1 ⊆ set Vs` have "A ∪ A1 ∪ A2 ⊆ set Vs" by auto from IH3[OF this fv3] Some `\<A> a = ⌊A1⌋` D3 have "\<D> (compE1 Vs e) ⌊index Vs ` A ∪ index Vs ` A1 ∪ index Vs ` A2⌋" by(simp add: image_Un) ultimately show ?thesis using IH1[OF `A ⊆ set Vs` fv1 D1] D2' A1 A2 by(simp) qed qed next case (FAss e1 F D e2) hence IH1: "\<D> (compE1 Vs e1) ⌊index Vs ` A⌋" by simp show ?case proof (cases "\<A> e1") case None thus ?thesis using FAss by simp next case (Some A1) have indexA1: "\<A> (compE1 Vs e1) = ⌊index Vs ` A1⌋" using A_compE1[OF Some] FAss.prems by auto have "A ∪ A1 ⊆ set Vs" using FAss.prems A_fv[OF Some] by auto hence "\<D> (compE1 Vs e2) ⌊index Vs ` (A ∪ A1)⌋" using FAss Some by auto hence "\<D> (compE1 Vs e2) ⌊index Vs ` A ∪ index Vs ` A1⌋" by(simp add: image_Un) thus ?thesis using IH1 indexA1 by auto qed next case (Call e1 M es) hence IH1: "\<D> (compE1 Vs e1) ⌊index Vs ` A⌋" by simp show ?case proof (cases "\<A> e1") case None thus ?thesis using Call by simp next case (Some A1) have indexA1: "\<A> (compE1 Vs e1) = ⌊index Vs ` A1⌋" using A_compE1[OF Some] Call.prems by auto have "A ∪ A1 ⊆ set Vs" using Call.prems A_fv[OF Some] by auto hence "\<D>s (compEs1 Vs es) ⌊index Vs ` (A ∪ A1)⌋" using Call Some by auto hence "\<D>s (compEs1 Vs es) ⌊index Vs ` A ∪ index Vs ` A1⌋" by(simp add: image_Un) thus ?thesis using IH1 indexA1 by auto qed next case (Synchronized V exp1 exp2 A Vs) have IH1: "!!A Vs. [|A ⊆ set Vs; fv exp1 ⊆ set Vs; \<D> exp1 ⌊A⌋|] ==> \<D> (compE1 Vs exp1) ⌊index Vs ` A⌋" by fact have IH2: "!!A Vs. [|A ⊆ set Vs; fv exp2 ⊆ set Vs; \<D> exp2 ⌊A⌋|] ==> \<D> (compE1 Vs exp2) ⌊index Vs ` A⌋" by fact from `\<D> (syncV (exp1) exp2) ⌊A⌋` have D1: "\<D> exp1 ⌊A⌋" and D2: "\<D> exp2 (⌊A⌋ \<squnion> \<A> exp1)" by auto from `fv (syncV (exp1) exp2) ⊆ set Vs` have fv1: "fv exp1 ⊆ set Vs" and fv2: "fv exp2 ⊆ set Vs" by auto show ?case proof(cases "\<A> exp1") case None thus ?thesis using Synchronized by(simp) next case (Some A1) with fv1 have A1: "\<A> (compE1 Vs exp1) = ⌊index Vs ` A1⌋" by-(rule A_compE1) from A_fv[OF Some] fv1 `A ⊆ set Vs` have "A ∪ A1 ⊆ set Vs" by auto hence "A ∪ A1 ⊆ set (Vs @ [fresh_var Vs])" by simp from IH2[OF this] fv2 Some D2 have D2': "\<D> (compE1 (Vs @ [fresh_var Vs]) exp2) ⌊index (Vs @ [fresh_var Vs]) ` (A ∪ A1)⌋" by(simp) moreover from fresh_var_fresh[of Vs] `A ∪ A1 ⊆ set Vs` have "(fresh_var Vs) ∉ A ∪ A1" by auto with `A ∪ A1 ⊆ set Vs` have "index (Vs @ [fresh_var Vs]) ` (A ∪ A1) = index Vs ` A ∪ index Vs ` A1" by(simp add: image_index image_Un) ultimately show ?thesis using IH1[OF `A ⊆ set Vs` fv1 D1] D2' A1 by(simp) qed next case (InSynchronized V a e A Vs) have IH: "!!A Vs. [|A ⊆ set Vs; fv e ⊆ set Vs; \<D> e ⌊A⌋|] ==> \<D> (compE1 Vs e) ⌊index Vs ` A⌋" by fact from IH[of A "Vs @ [fresh_var Vs]"] `A ⊆ set Vs` `fv (insyncV (a) e) ⊆ set Vs` `\<D> (insyncV (a) e) ⌊A⌋` have "\<D> (compE1 (Vs @ [fresh_var Vs]) e) ⌊index (Vs @ [fresh_var Vs]) ` A⌋" by(auto) moreover from fresh_var_fresh[of Vs] `A ⊆ set Vs` have "(fresh_var Vs) ∉ A" by auto with `A ⊆ set Vs` have "index (Vs @ [fresh_var Vs]) ` A = index Vs ` A" by(simp add: image_index) ultimately show ?case by(simp) next case (TryCatch e1 C V e2) have "[| A∪{V} ⊆ set(Vs@[V]); fv e2 ⊆ set(Vs@[V]); \<D> e2 ⌊A∪{V}⌋|] ==> \<D> (compE1 (Vs@[V]) e2) ⌊index (Vs@[V]) ` (A∪{V})⌋" by fact hence "\<D> (compE1 (Vs@[V]) e2) ⌊index (Vs@[V]) ` (A∪{V})⌋" using TryCatch.prems by(simp add:Diff_subset_conv) moreover have "index (Vs@[V]) ` A ⊆ index Vs ` A ∪ {size Vs}" using TryCatch.prems by(auto simp add: image_index split:split_if_asm) ultimately show ?case using TryCatch by(auto simp:hyperset_defs elim!:D_mono') next case (Seq e1 e2) hence IH1: "\<D> (compE1 Vs e1) ⌊index Vs ` A⌋" by simp show ?case proof (cases "\<A> e1") case None thus ?thesis using Seq by simp next case (Some A1) have indexA1: "\<A> (compE1 Vs e1) = ⌊index Vs ` A1⌋" using A_compE1[OF Some] Seq.prems by auto have "A ∪ A1 ⊆ set Vs" using Seq.prems A_fv[OF Some] by auto hence "\<D> (compE1 Vs e2) ⌊index Vs ` (A ∪ A1)⌋" using Seq Some by auto hence "\<D> (compE1 Vs e2) ⌊index Vs ` A ∪ index Vs ` A1⌋" by(simp add: image_Un) thus ?thesis using IH1 indexA1 by auto qed next case (Cond e e1 e2) hence IH1: "\<D> (compE1 Vs e) ⌊index Vs ` A⌋" by simp show ?case proof (cases "\<A> e") case None thus ?thesis using Cond by simp next case (Some B) have indexB: "\<A> (compE1 Vs e) = ⌊index Vs ` B⌋" using A_compE1[OF Some] Cond.prems by auto have "A ∪ B ⊆ set Vs" using Cond.prems A_fv[OF Some] by auto hence "\<D> (compE1 Vs e1) ⌊index Vs ` (A ∪ B)⌋" and "\<D> (compE1 Vs e2) ⌊index Vs ` (A ∪ B)⌋" using Cond Some by auto hence "\<D> (compE1 Vs e1) ⌊index Vs ` A ∪ index Vs ` B⌋" and "\<D> (compE1 Vs e2) ⌊index Vs ` A ∪ index Vs ` B⌋" by(simp add: image_Un)+ thus ?thesis using IH1 indexB by auto qed next case (While e1 e2) hence IH1: "\<D> (compE1 Vs e1) ⌊index Vs ` A⌋" by simp show ?case proof (cases "\<A> e1") case None thus ?thesis using While by simp next case (Some A1) have indexA1: "\<A> (compE1 Vs e1) = ⌊index Vs ` A1⌋" using A_compE1[OF Some] While.prems by auto have "A ∪ A1 ⊆ set Vs" using While.prems A_fv[OF Some] by auto hence "\<D> (compE1 Vs e2) ⌊index Vs ` (A ∪ A1)⌋" using While Some by auto hence "\<D> (compE1 Vs e2) ⌊index Vs ` A ∪ index Vs ` A1⌋" by(simp add: image_Un) thus ?thesis using IH1 indexA1 by auto qed next case (Block V T vo e A Vs) have IH: "!!A Vs. [|A ⊆ set Vs; fv e ⊆ set Vs; \<D> e ⌊A⌋|] ==> \<D> (compE1 Vs e) ⌊index Vs ` A⌋" by fact from `fv {V:T=vo; e} ⊆ set Vs` have fv: "fv e ⊆ set (Vs @ [V])" by auto show ?case proof(cases vo) case None with `\<D> {V:T=vo; e} ⌊A⌋` have D: "\<D> e ⌊A - {V}⌋" by(auto) from `A ⊆ set Vs` have "A - {V} ⊆ set (Vs @ [V])" by auto from IH[OF this fv D] have "\<D> (compE1 (Vs @ [V]) e) ⌊index (Vs @ [V]) ` (A - {V})⌋" . moreover from `A ⊆ set Vs` have size: "size Vs ∉ index Vs ` A" by(auto simp add: image_def) hence "⌊index Vs ` (A - {V})⌋ \<sqsubseteq> ⌊index Vs ` A⌋" by(auto simp add: hyperset_defs) ultimately have "\<D> (compE1 (Vs @ [V]) e) ⌊index Vs ` A⌋" using `A - {V} ⊆ set (Vs @ [V])` by(simp add: image_index)(erule D_mono', auto) thus ?thesis using None size by(simp) next case (Some v) with `\<D> {V:T=vo; e} ⌊A⌋` have D: "\<D> e ⌊insert V A⌋" by(auto) from `A ⊆ set Vs` have "insert V A ⊆ set (Vs @ [V])" by auto from IH[OF this fv D] have "\<D> (compE1 (Vs @ [V]) e) ⌊index (Vs @ [V]) ` insert V A⌋" by simp moreover from `A ⊆ set Vs` have "index (Vs @ [V]) ` insert V A ⊆ insert (length Vs) (index Vs ` A)" by(auto simp add: image_index) ultimately show ?thesis using Some by(auto elim!: D_mono' simp add: hyperset_defs) qed next case (Cons_exp e1 es) hence IH1: "\<D> (compE1 Vs e1) ⌊index Vs ` A⌋" by simp show ?case proof (cases "\<A> e1") case None thus ?thesis using Cons_exp by simp next case (Some A1) have indexA1: "\<A> (compE1 Vs e1) = ⌊index Vs ` A1⌋" using A_compE1[OF Some] Cons_exp.prems by auto have "A ∪ A1 ⊆ set Vs" using Cons_exp.prems A_fv[OF Some] by auto hence "\<D>s (compEs1 Vs es) ⌊index Vs ` (A ∪ A1)⌋" using Cons_exp Some by auto hence "\<D>s (compEs1 Vs es) ⌊index Vs ` A ∪ index Vs ` A1⌋" by(simp add: image_Un) thus ?thesis using IH1 indexA1 by auto qed qed (simp_all add:hyperset_defs) lemma index_image_set: "distinct xs ==> index xs ` set xs = {..<size xs}" by(induct xs rule:rev_induct) (auto simp add: image_index) lemma D_compE1: "[| \<D> e ⌊set Vs⌋; fv e ⊆ set Vs; distinct Vs |] ==> \<D> (compE1 Vs e) ⌊{..<length Vs}⌋" by(fastsimp dest!: D_index_compE1[OF subset_refl] simp add:index_image_set) lemma D_compE1': assumes "\<D> e ⌊set(V#Vs)⌋" and "fv e ⊆ set(V#Vs)" and "distinct(V#Vs)" shows "\<D> (compE1 (V#Vs) e) ⌊{..length Vs}⌋" proof - have "{..size Vs} = {..<size(V#Vs)}" by auto thus ?thesis using prems by (simp only:)(rule D_compE1) qed lemma fv_compE1: "fv e ⊆ set Vs ==> fv (compE1 Vs e) = (index Vs) ` (fv e)" and fvs_compEs1: "fvs es ⊆ set Vs ==> fvs (compEs1 Vs es) = (index Vs) ` (fvs es)" proof(induct e and es arbitrary: Vs and Vs) case (Block V ty vo exp) have IH: "!!Vs. fv exp ⊆ set Vs ==> fv (compE1 Vs exp) = index Vs ` fv exp" by fact from `fv {V:ty=vo; exp} ⊆ set Vs` have fv': "fv exp ⊆ set (Vs @ [V])" by auto from IH[OF this] have IH': "fv (compE1 (Vs @ [V]) exp) = index (Vs @ [V]) ` fv exp" . have "fv (compE1 (Vs @ [V]) exp) - {length Vs} = index Vs ` (fv exp - {V})" proof(rule equalityI[OF subsetI subsetI]) fix x assume x: "x ∈ fv (compE1 (Vs @ [V]) exp) - {length Vs}" hence "x ≠ length Vs" by simp from x IH' have "x ∈ index (Vs @ [V]) ` fv exp" by simp thus "x ∈ index Vs ` (fv exp - {V})" proof(rule imageE) fix y assume [simp]: "x = index (Vs @ [V]) y" and y: "y ∈ fv exp" have "y ≠ V" proof assume [simp]: "y = V" hence "x = length Vs" by simp with `x ≠ length Vs` show False by contradiction qed moreover with fv' y have "y ∈ set Vs" by auto ultimately have "index (Vs @ [V]) y = index Vs y" by(simp) thus ?thesis using y `y ≠ V` by auto qed next fix x assume x: "x ∈ index Vs ` (fv exp - {V})" thus "x ∈ fv (compE1 (Vs @ [V]) exp) - {length Vs}" proof(rule imageE) fix y assume [simp]: "x = index Vs y" and y: "y ∈ fv exp - {V}" with fv' have "y ∈ set Vs" "y ≠ V" by auto hence "index Vs y = index (Vs @ [V]) y" by simp with y have "x ∈ index (Vs @ [V]) ` fv exp" by auto thus ?thesis using IH' `y ∈ set Vs` by simp qed qed thus ?case by simp next case (Synchronized V exp1 exp2) have IH1: "!!Vs. fv exp1 ⊆ set Vs ==> fv (compE1 Vs exp1) = index Vs ` fv exp1" and IH2: "!!Vs. fv exp2 ⊆ set Vs ==> fv (compE1 Vs exp2) = index Vs ` fv exp2" by fact+ from `fv (syncV (exp1) exp2) ⊆ set Vs` have fv1: "fv exp1 ⊆ set Vs" and fv2: "fv exp2 ⊆ set Vs" by auto from fv2 have fv2': "fv exp2 ⊆ set (Vs @ [fresh_var Vs])" by auto have "index (Vs @ [fresh_var Vs]) ` fv exp2 = index Vs ` fv exp2" proof(rule equalityI[OF subsetI subsetI]) fix x assume x: "x ∈ index (Vs @ [fresh_var Vs]) ` fv exp2" thus "x ∈ index Vs ` fv exp2" proof(rule imageE) fix y assume [simp]: "x = index (Vs @ [fresh_var Vs]) y" and y: "y ∈ fv exp2" from y fv2 have "y ∈ set Vs" by auto moreover hence "y ≠ (fresh_var Vs)" by(auto simp add: fresh_var_fresh) ultimately show ?thesis using y by(auto) qed next fix x assume x: "x ∈ index Vs ` fv exp2" thus "x ∈ index (Vs @ [fresh_var Vs]) ` fv exp2" proof(rule imageE) fix y assume [simp]: "x = index Vs y" and y: "y ∈ fv exp2" from y fv2 have "y ∈ set Vs" by auto moreover hence "y ≠ (fresh_var Vs)" by(auto simp add: fresh_var_fresh) ultimately have "index Vs y = index (Vs @ [fresh_var Vs]) y" by simp thus ?thesis using y by(auto) qed qed with IH1[OF fv1] IH2[OF fv2'] show ?case by(auto) next case (InSynchronized V a exp) have IH: "!!Vs. fv exp ⊆ set Vs ==> fv (compE1 Vs exp) = index Vs ` fv exp" by fact from `fv (insyncV (a) exp) ⊆ set Vs` have fv: "fv exp ⊆ set Vs" by simp hence fv': "fv exp ⊆ set (Vs @ [fresh_var Vs])" by auto have "index (Vs @ [fresh_var Vs]) ` fv exp = index Vs ` fv exp" proof(rule equalityI[OF subsetI subsetI]) fix x assume "x ∈ index (Vs @ [fresh_var Vs]) ` fv exp" thus "x ∈ index Vs ` fv exp" proof(rule imageE) fix y assume [simp]: "x = index (Vs @ [fresh_var Vs]) y" and y: "y ∈ fv exp" from y fv have "y ∈ set Vs" by auto moreover hence "y ≠ (fresh_var Vs)" by(auto simp add: fresh_var_fresh) ultimately have "index (Vs @ [fresh_var Vs]) y = index Vs y" by simp thus ?thesis using y by simp qed next fix x assume "x ∈ index Vs ` fv exp" thus "x ∈ index (Vs @ [fresh_var Vs]) ` fv exp" proof(rule imageE) fix y assume [simp]: "x = index Vs y" and y: "y ∈ fv exp" from y fv have "y ∈ set Vs" by auto moreover hence "y ≠ (fresh_var Vs)" by(auto simp add: fresh_var_fresh) ultimately have "index Vs y = index (Vs @ [fresh_var Vs]) y" by simp thus ?thesis using y by auto qed qed with IH[OF fv'] show ?case by simp next case (TryCatch exp1 C V exp2) have IH1: "!!Vs. fv exp1 ⊆ set Vs ==> fv (compE1 Vs exp1) = index Vs ` fv exp1" and IH2: "!!Vs. fv exp2 ⊆ set Vs ==> fv (compE1 Vs exp2) = index Vs ` fv exp2" by fact+ from `fv (try exp1 catch(C V) exp2) ⊆ set Vs` have fv1: "fv exp1 ⊆ set Vs" and fv2: "fv exp2 ⊆ set (Vs @ [V])" by auto have "index (Vs @ [V]) ` fv exp2 - {length Vs} = index Vs ` (fv exp2 - {V})" proof(rule equalityI[OF subsetI subsetI]) fix x assume x: "x ∈ index (Vs @ [V]) ` fv exp2 - {length Vs}" hence "x ≠ length Vs" by simp from x have "x ∈ index (Vs @ [V]) ` fv exp2" by auto thus "x ∈ index Vs ` (fv exp2 - {V})" proof(rule imageE) fix y assume [simp]: "x = index (Vs @ [V]) y" and y: "y ∈ fv exp2" have "y ≠ V" proof assume [simp]: "y = V" hence "x = length Vs" by simp with `x ≠ length Vs` show False by contradiction qed moreover with fv2 y have "y ∈ set Vs" by auto ultimately have "index (Vs @ [V]) y = index Vs y" by(simp) thus ?thesis using y `y ≠ V` by auto qed next fix x assume x: "x ∈ index Vs ` (fv exp2 - {V})" thus "x ∈ index (Vs @ [V]) ` fv exp2 - {length Vs}" proof(rule imageE) fix y assume [simp]: "x = index Vs y" and y: "y ∈ fv exp2 - {V}" with fv2 have "y ∈ set Vs" "y ≠ V" by auto hence "index Vs y = index (Vs @ [V]) y" by simp with y have "x ∈ index (Vs @ [V]) ` fv exp2" by auto thus ?thesis using `y ∈ set Vs` by simp qed qed with IH1[OF fv1] IH2[OF fv2] show ?case by auto qed(auto) lemma syncvars_compE1: "fv e ⊆ set Vs ==> syncvars (compE1 Vs e)" and syncvarss_compEs1: "fvs es ⊆ set Vs ==> syncvarss (compEs1 Vs es)" proof(induct e and es arbitrary: Vs and Vs) case (Block V ty vo exp) from `fv {V:ty=vo; exp} ⊆ set Vs` have "fv exp ⊆ set (Vs @ [V])" by auto from `!!Vs. fv exp ⊆ set Vs ==> syncvars (compE1 Vs exp)`[OF this] show ?case by(simp) next case (Synchronized V exp1 exp2) note IH1 = `!!Vs. fv exp1 ⊆ set Vs ==> syncvars (compE1 Vs exp1)` note IH2 = `!!Vs. fv exp2 ⊆ set Vs ==> syncvars (compE1 Vs exp2)` from `fv (syncV (exp1) exp2) ⊆ set Vs` have fv1: "fv exp1 ⊆ set Vs" and fv2: "fv exp2 ⊆ set Vs" and fv2': "fv exp2 ⊆ set (Vs @ [fresh_var Vs])" by auto have "length Vs ∉ index (Vs @ [fresh_var Vs]) ` fv exp2" proof assume "length Vs ∈ index (Vs @ [fresh_var Vs]) ` fv exp2" thus False proof(rule imageE) fix x assume x: "length Vs = index (Vs @ [fresh_var Vs]) x" and x': "x ∈ fv exp2" from x' fv2 have "x ∈ set Vs" "x ≠ (fresh_var Vs)" by(auto simp add: fresh_var_fresh) with x show ?thesis by(simp) qed qed with IH1[OF fv1] IH2[OF fv2'] fv2' show ?case by(simp add: fv_compE1) next case (InSynchronized V a exp) note IH = `!!Vs. fv exp ⊆ set Vs ==> syncvars (compE1 Vs exp)` from `fv (insyncV (a) exp) ⊆ set Vs` have fv: "fv exp ⊆ set Vs" and fv': "fv exp ⊆ set (Vs @ [fresh_var Vs])" by auto have "length Vs ∉ index (Vs @ [fresh_var Vs]) ` fv exp" proof assume "length Vs ∈ index (Vs @ [fresh_var Vs]) ` fv exp" thus False proof(rule imageE) fix x assume x: "length Vs = index (Vs @ [fresh_var Vs]) x" and x': "x ∈ fv exp" from x' fv have "x ∈ set Vs" "x ≠ (fresh_var Vs)" by(auto simp add: fresh_var_fresh) with x show ?thesis by(simp) qed qed with IH[OF fv'] fv' show ?case by(simp add: fv_compE1) next case (TryCatch exp1 C V exp2) note IH1 = `!!Vs. fv exp1 ⊆ set Vs ==> syncvars (compE1 Vs exp1)` note IH2 = `!!Vs. fv exp2 ⊆ set Vs ==> syncvars (compE1 Vs exp2)` from `fv (try exp1 catch(C V) exp2) ⊆ set Vs` have fv1: "fv exp1 ⊆ set Vs" and fv2: "fv exp2 ⊆ set (Vs @ [V])" by auto from IH1[OF fv1] IH2[OF fv2] show ?case by auto qed auto lemma compP1_pres_wf: "wf_J_prog P ==> wf_J1_prog (compP1 P)" apply simp apply(rule wf_prog_compPI) prefer 2 apply assumption apply(case_tac m) apply(simp add:wf_mdecl_def wf_J1_mdecl_def wf_J_mdecl) apply(clarify) apply(frule WT_fv) apply(fastsimp intro!: compE1_pres_wt D_compE1' \<B> syncvars_compE1) done end