Theory J1JVM
section ‹Correctness of Stage: From intermediate language to JVM›
theory J1JVM imports J1JVMBisim begin
context J1_JVM_heap_base begin
declare τmove1.simps [simp del] τmoves1.simps [simp del]
lemma bisim1_insync_Throw_exec:
assumes bisim2: "P,e2,h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, xcp)"
shows "τExec_movet_a P t (sync⇘V⇙ (e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), xcp) ([Addr ad], loc, 6 + length (compE2 e1) + length (compE2 e2), None)"
proof -
from bisim2 have pc: "pc < length (compE2 e2)" and [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
let ?stk = "Addr ad # drop (size stk - 0) stk"
from bisim2 have "xcp = ⌊ad⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊ad⌋"
have "τExec_movet_a P t (sync⇘V⇙ (e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), ⌊ad⌋) (?stk, loc, ?pc, None)"
proof(rule τExect1step[unfolded exec_move_def, OF exec_catch])
from bisim1_xcp_Some_not_caught[OF bisim2[simplified], of "λC M Ts T. compMb2" "Suc (Suc (Suc (length (compE2 e1))))" 0]
have "match_ex_table (compP2 P) (cname_of h ad) (Suc (Suc (Suc (length (compE2 e1) + pc)))) (compxE2 e2 (Suc (Suc (Suc (length (compE2 e1))))) 0) = None"
by(simp add: compP2_def)
thus "match_ex_table (compP2 P) (cname_of h ad) (Suc (Suc (Suc (length (compE2 e1) + pc)))) (compxE2 (sync⇘V⇙ (e1) e2) 0 0) = ⌊(6 + length (compE2 e1) + length (compE2 e2), 0)⌋"
using pc
by(auto simp add: compP2_def match_ex_table_append matches_ex_entry_def eval_nat_numeral
dest: match_ex_table_pc_length_compE2)
qed(insert pc, auto intro: τmove2xcp)
thus ?thesis by simp
next
assume [simp]: "xcp = None"
with bisim2 obtain pc'
where "τExec_movet_a P t e2 h (stk, loc, pc, None) ([Addr ad], loc, pc', ⌊ad⌋)"
and bisim': "P, e2, h ⊢ (Throw ad, xs) ↔ ([Addr ad], loc, pc', ⌊ad⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_movet)
hence "τExec_movet_a P t (sync⇘V⇙ (e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), None) ([Addr ad], loc, Suc (Suc (Suc (length (compE2 e1) + pc'))), ⌊ad⌋)"
by-(rule Insync_τExectI)
also let ?stk = "Addr ad # drop (size [Addr ad] - 0) [Addr ad]"
from bisim' have pc': "pc' < length (compE2 e2)" by(auto dest: bisim1_ThrowD)
have "τExec_movet_a P t (sync⇘V⇙ (e1) e2) h ([Addr ad], loc, Suc (Suc (Suc (length (compE2 e1) + pc'))), ⌊ad⌋) (?stk, loc, ?pc, None)"
proof(rule τExect1step[unfolded exec_move_def, OF exec_catch])
from bisim1_xcp_Some_not_caught[OF bisim', of "λC M Ts T. compMb2" "Suc (Suc (Suc (length (compE2 e1))))" 0]
have "match_ex_table (compP2 P) (cname_of h ad) (Suc (Suc (Suc (length (compE2 e1) + pc')))) (compxE2 e2 (Suc (Suc (Suc (length (compE2 e1))))) 0) = None"
by(simp add: compP2_def)
thus "match_ex_table (compP2 P) (cname_of h ad) (Suc (Suc (Suc (length (compE2 e1) + pc')))) (compxE2 (sync⇘V⇙ (e1) e2) 0 0) = ⌊(6 + length (compE2 e1) + length (compE2 e2), 0)⌋"
using pc'
by(auto simp add: compP2_def match_ex_table_append matches_ex_entry_def eval_nat_numeral
dest: match_ex_table_pc_length_compE2)
qed(insert pc', auto intro: τmove2xcp)
finally (tranclp_trans) show ?thesis by simp
qed
qed
end
primrec sim12_size :: "('a, 'b, 'addr) exp ⇒ nat"
and sim12_sizes :: "('a, 'b, 'addr) exp list ⇒ nat"
where
"sim12_size (new C) = 0"
| "sim12_size (newA T⌊e⌉) = Suc (sim12_size e)"
| "sim12_size (Cast T e) = Suc (sim12_size e)"
| "sim12_size (e instanceof T) = Suc (sim12_size e)"
| "sim12_size (e «bop» e') = Suc (sim12_size e + sim12_size e')"
| "sim12_size (Val v) = 0"
| "sim12_size (Var V) = 0"
| "sim12_size (V := e) = Suc (sim12_size e)"
| "sim12_size (a⌊i⌉) = Suc (sim12_size a + sim12_size i)"
| "sim12_size (a⌊i⌉ := e) = Suc (sim12_size a + sim12_size i + sim12_size e)"
| "sim12_size (a∙length) = Suc (sim12_size a)"
| "sim12_size (e∙F{D}) = Suc (sim12_size e)"
| "sim12_size (e∙F{D} := e') = Suc (sim12_size e + sim12_size e')"
| "sim12_size (e∙compareAndSwap(D∙F, e', e'')) = Suc (sim12_size e + sim12_size e' + sim12_size e'')"
| "sim12_size (e∙M(es)) = Suc (sim12_size e + sim12_sizes es)"
| "sim12_size ({V:T=vo; e}) = Suc (sim12_size e)"
| "sim12_size (sync⇘V⇙(e) e') = Suc (sim12_size e + sim12_size e')"
| "sim12_size (insync⇘V⇙(a) e) = Suc (sim12_size e)"
| "sim12_size (e;; e') = Suc (sim12_size e + sim12_size e')"
| "sim12_size (if (e) e1 else e2) = Suc (sim12_size e)"
| "sim12_size (while(b) c) = Suc (Suc (sim12_size b))"
| "sim12_size (throw e) = Suc (sim12_size e)"
| "sim12_size (try e catch(C V) e') = Suc (sim12_size e)"
| "sim12_sizes [] = 0"
| "sim12_sizes (e # es) = sim12_size e + sim12_sizes es"
lemma sim12_sizes_map_Val [simp]:
"sim12_sizes (map Val vs) = 0"
by(induct vs) simp_all
lemma sim12_sizes_append [simp]:
"sim12_sizes (es @ es') = sim12_sizes es + sim12_sizes es'"
by(induct es) simp_all
context JVM_heap_base begin
lemma τExec_mover_length_compE2_conv [simp]:
assumes pc: "pc ≥ length (compE2 e)"
shows "τExec_mover ci P t e h (stk, loc, pc, xcp) s ⟷ s = (stk, loc, pc, xcp)"
proof
assume "τExec_mover ci P t e h (stk, loc, pc, xcp) s"
thus "s = (stk, loc, pc, xcp)" using pc
by induct(auto simp add: τexec_move_def)
qed auto
lemma τExec_movesr_length_compE2_conv [simp]:
assumes pc: "pc ≥ length (compEs2 es)"
shows "τExec_movesr ci P t es h (stk, loc, pc, xcp) s ⟷ s = (stk, loc, pc, xcp)"
proof
assume "τExec_movesr ci P t es h (stk, loc, pc, xcp) s"
thus "s = (stk, loc, pc, xcp)" using pc
by induct(auto simp add: τexec_moves_def)
qed auto
end
context J1_JVM_heap_base begin
lemma assumes wf: "wf_J1_prog P"
defines [simp]: "sim_move ≡ λe e'. if sim12_size e' < sim12_size e then τExec_mover_a else τExec_movet_a"
and [simp]: "sim_moves ≡ λes es'. if sim12_sizes es' < sim12_sizes es then τExec_movesr_a else τExec_movest_a"
shows exec_instr_simulates_red1:
"⟦ P, E, h ⊢ (e, xs) ↔ (stk, loc, pc, xcp); True,P,t ⊢1 ⟨e, (h, xs)⟩ -ta→ ⟨e', (h', xs')⟩; bsok E n ⟧
⟹ ∃pc'' stk'' loc'' xcp''. P, E, h' ⊢ (e', xs') ↔ (stk'', loc'', pc'', xcp'') ∧
(if τmove1 P h e
then h = h' ∧ sim_move e e' P t E h (stk, loc, pc, xcp) (stk'', loc'', pc'', xcp'')
else ∃pc' stk' loc' xcp'. τExec_mover_a P t E h (stk, loc, pc, xcp) (stk', loc', pc', xcp') ∧
exec_move_a P t E h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'') ∧
¬ τmove2 (compP2 P) h stk' E pc' xcp' ∧
(call1 e = None ∨ no_call2 E pc ∨ pc' = pc ∧ stk' = stk ∧ loc' = loc ∧ xcp' = xcp))"
(is "⟦ _; _; _ ⟧
⟹ ∃pc'' stk'' loc'' xcp''. _ ∧ ?exec ta E e e' h stk loc pc xcp h' pc'' stk'' loc'' xcp''")
and exec_instr_simulates_reds1:
"⟦ P, Es, h ⊢ (es, xs) [↔] (stk, loc, pc, xcp); True,P,t ⊢1 ⟨es, (h, xs)⟩ [-ta→] ⟨es', (h', xs')⟩; bsoks Es n ⟧
⟹ ∃pc'' stk'' loc'' xcp''. P, Es, h' ⊢ (es', xs') [↔] (stk'', loc'', pc'', xcp'') ∧
(if τmoves1 P h es
then h = h' ∧ sim_moves es es' P t Es h (stk, loc, pc, xcp) (stk'', loc'', pc'', xcp'')
else ∃pc' stk' loc' xcp'. τExec_movesr_a P t Es h (stk, loc, pc, xcp) (stk', loc', pc', xcp') ∧
exec_moves_a P t Es h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'') ∧
¬ τmoves2 (compP2 P) h stk' Es pc' xcp' ∧
(calls1 es = None ∨ no_calls2 Es pc ∨ pc' = pc ∧ stk' = stk ∧ loc' = loc ∧ xcp' = xcp))"
(is "⟦ _; _; _ ⟧
⟹ ∃pc'' stk'' loc'' xcp''. _ ∧ ?execs ta Es es es' h stk loc pc xcp h' pc'' stk'' loc'' xcp''")
proof(induction E n e xs stk loc pc xcp and Es n es xs stk loc pc xcp
arbitrary: e' h' xs' Env T Env' T' and es' h' xs' Env Ts Env' Ts' rule: bisim1_bisims1_inducts_split)
case (bisim1Call1 obj n obj' xs stk loc pc xcp ps M')
note IHobj = bisim1Call1.IH(2)
note IHparam = bisim1Call1.IH(4)
note bisim1 = ‹P,obj,h ⊢ (obj', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹⋀xs. P,ps,h ⊢ (ps, xs) [↔] ([], xs, 0, None)›
note bsok = ‹bsok (obj∙M'(ps)) n›
note red = ‹True,P,t ⊢1 ⟨obj'∙M'(ps),(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
from red show ?case
proof(cases)
case (Call1Obj E')
note [simp] = ‹e' = E'∙M'(ps)›
and red = ‹True,P,t ⊢1 ⟨obj',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h obj' = τmove1 P h (obj'∙M'(ps))" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from red have "call1 (obj'∙M'(ps)) = call1 obj'" by auto
moreover from IHobj[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,obj,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta obj obj' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,obj∙M'(ps),h' ⊢ (E'∙M'(ps), xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1Call1)
moreover {
assume "no_call2 obj pc"
hence "no_call2 (obj∙M'(ps)) pc ∨ pc = length (compE2 obj)" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Call_τExecrI1 Call_τExectI1 exec_move_CallI1)+
next
case (Call1Params es v)
note [simp] = ‹obj' = Val v› ‹e' = Val v∙M'(es)›
and red = ‹True,P,t ⊢1 ⟨ps, (h, xs)⟩ [-ta→] ⟨es, (h', xs')⟩›
from red have τ: "τmove1 P h (obj'∙M'(ps)) = τmoves1 P h ps" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and execo: "τExec_mover_a P t obj h (stk, loc, pc, xcp) ([v], loc, length (compE2 obj), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (obj∙M'(ps)) h (stk, loc, pc, xcp) ([v], loc, length (compE2 obj), None)"
by-(rule Call_τExecrI1)
moreover from IHparam[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,ps,h' ⊢ (es, xs') [↔] (stk'', loc'', pc'', xcp'')"
and exec': "?execs ta ps ps es h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (obj∙M'(ps)) (obj'∙M'(ps)) (obj'∙M(es)) h [v] loc (length (compE2 obj)) None h' (length (compE2 obj) + pc'') (stk'' @ [v]) loc'' xcp''"
proof(cases "τmove1 P h (obj'∙M'(ps))")
case True
with exec' τ have [simp]: "h = h'"
and e: "sim_moves ps es P t ps h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (obj'∙M'(ps)) (obj'∙M'(es)) P t (obj∙M'(ps)) h ([] @ [v], xs, length (compE2 obj) + 0, None) (stk'' @ [v], loc'', length (compE2 obj) + pc'', xcp'')"
by(fastforce dest: Call_τExecrI2 Call_τExectI2)
with s True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_movesr_a P t ps h ([], xs, 0, None) (stk', loc', pc', xcp')"
and e': "exec_moves_a P t ps h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmoves2 (compP2 P) h stk' ps pc' xcp'"
and call: "calls1 ps = None ∨ no_calls2 ps 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs ∧ xcp' = None" by auto
from e have "τExec_mover_a P t (obj∙M'(ps)) h ([] @ [v], xs, length (compE2 obj) + 0, None) (stk' @ [v], loc', length (compE2 obj) + pc', xcp')" by(rule Call_τExecrI2)
moreover from e' have "exec_move_a P t (obj∙M'(ps)) h (stk' @ [v], loc', length (compE2 obj) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 obj) + pc'', xcp'')"
by(rule exec_move_CallI2)
moreover from τ' e' have "τmove2 (compP2 P) h (stk' @ [v]) (obj∙M'(ps)) (length (compE2 obj) + pc') xcp' ⟹ False"
by(fastforce simp add: τmove2_iff τmoves2_iff τinstr_stk_drop_exec_moves split: if_split_asm)
moreover from red have "call1 (obj'∙M'(ps)) = calls1 ps" by(auto simp add: is_vals_conv)
moreover have "no_calls2 ps 0 ⟹ no_call2 (obj∙M'(ps)) (length (compE2 obj)) ∨ ps = []" "calls1 [] = None"
by(auto simp add: no_calls2_def no_call2_def)
ultimately show ?thesis using False s call
by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P,obj∙M'(ps),h' ⊢ (Val v∙M'(es), xs') ↔ ((stk'' @ [v]), loc'', length (compE2 obj) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1CallParams)
moreover from bisim1 have "pc ≠ length (compE2 obj) ⟶ no_call2 (obj∙M'(ps)) pc"
by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
ultimately show ?thesis using τ execo
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
done
next
case (Call1ThrowObj a)
note [simp] = ‹obj' = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (Throw a∙M'(ps))" by(rule τmove1CallThrowObj)
from bisim1 have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim1 have "P, obj∙M'(ps), h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
by(auto intro: bisim1_bisims1.bisim1CallThrowObj)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim1 obtain pc'
where "τExec_mover_a P t obj h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, obj, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (obj∙M'(ps)) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule Call_τExecrI1)
moreover from bisim' have "P, obj∙M'(ps), h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by(rule bisim1CallThrowObj)
ultimately show ?thesis using τ by auto
qed
next
case (Call1ThrowParams vs a es' v)
note [simp] = ‹obj' = Val v› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
and ps = ‹ps = map Val vs @ Throw a # es'›
from bisim1 have [simp]: "xcp = None" "xs = loc"
and "τExec_mover_a P t obj h (stk, loc, pc, xcp) ([v], loc, length (compE2 obj), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (obj∙M'(ps)) h (stk, loc, pc, xcp) ([v], loc, length (compE2 obj), None)"
by-(rule Call_τExecrI1)
also from bisims1_Throw_τExec_movest[OF bisim2[of xs, unfolded ps]]
obtain pc' where exec': "τExec_movest_a P t (map Val vs @ Throw a # es') h ([], xs, 0, None) (Addr a # rev vs, xs, pc', ⌊a⌋)"
and bisim': "P,map Val vs @ Throw a # es',h ⊢ (map Val vs @ Throw a # es', xs) [↔] (Addr a # rev vs, xs, pc', ⌊a⌋)"
by auto
from Call_τExectI2[OF exec', of "obj" M' v] ps
have "τExec_movet_a P t (obj∙M'(ps)) h ([v], loc, length (compE2 obj), None) (Addr a # rev vs @ [v], xs, length (compE2 obj) + pc', ⌊a⌋)" by simp
also from bisim1_bisims1.bisim1CallThrowParams[OF bisim', of obj M' v] ps
have bisim'': "P,obj∙M'(ps),h ⊢ (Throw a, xs) ↔ (Addr a # rev vs @ [v], xs, length (compE2 obj) + pc', ⌊a⌋)" by simp
moreover have "τmove1 P h (obj'∙M'(ps))" using ps by(auto intro: τmove1CallThrowParams)
ultimately show ?thesis by fastforce
next
case (Red1CallExternal a Ta Ts Tr D vs va H')
hence [simp]: "obj' = addr a" "ps = map Val vs"
"e' = extRet2J (addr a∙M'(map Val vs)) va" "H' = h'" "xs' = xs"
and Ta: "typeof_addr h a = ⌊Ta⌋"
and iec: "P ⊢ class_type_of Ta sees M': Ts→Tr = Native in D"
and redex: "P,t ⊢ ⟨a∙M'(vs),h⟩ -ta→ext ⟨va,h'⟩" by auto
from bisim1 have [simp]: "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
have τ: "τmove1 P h (addr a∙M'(map Val vs)) ⟷ τmove2 (compP2 P) h (rev vs @ [Addr a]) (obj∙M'(ps)) (length (compE2 obj) + length (compEs2 ps)) None" using Ta iec
by(auto simp add: map_eq_append_conv τmove1.simps τmoves1.simps τmove2_iff compP2_def)
from bisim1 have s: "xcp = None" "lcl (h, xs) = loc"
and "τExec_mover_a P t obj h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 obj), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (obj∙M'(ps)) h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 obj), None)"
by-(rule Call_τExecrI1)
also have "τExec_movesr_a P t ps h ([], loc, 0, None) (rev vs, loc, length (compEs2 ps), None)"
unfolding ‹ps = map Val vs› by(rule τExec_movesr_map_Val)
from Call_τExecrI2[OF this, of obj M' "Addr a"]
have "τExec_mover_a P t (obj∙M'(ps)) h ([Addr a], loc, length (compE2 obj), None) (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 ps), None)" by simp
also (rtranclp_trans) from bisim1 have "pc ≤ length (compE2 obj)" by(rule bisim1_pc_length_compE2)
hence "no_call2 (obj∙M'(ps)) pc ∨ pc = length (compE2 obj) + length (compEs2 ps)"
using bisim1 by(fastforce simp add: no_call2_def neq_Nil_conv dest: bisim_Val_pc_not_Invoke)
moreover {
assume "pc = length (compE2 obj) + length (compEs2 ps)"
with ‹τExec_mover_a P t obj h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 obj), None)›
have "stk = rev vs @ [Addr a]" "xcp = None" by auto }
moreover
let ?ret = "extRet2JVM (length ps) h' (rev vs @ [Addr a]) loc undefined undefined (length (compE2 obj) + length (compEs2 ps)) [] va"
let ?stk' = "fst (hd (snd (snd ?ret)))"
let ?xcp' = "fst ?ret"
let ?pc' = "snd (snd (snd (snd (hd (snd (snd ?ret))))))"
from redex have redex': "(ta, va, h') ∈ red_external_aggr (compP2 P) t a M' vs h"
by -(rule red_external_imp_red_external_aggr, simp add: compP2_def)
with Ta iec redex'
have "exec_move_a P t (obj∙M'(ps)) h (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 ps), None) (extTA2JVM (compP2 P) ta) h' (?stk', loc, ?pc', ?xcp')"
unfolding exec_move_def
by-(rule exec_instr,cases va,(force simp add: compP2_def simp del: split_paired_Ex)+)
moreover have "P,obj∙M'(ps),h' ⊢ (extRet2J1 (addr a∙M'(map Val vs)) va, loc) ↔ (?stk', loc, ?pc', ?xcp')"
proof(cases va)
case (RetVal v)
have "P,obj∙M'(ps),h' ⊢ (Val v, loc) ↔ ([v], loc, length (compE2 (obj∙M'(ps))), None)"
by(rule bisim1Val2) simp
thus ?thesis unfolding RetVal by simp
next
case (RetExc ad) thus ?thesis by(auto intro: bisim1CallThrow)
next
case RetStaySame
from bisims1_map_Val_append[OF bisims1Nil, of "map Val vs" vs P h' loc]
have "P,map Val vs,h' ⊢ (map Val vs, loc) [↔] (rev vs, loc, length (compEs2 (map Val vs)), None)" by simp
hence "P,obj∙M'(map Val vs),h' ⊢ (addr a∙M'(map Val vs), loc) ↔ (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 (map Val vs)), None)"
by(rule bisim1CallParams)
thus ?thesis using RetStaySame by simp
qed
moreover from redex Ta iec
have "τmove1 P h (addr a∙M'(map Val vs)) ⟹ ta = ε ∧ h' = h"
by(fastforce simp add: τmove1.simps τmoves1.simps map_eq_append_conv τexternal'_def τexternal_def dest: τexternal'_red_external_heap_unchanged τexternal'_red_external_TA_empty sees_method_fun)
ultimately show ?thesis using τ
apply(cases "τmove1 P h (addr a∙M'(map Val vs) :: 'addr expr1)")
apply(auto simp del: split_paired_Ex simp add: compP2_def)
apply(blast intro: rtranclp.rtrancl_into_rtrancl rtranclp_into_tranclp1 τexec_moveI)+
done
next
case (Red1CallNull vs)
note [simp] = ‹h' = h› ‹xs' = xs› ‹ta = ε› ‹obj' = null› ‹ps = map Val vs› ‹e' = THROW NullPointer›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t obj h (stk, loc, pc, xcp) ([Null], loc, length (compE2 obj), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (obj∙M'(map Val vs)) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 obj), None)"
by-(rule Call_τExecrI1)
also have "τExec_movesr_a P t (map Val vs) h ([], loc, 0, None) (rev vs, loc, length (compEs2 (map Val vs)), None)"
proof(cases "vs")
case Nil thus ?thesis by(auto)
next
case Cons
with bisims1_refl[of P "h" "map Val vs" loc, simplified] show ?thesis
by -(drule bisims1_Val_τExec_moves, auto)
qed
from Call_τExecrI2[OF this, of obj M' Null]
have "τExec_mover_a P t (obj∙M'(map Val vs)) h ([Null], loc, length (compE2 obj), None) (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 (map Val vs)), None)" by simp
also (rtranclp_trans) {
have "τmove2 (compP2 P) h (rev vs @ [Null]) (obj∙M'(map Val vs)) (length (compE2 obj) + length (compEs2 (map Val vs))) None"
by(simp add: τmove2_iff)
moreover have "exec_move_a P t (obj∙M'(map Val vs)) h (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 (map Val vs)), None) ε h (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 (map Val vs)), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by(cases vs)(auto intro: exec_instr)
ultimately have "τExec_movet_a P t (obj∙M'(map Val vs)) h (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 (map Val vs)), None) (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 (map Val vs)), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(auto intro: τexec_moveI simp add: compP2_def) }
also have "τmove1 P h (null∙M'(map Val vs))" by(auto simp add: τmove1.simps τmoves1.simps map_eq_append_conv)
moreover have "P,obj∙M'(map Val vs),h ⊢ (THROW NullPointer, loc) ↔ ((rev vs @ [Null]), loc, length (compE2 obj) + length (compEs2 (map Val vs)), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1CallThrow) simp
ultimately show ?thesis using s by(auto simp del: split_paired_Ex)
qed
next
case bisim1Val2 thus ?case by fastforce
next
case (bisim1New C' n xs)
have τ: "¬ τmove1 P h (new C')" by(auto simp add: τmove1.simps τmoves1.simps)
from ‹True,P,t ⊢1 ⟨new C',(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Red1New a)
hence "exec_meth_a (compP2 P) [New C'] [] t h ([], xs, 0, None) ⦃NewHeapElem a (Class_type C')⦄ h' ([Addr a], xs, Suc 0, None)"
and [simp]: "e' = addr a" "xs' = xs" "ta = ⦃NewHeapElem a (Class_type C')⦄"
by (auto intro!: exec_instr simp add: compP2_def simp del: fun_upd_apply cong cong del: image_cong_simp)
moreover have "P, new C', h' ⊢ (addr a, xs) ↔ ([Addr a], xs, length (compE2 (new C')), None)"
by(rule bisim1Val2)(simp)
moreover have "¬ τmove2 (compP2 P) h [] (new C') 0 None" by(simp add: τmove2_iff)
ultimately show ?thesis using τ
by(fastforce simp add: exec_move_def ta_upd_simps)
next
case Red1NewFail
hence "exec_meth_a (compP2 P) [New C'] [] t h ([], xs, 0, None) ε h' ([], xs, 0, ⌊addr_of_sys_xcpt OutOfMemory⌋)"
and [simp]: "ta = ε" "xs' = xs" "e' = THROW OutOfMemory"
by(auto intro!:exec_instr simp add: compP2_def simp del: fun_upd_apply)
moreover have "P, new C', h' ⊢ (THROW OutOfMemory, xs) ↔ ([], xs, 0, ⌊addr_of_sys_xcpt OutOfMemory⌋)"
by(rule bisim1NewThrow)
moreover have "¬ τmove2 (compP2 P) h [] (new C') 0 None" by(simp add: τmove2_iff)
ultimately show ?thesis using τ by(fastforce simp add: exec_move_def)
qed
next
case bisim1NewThrow thus ?case by fastforce
next
case (bisim1NewArray E n e xs stk loc pc xcp U)
note IH = bisim1NewArray.IH(2)
note bisim = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note red = ‹True,P,t ⊢1 ⟨newA U⌊e⌉,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (newA U⌊E⌉) n›
from red show ?case
proof cases
case (New1ArrayRed ee')
note [simp] = ‹e' = newA U⌊ee'⌉›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -ta→ ⟨ee', (h', xs')⟩›
from red have "τmove1 P h (newA U⌊e⌉) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from red have "call1 (newA U⌊e⌉) = call1 e" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h' ⊢ (ee', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta E e ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,newA U⌊E⌉,h' ⊢ (newA U⌊ee'⌉, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1NewArray)
moreover {
assume "no_call2 E pc"
hence "no_call2 (newA U⌊E⌉) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: NewArray_τExecrI NewArray_τExectI exec_move_newArrayI)+
next
case (Red1NewArray i a)
note [simp] = ‹e = Val (Intg i)› ‹ta = ⦃NewHeapElem a (Array_type U (nat (sint i)))⦄› ‹e' = addr a› ‹xs' = xs›
and new = ‹(h', a) ∈ allocate h (Array_type U (nat (sint i)))›
from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
from bisim have "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Intg i], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (newA U⌊E⌉) h (stk, loc, pc, xcp) ([Intg i], loc, length (compE2 E), None)"
by(rule NewArray_τExecrI)
moreover from new ‹0 <=s i›
have "exec_move_a P t (newA U⌊E⌉) h ([Intg i], loc, length (compE2 E), None) ⦃NewHeapElem a (Array_type U (nat (sint i)))⦄ h' ([Addr a], loc, Suc (length (compE2 E)), None)"
by (auto intro!: exec_instr simp add: compP2_def exec_move_def cong del: image_cong_simp)
moreover have "τmove2 (compP2 P) h [Intg i] (newA U⌊E⌉) (length (compE2 E)) None ⟹ False" by(simp add: τmove2_iff)
moreover have "¬ τmove1 P h (newA U⌊Val (Intg i)⌉)" by(auto simp add: τmove1.simps τmoves1.simps)
moreover have "P, newA U⌊E⌉, h' ⊢ (addr a, loc) ↔ ([Addr a], loc, length (compE2 (newA U⌊E⌉)), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s by(auto simp del: fun_upd_apply simp add: ta_upd_simps) blast
next
case (Red1NewArrayNegative i)
note [simp] = ‹e = Val (Intg i)› ‹e' = THROW NegativeArraySize› ‹h' = h› ‹xs' = xs› ‹ta = ε›
have "¬ τmove1 P h (newA U⌊Val (Intg i)⌉)" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from bisim have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Intg i], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
moreover from ‹i <s 0›
have "exec_meth_a (compP2 P) (compE2 (newA U⌊E⌉)) (compxE2 (newA U⌊E⌉) 0 0) t h ([Intg i], loc, length (compE2 E), None) ε h ([Intg i], loc, length (compE2 E), ⌊addr_of_sys_xcpt NegativeArraySize⌋)"
by -(rule exec_instr, auto simp add: compP2_def)
moreover have "τmove2 (compP2 P) h [Intg i] (newA U⌊E⌉) (length (compE2 E)) None ⟹ False" by(simp add: τmove2_iff)
moreover
have "P,newA U⌊E⌉,h ⊢ (THROW NegativeArraySize, loc) ↔ ([Intg i], loc, length (compE2 E), ⌊addr_of_sys_xcpt NegativeArraySize⌋)"
by(auto intro!: bisim1_bisims1.bisim1NewArrayFail)
ultimately show ?thesis using s
by(auto simp add: exec_move_def)(blast intro: NewArray_τExecrI)
next
case (Red1NewArrayFail i)
note [simp] = ‹e = Val (Intg i)› ‹e' = THROW OutOfMemory› ‹xs' = xs› ‹ta = ε› ‹h' = h›
and new = ‹allocate h (Array_type U (nat (sint i))) = {}›
have "¬ τmove1 P h (newA U⌊Val (Intg i)⌉)" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from bisim have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Intg i], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
moreover from ‹0 <=s i› new
have "exec_meth_a (compP2 P) (compE2 (newA U⌊E⌉)) (compxE2 (newA U⌊E⌉) 0 0) t h ([Intg i], loc, length (compE2 E), None) ε h' ([Intg i], loc, length (compE2 E), ⌊addr_of_sys_xcpt OutOfMemory⌋)"
by -(rule exec_instr, auto simp add: compP2_def)
moreover have "τmove2 (compP2 P) h [Intg i] (newA U⌊E⌉) (length (compE2 E)) None ⟹ False" by(simp add: τmove2_iff)
moreover
have "P,newA U⌊E⌉,h' ⊢ (THROW OutOfMemory, loc) ↔ ([Intg i], loc, length (compE2 E), ⌊addr_of_sys_xcpt OutOfMemory⌋)"
by(auto intro!: bisim1_bisims1.bisim1NewArrayFail)
ultimately show ?thesis using s by (auto simp add: exec_move_def)(blast intro: NewArray_τExecrI)
next
case (New1ArrayThrow a)
note [simp] = ‹e = Throw a› ‹h' = h› ‹xs' = xs› ‹ta = ε› ‹e' = Throw a›
have τ: "τmove1 P h (newA U⌊e⌉)" by(auto intro: τmove1NewArrayThrow)
from bisim have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim have "P,newA U⌊E⌉, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1_bisims1.bisim1NewArrayThrow)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim obtain pc'
where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (newA U⌊E⌉) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule NewArray_τExecrI)
moreover from bisim' have "P, newA U⌊E⌉, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by(rule bisim1_bisims1.bisim1NewArrayThrow)
ultimately show ?thesis using τ by auto
qed
qed
next
case bisim1NewArrayThrow thus ?case by auto
next
case bisim1NewArrayFail thus ?case by auto
next
case (bisim1Cast E n e xs stk loc pc xcp U)
note IH = bisim1Cast.IH(2)
note bisim = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note red = ‹True,P,t ⊢1 ⟨Cast U e,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (Cast U E) n›
from red show ?case
proof cases
case (Cast1Red ee')
note [simp] = ‹e' = Cast U ee'›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -ta→ ⟨ee', (h', xs')⟩›
from red have "τmove1 P h (Cast U e) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from red have "call1 (Cast U e) = call1 e" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h' ⊢ (ee', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta E e ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,Cast U E,h' ⊢ (Cast U ee', xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1Cast)
moreover {
assume "no_call2 E pc"
hence "no_call2 (Cast U E) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Cast_τExecrI Cast_τExectI exec_move_CastI)+
next
case (Red1Cast c U')
hence [simp]: "e = Val c" "ta = ε" "e' = Val c" "h' = h" "xs' = xs"
and type: "typeof⇘h⇙ c = ⌊U'⌋" "P ⊢ U' ≤ U" by auto
from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
from bisim have "τExec_mover_a P t E h (stk, loc, pc, xcp) ([c], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (Cast U E) h (stk, loc, pc, xcp) ([c], loc, length (compE2 E), None)"
by(rule Cast_τExecrI)
moreover from type
have "exec_meth_a (compP2 P) (compE2 (Cast U E)) (compxE2 (Cast U E) 0 0) t h ([c], loc, length (compE2 E), None) ε h' ([c], loc, Suc (length (compE2 E)), None)"
by(auto intro!: exec_instr simp add: compP2_def)
moreover have "τmove2 (compP2 P) h [c] (Cast U E) (length (compE2 E)) None" by(simp add: τmove2_iff)
ultimately have "τExec_mover_a P t (Cast U E) h (stk, loc, pc, xcp) ([c], loc, Suc (length (compE2 E)), None)"
by(fastforce elim: rtranclp.rtrancl_into_rtrancl intro: τexec_moveI simp add: exec_move_def compP2_def)
moreover have "τmove1 P h (Cast U (Val c))" by(rule τmove1CastRed)
moreover
have "P, Cast U E, h' ⊢ (Val c, loc) ↔ ([c], loc, length (compE2 (Cast U E)), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s by(auto simp add: exec_move_def)
next
case (Red1CastFail v U')
note [simp] = ‹e = Val v› ‹e' = THROW ClassCast› ‹h' = h› ‹xs' = xs› ‹ta = ε›
moreover from bisim have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (Cast U E) h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
by(auto elim: Cast_τExecrI)
moreover from ‹typeof⇘hp (h, xs)⇙ v = ⌊U'⌋› ‹¬ P ⊢ U' ≤ U›
have "exec_meth_a (compP2 P) (compE2 (Cast U E)) (compxE2 (Cast U E) 0 0) t h ([v], loc, length (compE2 E), None) ε h ([v], loc, length (compE2 E), ⌊addr_of_sys_xcpt ClassCast⌋)"
by -(rule exec_instr, auto simp add: compP2_def)
moreover have "τmove2 (compP2 P) h [v] (Cast U E) (length (compE2 E)) None" by(simp add: τmove2_iff)
ultimately have "τExec_movet_a P t (Cast U E) h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), ⌊addr_of_sys_xcpt ClassCast⌋)"
by(fastforce simp add: exec_move_def compP2_def intro: rtranclp_into_tranclp1 τexec_moveI)
moreover have "τmove1 P h (Cast U (Val v))" by(rule τmove1CastRed)
moreover
have "P,Cast U E,h ⊢ (THROW ClassCast, loc) ↔ ([v], loc, length (compE2 E), ⌊addr_of_sys_xcpt ClassCast⌋)"
by(auto intro!: bisim1_bisims1.bisim1CastFail)
ultimately show ?thesis using s by(auto simp add: exec_move_def)
next
case [simp]: (Cast1Throw a)
have τ: "τmove1 P h (Cast U e)" by(auto intro: τmove1CastThrow)
from bisim have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim have "P,Cast U E, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1_bisims1.bisim1CastThrow)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim obtain pc'
where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (Cast U E) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule Cast_τExecrI)
moreover from bisim' have "P, Cast U E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by-(rule bisim1_bisims1.bisim1CastThrow, auto)
ultimately show ?thesis using τ by auto
qed
qed
next
case bisim1CastThrow thus ?case by auto
next
case bisim1CastFail thus ?case by auto
next
case (bisim1InstanceOf E n e xs stk loc pc xcp U)
note IH = bisim1InstanceOf(2)
note bisim = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note red = ‹True,P,t ⊢1 ⟨e instanceof U,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (E instanceof U) n›
from red show ?case
proof cases
case (InstanceOf1Red ee')
note [simp] = ‹e' = ee' instanceof U›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -ta→ ⟨ee', (h', xs')⟩›
from red have "τmove1 P h (e instanceof U) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from red have "call1 (e instanceof U) = call1 e" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h' ⊢ (ee', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta E e ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,E instanceof U,h' ⊢ (ee' instanceof U, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1InstanceOf)
moreover {
assume "no_call2 E pc"
hence "no_call2 (E instanceof U) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: InstanceOf_τExecrI InstanceOf_τExectI exec_move_InstanceOfI)+
next
case (Red1InstanceOf c U' b)
hence [simp]: "e = Val c" "ta = ε" "e' = Val (Bool (c ≠ Null ∧ P ⊢ U' ≤ U))" "h' = h" "xs' = xs"
"b = (c ≠ Null ∧ P ⊢ U' ≤ U)"
and type: "typeof⇘h⇙ c = ⌊U'⌋" by auto
from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
from bisim have "τExec_mover_a P t E h (stk, loc, pc, xcp) ([c], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (E instanceof U) h (stk, loc, pc, xcp) ([c], loc, length (compE2 E), None)"
by(rule InstanceOf_τExecrI)
moreover from type
have "exec_meth_a (compP2 P) (compE2 (E instanceof U)) (compxE2 (E instanceof U) 0 0) t h ([c], loc, length (compE2 E), None) ε h' ([Bool b], loc, Suc (length (compE2 E)), None)"
by(auto intro!: exec_instr simp add: compP2_def)
moreover have "τmove2 (compP2 P) h [c] (E instanceof U) (length (compE2 E)) None" by(simp add: τmove2_iff)
ultimately have "τExec_mover_a P t (E instanceof U) h (stk, loc, pc, xcp) ([Bool b], loc, Suc (length (compE2 E)), None)"
by(fastforce elim: rtranclp.rtrancl_into_rtrancl intro: τexec_moveI simp add: exec_move_def compP2_def)
moreover have "τmove1 P h ((Val c) instanceof U)" by(rule τmove1InstanceOfRed)
moreover
have "P, E instanceof U, h' ⊢ (Val (Bool b), loc) ↔ ([Bool b], loc, length (compE2 (E instanceof U)), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s by(auto simp add: exec_move_def)
next
case (InstanceOf1Throw a)
note [simp] = ‹e = Throw a› ‹h' = h› ‹xs' = xs› ‹ta = ε› ‹e' = Throw a›
have τ: "τmove1 P h (e instanceof U)" by(auto intro: τmove1InstanceOfThrow)
from bisim have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim have "P,E instanceof U, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1_bisims1.bisim1InstanceOfThrow)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim obtain pc'
where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (E instanceof U) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule InstanceOf_τExecrI)
moreover from bisim' have "P, E instanceof U, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by-(rule bisim1_bisims1.bisim1InstanceOfThrow, auto)
ultimately show ?thesis using τ by auto
qed
qed
next
case bisim1InstanceOfThrow thus ?case by auto
next
case bisim1Val thus ?case by fastforce
next
case (bisim1Var V n xs)
from ‹True,P,t ⊢1 ⟨Var V,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Red1Var v)
hence "exec_meth_a (compP2 P) [Load V] [] t h ([], xs, 0, None) ε h ([v], xs, 1, None)"
and [simp]: "ta = ε" "h' = h" "xs' = xs" "e' = Val v"
by(auto intro: exec_instr)
moreover have "τmove2 (compP2 P) h [] (Var V) 0 None" by(simp add: τmove2_iff)
ultimately have "τExec_movet_a P t (Var V) h ([], xs, 0, None) ([v], xs, 1, None)"
by(auto intro: τExect1step simp add: exec_move_def compP2_def)
moreover have "P, Var V, h ⊢ (Val v, xs) ↔ ([v], xs, length (compE2 (Var V)), None)"
by(rule bisim1Val2) simp
moreover have "τmove1 P h (Var V)" by(rule τmove1Var)
ultimately show ?thesis by(fastforce)
qed
next
case (bisim1BinOp1 e1 n e1' xs stk loc pc xcp e2 bop)
note IH1 = bisim1BinOp1.IH(2)
note IH2 = bisim1BinOp1.IH(4)
note bisim1 = ‹P,e1,h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok (e1 «bop» e2) n›
from ‹True,P,t ⊢1 ⟨e1' «bop» e2,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Bin1OpRed1 E')
note [simp] = ‹e' = E' «bop» e2›
and red = ‹True,P,t ⊢1 ⟨e1',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have "τmove1 P h (e1' «bop» e2) = τmove1 P h e1'" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from red have "call1 (e1' «bop» e2) = call1 e1'" by auto
moreover from IH1[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,e1,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta e1 e1' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,e1«bop»e2,h' ⊢ (E'«bop»e2, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1BinOp1)
moreover {
assume "no_call2 e1 pc"
hence "no_call2 (e1«bop»e2) pc ∨ pc = length (compE2 e1)" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: BinOp_τExecrI1 BinOp_τExectI1 exec_move_BinOpI1)+
next
case (Bin1OpRed2 E' v)
note [simp] = ‹e1' = Val v› ‹e' = Val v «bop» E'›
and red = ‹True,P,t ⊢1 ⟨e2,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v «bop» e2) = τmove1 P h e2" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t e1 h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
from exec1 have "τExec_mover_a P t (e1«bop»e2) h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
by(rule BinOp_τExecrI1)
moreover
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e2,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e2 e2 E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (e1«bop»e2) (Val v«bop»e2) (Val v«bop»E') h ([] @ [v]) xs (length (compE2 e1) + 0) None h' (length (compE2 e1) + pc'') (stk'' @ [v]) loc'' xcp''"
proof(cases "τmove1 P h (Val v «bop» e2)")
case True
with exec' τ have [simp]: "h = h'" and e: "sim_move e2 E' P t e2 h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (Val v«bop»e2) (Val v«bop»E') P t (e1 «bop» e2) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
by(fastforce dest: BinOp_τExecrI2 BinOp_τExectI2)
with True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t e2 h ([], xs, 0, None) (stk', loc', pc', xcp')"
and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'"
and call: "call1 e2 = None ∨ no_call2 e2 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs ∧ xcp' = None" by auto
from e have "τExec_mover_a P t (e1 «bop» e2) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk' @ [v], loc', length (compE2 e1) + pc', xcp')" by(rule BinOp_τExecrI2)
moreover from e' have "exec_move_a P t (e1 «bop» e2) h (stk' @ [v], loc', length (compE2 e1) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
by(rule exec_move_BinOpI2)
moreover from e' have "pc' < length (compE2 e2)" by auto
with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v]) (e1 «bop» e2) (length (compE2 e1) + pc') xcp'"
by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
moreover from red have "call1 (e1'«bop»e2) = call1 e2" by(auto)
moreover have "no_call2 e2 0 ⟹ no_call2 (e1«bop»e2) (length (compE2 e1))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call
by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P,e1«bop»e2,h' ⊢ (Val v«bop»E', xs') ↔ ((stk'' @ [v]), loc'', length (compE2 e1) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1BinOp2)
moreover from bisim1 have "pc ≠ length (compE2 e1) ⟶ no_call2 (e1«bop»e2) pc"
by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
ultimately show ?thesis using τ exec1 s
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
done
next
case (Red1BinOp v1 v2 v)
note [simp] = ‹e1' = Val v1› ‹e2 = Val v2› ‹ta = ε› ‹e' = Val v› ‹h' = h› ‹xs' = xs›
and binop = ‹binop bop v1 v2 = ⌊Inl v⌋›
have τ: "τmove1 P h (Val v1 «bop» Val v2)" by(rule τmove1BinOp)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v1], loc, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1«bop»Val v2) h (stk, loc, pc, xcp) ([v1], loc, length (compE2 e1), None)"
by-(rule BinOp_τExecrI1)
also have "τmove2 (compP2 P) h [v1] (e1 «bop» Val v2) (length (compE2 e1) + 0) None"
by(rule τmove2BinOp2)(rule τmove2Val)
with binop have "τExec_mover_a P t (e1«bop»Val v2) h ([v1], loc, length (compE2 e1), None) ([v2, v1], loc, Suc (length (compE2 e1)), None)"
by-(rule τExecr1step, auto intro!: exec_instr simp add: exec_move_def compP2_def)
also (rtranclp_trans) from binop
have "exec_meth_a (compP2 P) (compE2 (e1«bop»Val v2)) (compxE2 (e1«bop»Val v2) 0 0) t
h ([v2, v1], loc, Suc (length (compE2 e1)), None) ε
h ([v], loc, Suc (Suc (length (compE2 e1))), None)"
by-(rule exec_instr, auto)
moreover have "τmove2 (compP2 P) h [v2, v1] (e1«bop»Val v2) (Suc (length (compE2 e1))) None" by(simp add: τmove2_iff)
ultimately have "τExec_mover_a P t (e1 «bop» Val v2) h (stk, loc, pc, xcp) ([v], loc, Suc (Suc (length (compE2 e1))), None)"
by(fastforce intro: rtranclp.rtrancl_into_rtrancl τexec_moveI simp add: exec_move_def compP2_def)
moreover
have "P, e1 «bop» Val v2, h ⊢ (Val v, loc) ↔ ([v], loc, length (compE2 (e1 «bop» Val v2)), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s τ by auto
next
case (Red1BinOpFail v1 v2 a)
note [simp] = ‹e1' = Val v1› ‹e2 = Val v2› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
and binop = ‹binop bop v1 v2 = ⌊Inr a⌋›
have τ: "τmove1 P h (Val v1 «bop» Val v2)" by(rule τmove1BinOp)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v1], loc, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1«bop»Val v2) h (stk, loc, pc, xcp) ([v1], loc, length (compE2 e1), None)"
by-(rule BinOp_τExecrI1)
also have "τmove2 (compP2 P) h [v1] (e1 «bop» Val v2) (length (compE2 e1) + 0) None"
by(rule τmove2BinOp2)(rule τmove2Val)
with binop have "τExec_mover_a P t (e1«bop»Val v2) h ([v1], loc, length (compE2 e1), None) ([v2, v1], loc, Suc (length (compE2 e1)), None)"
by-(rule τExecr1step, auto intro!: exec_instr simp add: exec_move_def compP2_def)
also (rtranclp_trans) from binop
have "exec_meth_a (compP2 P) (compE2 (e1«bop»Val v2)) (compxE2 (e1«bop»Val v2) 0 0) t
h ([v2, v1], loc, Suc (length (compE2 e1)), None) ε
h ([v2, v1], loc, Suc (length (compE2 e1)), ⌊a⌋)"
by-(rule exec_instr, auto)
moreover have "τmove2 (compP2 P) h [v2, v1] (e1«bop»Val v2) (Suc (length (compE2 e1))) None" by(simp add: τmove2_iff)
ultimately have "τExec_movet_a P t (e1 «bop» Val v2) h (stk, loc, pc, xcp) ([v2, v1], loc, Suc (length (compE2 e1)), ⌊a⌋)"
by(fastforce intro: rtranclp_into_tranclp1 τexec_moveI simp add: exec_move_def compP2_def)
moreover
have "P, e1 «bop» Val v2, h ⊢ (Throw a, loc) ↔ ([v2, v1], loc, length (compE2 e1) + length (compE2 (Val v2)), ⌊a⌋)"
by(rule bisim1BinOpThrow)
ultimately show ?thesis using s τ by auto
next
case (Bin1OpThrow1 a)
note [simp] = ‹e1' = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (Throw a «bop» e2)" by(rule τmove1BinOpThrow1)
from bisim1 have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim1 have "P, e1«bop»e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1_bisims1.intros)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim1 obtain pc' where "τExec_mover_a P t e1 h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, e1, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (e1«bop»e2) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule BinOp_τExecrI1)
moreover from bisim'
have "P, e1«bop»e2, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by(auto intro: bisim1_bisims1.bisim1BinOpThrow1)
ultimately show ?thesis using τ by auto
qed
next
case (Bin1OpThrow2 v a)
note [simp] = ‹e1' = Val v› ‹e2 = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1«bop»Throw a) h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
by-(rule BinOp_τExecrI1)
also have "τExec_mover_a P t (e1«bop»Throw a) h ([v], loc, length (compE2 e1), None) ([Addr a, v], loc, Suc (length (compE2 e1)), ⌊a⌋)"
by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
also (rtranclp_trans)
have "P,e1«bop»Throw a,h ⊢ (Throw a, loc) ↔ ([Addr a] @ [v], loc, (length (compE2 e1) + length (compE2 (addr a))), ⌊a⌋)"
by(rule bisim1BinOpThrow2[OF bisim1Throw2])
moreover have "τmove1 P h (e1' «bop» e2)" by(auto intro: τmove1BinOpThrow2)
ultimately show ?thesis using s by auto
qed
next
case (bisim1BinOp2 e2 n e2' xs stk loc pc xcp e1 bop v1)
note IH2 = bisim1BinOp2.IH(2)
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
note red = ‹True,P,t ⊢1 ⟨Val v1 «bop» e2',(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (e1 «bop» e2) n›
from red show ?case
proof cases
case (Bin1OpRed2 E')
note [simp] = ‹e' = Val v1 «bop» E'›
and red = ‹True,P,t ⊢1 ⟨e2',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e2,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e2 e2' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from red have τ: "τmove1 P h (Val v1 «bop» e2') = τmove1 P h e2'" by(auto simp add: τmove1.simps τmoves1.simps)
have "no_call2 e2 pc ⟹ no_call2 (e1 «bop» e2) (length (compE2 e1) + pc)" by(auto simp add: no_call2_def)
hence "?exec ta (e1«bop»e2) (Val v1«bop»e2') (Val v1«bop»E') h (stk @ [v1]) loc (length (compE2 e1) + pc) xcp h' (length (compE2 e1) + pc'') (stk'' @ [v1]) loc'' xcp''"
using exec' τ
apply(cases "τmove1 P h (Val v1 «bop» e2')")
apply(auto)
apply(blast intro: BinOp_τExecrI2 BinOp_τExectI2 exec_move_BinOpI2)
apply(blast intro: BinOp_τExecrI2 BinOp_τExectI2 exec_move_BinOpI2)
apply(rule exI conjI BinOp_τExecrI2 exec_move_BinOpI2|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
apply(rule exI conjI BinOp_τExecrI2 exec_move_BinOpI2|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
apply(rule exI conjI BinOp_τExecrI2 exec_move_BinOpI2 rtranclp.rtrancl_refl|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)+
done
moreover from bisim'
have "P,e1«bop»e2,h' ⊢ (Val v1«bop»E', xs') ↔ (stk''@[v1], loc'', length (compE2 e1) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1BinOp2)
ultimately show ?thesis using τ by auto blast+
next
case (Red1BinOp v2 v)
note [simp] = ‹e2' = Val v2› ‹ta = ε› ‹e' = Val v› ‹h' = h› ‹xs' = xs›
and binop = ‹binop bop v1 v2 = ⌊Inl v⌋›
have τ: "τmove1 P h (Val v1 «bop» Val v2)" by(rule τmove1BinOp)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v2], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1«bop»e2) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v2] @ [v1], loc, length (compE2 e1) + length (compE2 e2), None)"
by-(rule BinOp_τExecrI2)
moreover from binop
have "exec_move_a P t (e1«bop»e2) h ([v2, v1], loc, length (compE2 e1) + length (compE2 e2), None) ε
h ([v], loc, Suc (length (compE2 e1) + length (compE2 e2)), None)"
unfolding exec_move_def by-(rule exec_instr, auto)
moreover have "τmove2 (compP2 P) h [v2, v1] (e1«bop»e2) (length (compE2 e1) + length (compE2 e2)) None"
by(simp add: τmove2_iff)
ultimately have "τExec_mover_a P t (e1 «bop» e2) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v], loc, Suc (length (compE2 e1) + length (compE2 e2)), None)"
by(auto intro: rtranclp.rtrancl_into_rtrancl τexec_moveI simp add: compP2_def)
moreover
have "P, e1 «bop» e2, h ⊢ (Val v, loc) ↔ ([v], loc, length (compE2 (e1 «bop» e2)), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s τ by(auto)
next
case (Red1BinOpFail v2 a)
note [simp] = ‹e2' = Val v2› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
and binop = ‹binop bop v1 v2 = ⌊Inr a⌋›
have τ: "τmove1 P h (Val v1 «bop» Val v2)" by(rule τmove1BinOp)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v2], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1«bop»e2) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v2] @ [v1], loc, length (compE2 e1) + length (compE2 e2), None)"
by-(rule BinOp_τExecrI2)
moreover from binop
have "exec_move_a P t (e1«bop»e2) h ([v2, v1], loc, length (compE2 e1) + length (compE2 e2), None) ε
h ([v2, v1], loc, length (compE2 e1) + length (compE2 e2), ⌊a⌋)"
unfolding exec_move_def by-(rule exec_instr, auto)
moreover have "τmove2 (compP2 P) h [v2, v1] (e1«bop»e2) (length (compE2 e1) + length (compE2 e2)) None"
by(simp add: τmove2_iff)
ultimately have "τExec_movet_a P t (e1 «bop» e2) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v2, v1], loc, length (compE2 e1) + length (compE2 e2), ⌊a⌋)"
by(auto intro: rtranclp_into_tranclp1 τexec_moveI simp add: compP2_def)
moreover
have "P, e1 «bop» e2, h ⊢ (Throw a, loc) ↔ ([v2, v1], loc, length (compE2 e1) + length (compE2 e2), ⌊a⌋)"
by(rule bisim1BinOpThrow)
ultimately show ?thesis using s τ by(auto)
next
case (Bin1OpThrow2 a)
note [simp] = ‹e2' = Throw a› ‹ta = ε› ‹h' = h› ‹xs' = xs› ‹e' = Throw a›
have τ: "τmove1 P h (Val v1 «bop» Throw a)" by(rule τmove1BinOpThrow2)
from bisim2 have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim2
have "P, e1«bop»e2, h ⊢ (Throw a, xs) ↔ (stk @ [v1], loc, length (compE2 e1) + pc, xcp)"
by(auto intro: bisim1BinOpThrow2)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim2 obtain pc'
where "τExec_mover_a P t e2 h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, e2, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (e1«bop»e2) h (stk @ [v1], loc, length (compE2 e1) + pc, None) ([Addr a] @ [v1], loc, length (compE2 e1) + pc', ⌊a⌋)"
by-(rule BinOp_τExecrI2)
moreover from bisim'
have "P, e1«bop»e2, h ⊢ (Throw a, xs) ↔ ([Addr a]@[v1], loc, length (compE2 e1) + pc', ⌊a⌋)"
by-(rule bisim1BinOpThrow2, auto)
ultimately show ?thesis using τ by auto
qed
qed auto
next
case bisim1BinOpThrow1 thus ?case by fastforce
next
case bisim1BinOpThrow2 thus ?case by fastforce
next
case bisim1BinOpThrow thus ?case by fastforce
next
case (bisim1LAss1 E n e xs stk loc pc xcp V)
note IH = bisim1LAss1.IH(2)
note bisim = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note red = ‹True,P,t ⊢1 ⟨V:=e,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (V:=E) n›
from red show ?case
proof cases
case (LAss1Red ee')
note [simp] = ‹e' = V := ee'›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -ta→ ⟨ee', (h', xs')⟩›
from red have "τmove1 P h (V:=e) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from red have "call1 (V:=e) = call1 e" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h' ⊢ (ee', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta E e ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,V:=E,h' ⊢ (V:=ee', xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1LAss1)
moreover {
assume "no_call2 E pc"
hence "no_call2 (V:=E) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: LAss_τExecrI LAss_τExectI exec_move_LAssI)+
next
case (Red1LAss v)
note [simp] = ‹e = Val v› ‹ta = ε› ‹e' = unit› ‹h' = h› ‹xs' = xs[V := v]›
and V = ‹V < length xs›
from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
from bisim have "τExec_mover_a P t E h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (V:=E) h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
by(rule LAss_τExecrI)
moreover have "exec_move_a P t (V:=E) h ([v], loc, length (compE2 E), None) ε h ([], loc[V := v], Suc (length (compE2 E)), None)"
using V s by(auto intro: exec_instr simp add: exec_move_def)
moreover have "τmove2 (compP2 P) h [v] (V := E) (length (compE2 E)) None" by(simp add: τmove2_iff)
ultimately have "τExec_mover_a P t (V:=E) h (stk, loc, pc, xcp) ([], loc[V := v], Suc (length (compE2 E)), None)"
by(auto intro: rtranclp.rtrancl_into_rtrancl τexec_moveI simp add: compP2_def)
moreover have "τmove1 P h (V := Val v)" by(rule τmove1LAssRed)
moreover have "P, V:=E, h ⊢ (unit, loc[V := v]) ↔ ([], loc[V := v], Suc (length (compE2 E)), None)"
by(rule bisim1LAss2)
ultimately show ?thesis using s by auto
next
case (LAss1Throw a)
note [simp] = ‹e = Throw a› ‹h' = h› ‹xs' = xs› ‹ta = ε› ‹e' = Throw a›
have τ: "τmove1 P h (V:=e)" by(auto intro: τmove1LAssThrow)
from bisim have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim have "P, V:=E, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, xcp)" by(auto intro: bisim1LAssThrow)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim obtain pc'
where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (V:=E) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule LAss_τExecrI)
moreover from bisim' have "P, V:=E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by-(rule bisim1LAssThrow, auto)
ultimately show ?thesis using τ by auto
qed
qed
next
case bisim1LAss2 thus ?case by fastforce
next
case bisim1LAssThrow thus ?case by fastforce
next
case (bisim1AAcc1 a n a' xs stk loc pc xcp i)
note IH1 = bisim1AAcc1.IH(2)
note IH2 = bisim1AAcc1.IH(4)
note bisim1 = ‹P,a,h ⊢ (a', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹⋀xs. P,i,h ⊢ (i, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok (a⌊i⌉) n›
from ‹True,P,t ⊢1 ⟨a'⌊i⌉,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (AAcc1Red1 E')
note [simp] = ‹e' = E'⌊i⌉›
and red = ‹True,P,t ⊢1 ⟨a',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have "τmove1 P h (a'⌊i⌉) = τmove1 P h a'" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from red have "call1 (a'⌊i⌉) = call1 a'" by auto
moreover from IH1[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,a,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta a a' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim have "P,a⌊i⌉,h' ⊢ (E'⌊i⌉, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1AAcc1)
moreover {
assume "no_call2 a pc"
hence "no_call2 (a⌊i⌉) pc ∨ pc = length (compE2 a)" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: AAcc_τExecrI1 AAcc_τExectI1 exec_move_AAccI1)+
next
case (AAcc1Red2 E' v)
note [simp] = ‹a' = Val v› ‹e' = Val v⌊E'⌉›
and red = ‹True,P,t ⊢1 ⟨i,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v⌊i⌉) = τmove1 P h i" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t a h (stk, loc, pc, None) ([v], xs, length (compE2 a), None)"
by(auto dest: bisim1Val2D1)
from exec1 have "τExec_mover_a P t (a⌊i⌉) h (stk, loc, pc, None) ([v], xs, length (compE2 a), None)"
by(rule AAcc_τExecrI1)
moreover
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,i,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta i i E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (a⌊i⌉) (Val v⌊i⌉) (Val v⌊E'⌉) h ([] @ [v]) xs (length (compE2 a) + 0) None h' (length (compE2 a) + pc'') (stk'' @ [v]) loc'' xcp''"
proof(cases "τmove1 P h (Val v⌊i⌉)")
case True
with exec' τ have [simp]: "h = h'" and e: "sim_move i E' P t i h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (a⌊i⌉) (a⌊E'⌉) P t (a⌊i⌉) h ([] @ [v], xs, length (compE2 a) + 0, None) (stk'' @ [v], loc'', length (compE2 a) + pc'', xcp'')"
by(fastforce dest: AAcc_τExecrI2 AAcc_τExectI2)
with True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t i h ([], xs, 0, None) (stk', loc', pc', xcp')"
and e': "exec_move_a P t i h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' i pc' xcp'"
and call: "call1 i = None ∨ no_call2 i 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs ∧ xcp' = None" by auto
from e have "τExec_mover_a P t (a⌊i⌉) h ([] @ [v], xs, length (compE2 a) + 0, None) (stk' @ [v], loc', length (compE2 a) + pc', xcp')"
by(rule AAcc_τExecrI2)
moreover from e' have "exec_move_a P t (a⌊i⌉) h (stk' @ [v], loc', length (compE2 a) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 a) + pc'', xcp'')"
by(rule exec_move_AAccI2)
moreover from e' τ' have "¬ τmove2 (compP2 P) h (stk' @ [v]) (a⌊i⌉) (length (compE2 a) + pc') xcp'"
by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
moreover have "call1 (a'⌊i⌉) = call1 i" by simp
moreover have "no_call2 i 0 ⟹ no_call2 (a⌊i⌉) (length (compE2 a))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call
by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P,a⌊i⌉,h' ⊢ (Val v⌊E'⌉, xs') ↔ ((stk'' @ [v]), loc'', length (compE2 a) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1AAcc2)
moreover from bisim1 have "pc ≠ length (compE2 a) ⟶ no_call2 (a⌊i⌉) pc"
by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
ultimately show ?thesis using τ exec1 s
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
done
next
case (Red1AAcc A U len I v)
hence [simp]: "a' = addr A" "e' = Val v" "i = Val (Intg I)" "h' = h" "xs' = xs"
"ta = ⦃ReadMem A (ACell (nat (sint I))) v⦄"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "0 <=s I" "sint I < int len"
and read: "heap_read h A (ACell (nat (sint I))) v" by auto
have τ: "¬ τmove1 P h (addr A⌊Val (Intg I)⌉)" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊Val (Intg I)⌉) h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
by-(rule AAcc_τExecrI1)
also have "τmove2 (compP2 P) h [Addr A] (a⌊Val (Intg I)⌉) (length (compE2 a) + 0) None"
by(rule τmove2AAcc2)(rule τmove2Val)
hence "τExec_mover_a P t (a⌊Val (Intg I)⌉) h ([Addr A], loc, length (compE2 a), None) ([Intg I, Addr A], loc, Suc (length (compE2 a)), None)"
by-(rule τExecr1step, auto intro!: exec_instr simp add: exec_move_def compP2_def)
also (rtranclp_trans) from hA I read
have "exec_move_a P t (a⌊Val (Intg I)⌉) h ([Intg I, Addr A], loc, Suc (length (compE2 a)), None)
⦃ReadMem A (ACell (nat (sint I))) v⦄
h ([v], loc, Suc (Suc (length (compE2 a))), None)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [Intg I, Addr A] (a⌊Val (Intg I)⌉) (Suc (length (compE2 a))) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊Val (Intg I)⌉, h ⊢ (Val v, loc) ↔ ([v], loc, length (compE2 (a⌊Val (Intg I)⌉)), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s τ
by(auto simp add: ta_upd_simps) blast
next
case (Red1AAccNull v)
note [simp] = ‹a' = null› ‹i = Val v› ‹ta = ε› ‹e' = THROW NullPointer› ‹h' = h› ‹xs' = xs›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([Null], loc, length (compE2 a), None)"
by(auto dest: bisim1Val2D1 intro: AAcc_τExecrI1)
hence "τExec_mover_a P t (a⌊i⌉) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 a), None)"
by-(rule AAcc_τExecrI1)
also from bisim2[of loc] have "τExec_mover_a P t i h ([], loc, 0, None) ([v], loc, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉) h ([] @ [Null], loc, length (compE2 a) + 0, None) ([v] @ [Null], loc, length (compE2 a) + length (compE2 i), None)"
by(rule AAcc_τExecrI2)
hence "τExec_mover_a P t (a⌊i⌉) h ([Null], loc, length (compE2 a), None) ([v, Null], loc, length (compE2 a) + length (compE2 i), None)" by simp
also (rtranclp_trans) have "exec_move_a P t (a⌊i⌉) h ([v, Null], loc, length (compE2 a) + length (compE2 i), None) ε h ([v, Null], loc, length (compE2 a) + length (compE2 i), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by-(rule exec_instr, auto)
moreover have "¬ τmove2 (compP2 P) h [v, Null] (a⌊i⌉) (length (compE2 a) + length (compE2 i)) None"
by(simp add: τmove2_iff)
moreover have "¬ τmove1 P h (a'⌊i⌉)" by(auto simp add: τmove1.simps τmoves1.simps)
moreover
have "P,a⌊i⌉,h ⊢ (THROW NullPointer, xs) ↔ ([v, Null], xs, length (compE2 a) + length (compE2 i), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1_bisims1.bisim1AAccFail)
ultimately show ?thesis using s by auto blast
next
case (Red1AAccBounds A U len I)
hence [simp]: "a' = addr A" "e' = THROW ArrayIndexOutOfBounds" "i = Val (Intg I)"
"ta = ε" "h' = h" "xs' = xs"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "I <s 0 ∨ int len ≤ sint I" by auto
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉) h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
by-(rule AAcc_τExecrI1)
also from bisim2[of loc] have "τExec_mover_a P t i h ([], loc, 0, None) ([Intg I], loc, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉) h ([] @ [Addr A], loc, length (compE2 a) + 0, None) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
by(rule AAcc_τExecrI2)
hence "τExec_mover_a P t (a⌊i⌉) h ([Addr A], loc, length (compE2 a), None) ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), None)" by simp
also (rtranclp_trans) from I hA
have "exec_move_a P t (a⌊i⌉) h ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), None) ε h ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), ⌊addr_of_sys_xcpt ArrayIndexOutOfBounds⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Intg I, Addr A] (a⌊i⌉) (length (compE2 a) + length (compE2 i)) None"
by(simp add: τmove2_iff)
moreover have "¬ τmove1 P h (a'⌊i⌉)" by(auto simp add: τmove1.simps τmoves1.simps)
moreover
have "P,a⌊i⌉,h ⊢ (THROW ArrayIndexOutOfBounds, xs) ↔ ([Intg I, Addr A], xs, length (compE2 a) + length (compE2 i), ⌊addr_of_sys_xcpt ArrayIndexOutOfBounds⌋)"
by(rule bisim1_bisims1.bisim1AAccFail)
ultimately show ?thesis using s by auto blast
next
case (AAcc1Throw1 A)
note [simp] = ‹a' = Throw A› ‹ta = ε› ‹e' = Throw A› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (Throw A⌊i⌉)" by(rule τmove1AAccThrow1)
from bisim1 have "xcp = ⌊A⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊A⌋"
with bisim1 have "P, a⌊i⌉, h ⊢ (Throw A, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1_bisims1.intros)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim1 obtain pc' where "τExec_mover_a P t a h (stk, loc, pc, None) ([Addr A], loc, pc', ⌊A⌋)"
and bisim': "P, a, h ⊢ (Throw A, xs) ↔ ([Addr A], loc, pc', ⌊A⌋)"
and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (a⌊i⌉) h (stk, loc, pc, None) ([Addr A], loc, pc', ⌊A⌋)"
by-(rule AAcc_τExecrI1)
moreover from bisim'
have "P, a⌊i⌉, h ⊢ (Throw A, xs) ↔ ([Addr A], loc, pc', ⌊A⌋)"
by(auto intro: bisim1_bisims1.bisim1AAccThrow1)
ultimately show ?thesis using τ by auto
qed
next
case (AAcc1Throw2 v ad)
note [simp] = ‹a' = Val v› ‹i = Throw ad› ‹ta = ε› ‹e' = Throw ad› ‹h' = h› ‹xs' = xs›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([v], loc, length (compE2 a), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊Throw ad⌉) h (stk, loc, pc, xcp) ([v], loc, length (compE2 a), None)"
by-(rule AAcc_τExecrI1)
also have "τExec_mover_a P t (a⌊Throw ad⌉) h ([v], loc, length (compE2 a), None) ([Addr ad, v], loc, Suc (length (compE2 a)), ⌊ad⌋)"
by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
also (rtranclp_trans)
have "P,a⌊Throw ad⌉,h ⊢ (Throw ad, loc) ↔ ([Addr ad] @ [v], loc, (length (compE2 a) + length (compE2 (addr ad))), ⌊ad⌋)"
by(rule bisim1AAccThrow2[OF bisim1Throw2])
moreover have "τmove1 P h (a'⌊Throw ad⌉)" by(auto intro: τmove1AAccThrow2)
ultimately show ?thesis using s by auto
qed
next
case (bisim1AAcc2 i n i' xs stk loc pc xcp a v1)
note IH2 = bisim1AAcc2.IH(2)
note bisim1 = ‹⋀xs. P,a,h ⊢ (a, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹P,i,h ⊢ (i', xs) ↔ (stk, loc, pc, xcp)›
note red = ‹True,P,t ⊢1 ⟨Val v1⌊i'⌉,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (a⌊i⌉) n›
from red show ?case
proof cases
case (AAcc1Red2 E')
note [simp] = ‹e' = Val v1⌊E'⌉›
and red = ‹True,P,t ⊢1 ⟨i',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,i,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta i i' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from red have τ: "τmove1 P h (Val v1⌊i'⌉) = τmove1 P h i'" by(auto simp add: τmove1.simps τmoves1.simps)
have "no_call2 i pc ⟹ no_call2 (a⌊i⌉) (length (compE2 a) + pc)" by(auto simp add: no_call2_def)
hence "?exec ta (a⌊i⌉) (Val v1⌊i'⌉) (Val v1⌊E'⌉) h (stk @ [v1]) loc (length (compE2 a) + pc) xcp h' (length (compE2 a) + pc'') (stk'' @ [v1]) loc'' xcp''"
using exec' τ
apply(cases "τmove1 P h (Val v1⌊i'⌉)")
apply(auto)
apply(blast intro: AAcc_τExecrI2 AAcc_τExectI2 exec_move_AAccI2)
apply(blast intro: AAcc_τExecrI2 AAcc_τExectI2 exec_move_AAccI2)
apply(rule exI conjI AAcc_τExecrI2 exec_move_AAccI2|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
apply(rule exI conjI AAcc_τExecrI2 exec_move_AAccI2|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
apply(rule exI conjI AAcc_τExecrI2 exec_move_AAccI2 rtranclp.rtrancl_refl|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)+
done
moreover from bisim'
have "P,a⌊i⌉,h' ⊢ (Val v1⌊E'⌉, xs') ↔ (stk''@[v1], loc'', length (compE2 a) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1AAcc2)
ultimately show ?thesis using τ by auto blast+
next
case (Red1AAcc A U len I v)
hence [simp]: "v1 = Addr A" "e' = Val v" "i' = Val (Intg I)"
"ta = ⦃ReadMem A (ACell (nat (sint I))) v⦄" "h' = h" "xs' = xs"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "0 <=s I" "sint I < int len"
and read: "heap_read h A (ACell (nat (sint I))) v" by auto
have τ: "¬ τmove1 P h (addr A⌊Val (Intg I)⌉)" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([Intg I], loc, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
by-(rule AAcc_τExecrI2)
moreover from hA I read
have "exec_move_a P t (a⌊i⌉) h ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), None)
⦃ReadMem A (ACell (nat (sint I))) v⦄
h ([v], loc, Suc (length (compE2 a) + length (compE2 i)), None)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [Intg I, Addr A] (a⌊i⌉) (length (compE2 a) + length (compE2 i)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉, h ⊢ (Val v, loc) ↔ ([v], loc, length (compE2 (a⌊i⌉)), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
next
case (Red1AAccNull v)
note [simp] = ‹v1 = Null› ‹i' = Val v› ‹ta = ε› ‹e' = THROW NullPointer› ‹h' = h› ‹xs' = xs›
from bisim2 have [simp]: "xcp = None" "xs = loc"
and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([v], loc, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉) h (stk @ [Null], loc, length (compE2 a) + pc, xcp) ([v] @ [Null], loc, length (compE2 a) + length (compE2 i), None)"
by-(rule AAcc_τExecrI2)
moreover have "exec_move_a P t (a⌊i⌉) h ([v, Null], loc, length (compE2 a) + length (compE2 i), None) ε h ([v, Null], loc, length (compE2 a) + length (compE2 i), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by-(rule exec_instr, auto)
moreover have "¬ τmove2 (compP2 P) h [v, Null] (a⌊i⌉) (length (compE2 a) + length (compE2 i)) None"
by(simp add: τmove2_iff)
moreover have "¬ τmove1 P h (null⌊i'⌉)" by(auto simp add: τmove1.simps τmoves1.simps)
moreover
have "P,a⌊i⌉,h ⊢ (THROW NullPointer, xs) ↔ ([v, Null], xs, length (compE2 a) + length (compE2 i), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1_bisims1.bisim1AAccFail)
ultimately show ?thesis by auto blast
next
case (Red1AAccBounds A U len I)
hence [simp]: "v1 = Addr A" "e' = THROW ArrayIndexOutOfBounds" "i' = Val (Intg I)"
"ta = ε" "h' = h" "xs' = xs"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "I <s 0 ∨ int len ≤ sint I" by auto
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([Intg I], loc, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
by-(rule AAcc_τExecrI2)
moreover from I hA
have "exec_move_a P t (a⌊i⌉) h ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), None) ε h ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), ⌊addr_of_sys_xcpt ArrayIndexOutOfBounds⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Intg I, Addr A] (a⌊i⌉) (length (compE2 a) + length (compE2 i)) None"
by(simp add: τmove2_iff)
moreover have "¬ τmove1 P h (addr A⌊i'⌉)" by(auto simp add: τmove1.simps τmoves1.simps)
moreover
have "P,a⌊i⌉,h ⊢ (THROW ArrayIndexOutOfBounds, xs) ↔ ([Intg I, Addr A], xs, length (compE2 a) + length (compE2 i), ⌊addr_of_sys_xcpt ArrayIndexOutOfBounds⌋)"
by(rule bisim1_bisims1.bisim1AAccFail)
ultimately show ?thesis using s by auto blast
next
case (AAcc1Throw2 A)
note [simp] = ‹i' = Throw A› ‹ta = ε› ‹e' = Throw A› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (Val v1⌊Throw A⌉)" by(rule τmove1AAccThrow2)
from bisim2 have "xcp = ⌊A⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊A⌋"
with bisim2
have "P, a⌊i⌉, h ⊢ (Throw A, xs) ↔ (stk @ [v1], loc, length (compE2 a) + pc, xcp)"
by(auto intro: bisim1_bisims1.intros)
thus ?thesis using τ by(auto)
next
assume [simp]: "xcp = None"
with bisim2 obtain pc' where "τExec_mover_a P t i h (stk, loc, pc, None) ([Addr A], loc, pc', ⌊A⌋)"
and bisim': "P, i, h ⊢ (Throw A, xs) ↔ ([Addr A], loc, pc', ⌊A⌋)"
and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (a⌊i⌉) h (stk @ [v1], loc, length (compE2 a) + pc, None) ([Addr A] @ [v1], loc, length (compE2 a) + pc', ⌊A⌋)"
by-(rule AAcc_τExecrI2)
moreover from bisim'
have "P, a⌊i⌉, h ⊢ (Throw A, xs) ↔ ([Addr A] @ [v1], loc, length (compE2 a) + pc', ⌊A⌋)"
by(rule bisim1_bisims1.bisim1AAccThrow2)
ultimately show ?thesis using τ by auto
qed
qed auto
next
case bisim1AAccThrow1 thus ?case by auto
next
case bisim1AAccThrow2 thus ?case by auto
next
case bisim1AAccFail thus ?case by auto
next
case (bisim1AAss1 a n a' xs stk loc pc xcp i e)
note IH1 = bisim1AAss1.IH(2)
note IH2 = bisim1AAss1.IH(4)
note IH3 = bisim1AAss1.IH(6)
note bisim1 = ‹P,a,h ⊢ (a', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹⋀xs. P,i,h ⊢ (i, xs) ↔ ([], xs, 0, None)›
note bisim3 = ‹⋀xs. P,e,h ⊢ (e, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok (a⌊i⌉ := e) n›
from ‹True,P,t ⊢1 ⟨a'⌊i⌉ := e,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (AAss1Red1 E')
note [simp] = ‹e' = E'⌊i⌉ := e›
and red = ‹True,P,t ⊢1 ⟨a',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have "τmove1 P h (a'⌊i⌉ := e) = τmove1 P h a'" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from red have "call1 (a'⌊i⌉ := e) = call1 a'" by auto
moreover from IH1[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,a,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta a a' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,a⌊i⌉ := e,h' ⊢ (E'⌊i⌉ := e, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1AAss1)
moreover {
assume "no_call2 a pc"
hence "no_call2 (a⌊i⌉ := e) pc ∨ pc = length (compE2 a)" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: AAss_τExecrI1 AAss_τExectI1 exec_move_AAssI1)+
next
case (AAss1Red2 E' v)
note [simp] = ‹a' = Val v› ‹e' = Val v⌊E'⌉ := e›
and red = ‹True,P,t ⊢1 ⟨i,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v⌊i⌉ := e) = τmove1 P h i" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t a h (stk, loc, pc, None) ([v], xs, length (compE2 a), None)"
by(auto dest: bisim1Val2D1)
from exec1 have "τExec_mover_a P t (a⌊i⌉ := e) h (stk, loc, pc, None) ([v], xs, length (compE2 a), None)"
by(rule AAss_τExecrI1)
moreover
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,i,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta i i E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (a⌊i⌉ := e) (Val v⌊i⌉ := e) (Val v⌊E'⌉ := e) h ([] @ [v]) xs (length (compE2 a) + 0) None h' (length (compE2 a) + pc'') (stk'' @ [v]) loc'' xcp''"
proof(cases "τmove1 P h (Val v⌊i⌉ := e)")
case True
with exec' τ have [simp]: "h = h'" and e: "sim_move i E' P t i h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (a⌊i⌉ := e) (a⌊E'⌉ := e) P t (a⌊i⌉ := e) h ([] @ [v], xs, length (compE2 a) + 0, None) (stk'' @ [v], loc'', length (compE2 a) + pc'', xcp'')"
by(fastforce dest: AAss_τExecrI2 AAss_τExectI2)
with True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t i h ([], xs, 0, None) (stk', loc', pc', xcp')"
and e': "exec_move_a P t i h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' i pc' xcp'"
and call: "call1 i = None ∨ no_call2 i 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs ∧ xcp' = None" by auto
from e have "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [v], xs, length (compE2 a) + 0, None) (stk' @ [v], loc', length (compE2 a) + pc', xcp')" by(rule AAss_τExecrI2)
moreover from e' have "exec_move_a P t (a⌊i⌉ := e) h (stk' @ [v], loc', length (compE2 a) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 a) + pc'', xcp'')"
by(rule exec_move_AAssI2)
moreover from e' have "pc' < length (compE2 i)" by(auto elim: exec_meth.cases)
with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v]) (a⌊i⌉ := e) (length (compE2 a) + pc') xcp'"
by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
moreover from red have "call1 (a'⌊i⌉ := e) = call1 i" by auto
moreover have "no_call2 i 0 ⟹ no_call2 (a⌊i⌉ := e) (length (compE2 a))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call
by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P,a⌊i⌉ := e,h' ⊢ (Val v⌊E'⌉ := e, xs') ↔ ((stk'' @ [v]), loc'', length (compE2 a) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1AAss2)
moreover from bisim1 have "pc ≠ length (compE2 a) ⟶ no_call2 (a⌊i⌉ := e) pc"
by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
ultimately show ?thesis using τ exec1 s
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
done
next
case (AAss1Red3 E' v v')
note [simp] = ‹i = Val v'› ‹a' = Val v› ‹e' = Val v⌊Val v'⌉ := E'›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v⌊Val v'⌉ := e) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t a h (stk, loc, pc, None) ([] @ [v], xs, length (compE2 a) + 0, None)"
by(auto dest: bisim1Val2D1)
from exec1 have "τExec_mover_a P t (a⌊i⌉ := e) h (stk, loc, pc, None) ([] @ [v], xs, length (compE2 a) + 0, None)"
by(rule AAss_τExecrI1)
also from bisim2[of xs]
have "τExec_mover_a P t i h ([], xs, 0, None) ([v'], xs, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [v], xs, length (compE2 a) + 0, None) ([v'] @ [v], xs, length (compE2 a) + length (compE2 i), None)"
by(rule AAss_τExecrI2)
also (rtranclp_trans) from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e e E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (a⌊i⌉ := e) (Val v⌊Val v'⌉ := e) (Val v⌊Val v'⌉ := E') h ([] @ [v', v]) xs (length (compE2 a) + length (compE2 i) + 0) None h' (length (compE2 a) + length (compE2 i) + pc'') (stk'' @ [v', v]) loc'' xcp''"
proof(cases "τmove1 P h (Val v⌊Val v'⌉ := e)")
case True
with exec' τ have [simp]: "h = h'" and e: "sim_move e E' P t e h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (Val v⌊Val v'⌉ := e) (Val v⌊Val v'⌉ := E') P t (a⌊i⌉ := e) h ([] @ [v', v], xs, length (compE2 a) + length (compE2 i) + 0, None) (stk'' @ [v', v], loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
by(fastforce dest: AAss_τExectI3 AAss_τExecrI3 simp del: compE2.simps compEs2.simps)
with True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t e h ([], xs, 0, None) (stk', loc', pc', xcp')"
and e': "exec_move_a P t e h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' e pc' xcp'"
and call: "call1 e = None ∨ no_call2 e 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs ∧ xcp' = None" by auto
from e have "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [v', v], xs, length (compE2 a) + length (compE2 i) + 0, None) (stk' @ [v', v], loc', length (compE2 a) + length (compE2 i) + pc', xcp')" by(rule AAss_τExecrI3)
moreover from e' have "exec_move_a P t (a⌊i⌉ := e) h (stk' @ [v', v], loc', length (compE2 a) + length (compE2 i) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v', v], loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
by(rule exec_move_AAssI3)
moreover from e' τ'
have "¬ τmove2 (compP2 P) h (stk' @ [v', v]) (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + pc') xcp'"
by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
moreover have "call1 (a'⌊i⌉ := e) = call1 e" by simp
moreover have "no_call2 e 0 ⟹ no_call2 (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call
by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P,a⌊i⌉ := e,h' ⊢ (Val v⌊Val v'⌉ := E', xs') ↔ ((stk'' @ [v', v]), loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1AAss3)
moreover from bisim1 have "pc ≠ length (compE2 a) + length (compE2 i) ⟶ no_call2 (a⌊i⌉ := e) pc"
by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
ultimately show ?thesis using τ exec1 s
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
done
next
case (Red1AAss A U len I v U')
hence [simp]: "a' = addr A" "e' = unit" "i = Val (Intg I)"
"ta = ⦃WriteMem A (ACell (nat (sint I))) v⦄" "xs' = xs" "e = Val v"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "0 <=s I" "sint I < int len"
and v: "typeof⇘h⇙ v = ⌊U'⌋" "P ⊢ U' ≤ U"
and h': "heap_write h A (ACell (nat (sint I))) v h'" by auto
have τ: "¬ τmove1 P h (AAss (addr A) (Val (Intg I)) (Val v))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
by-(rule AAss_τExecrI1)
also from bisim2[of loc]
have "τExec_mover_a P t i h ([], loc, 0, None) ([Intg I], loc, length (compE2 i) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [Addr A], loc, length (compE2 a) + 0, None) ([Intg I] @ [Addr A], loc, length (compE2 a) + (length (compE2 i) + 0), None)"
by(rule AAss_τExecrI2)
also (rtranclp_trans) have "[Intg I] @ [Addr A] = [] @ [Intg I, Addr A]" by simp
also note add.assoc[symmetric]
also from bisim3[of loc] have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by(rule AAss_τExecrI3)
also (rtranclp_trans) from hA I v h'
have "exec_move_a P t (a⌊i⌉ := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)
⦃WriteMem A (ACell (nat (sint I))) v⦄
h' ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (unit, loc) ↔ ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
by(rule bisim1_bisims1.bisim1AAss4)
ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
next
case (Red1AAssNull v v')
note [simp] = ‹a' = null› ‹e' = THROW NullPointer› ‹i = Val v› ‹xs' = xs› ‹ta = ε› ‹h' = h› ‹e = Val v'›
have τ: "¬ τmove1 P h (AAss null (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([] @ [Null], loc, length (compE2 a) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk, loc, pc, xcp) ([] @ [Null], loc, length (compE2 a) + 0, None)"
by-(rule AAss_τExecrI1)
also from bisim2[of loc] have "τExec_mover_a P t i h ([], loc, 0, None) ([v], loc, length (compE2 i) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [Null], loc, length (compE2 a) + 0, None) ([v] @ [Null], loc, length (compE2 a) + (length (compE2 i) + 0), None)"
by(rule AAss_τExecrI2)
also (rtranclp_trans) have "[v] @ [Null] = [] @ [v, Null]" by simp
also note add.assoc[symmetric]
also from bisim3[of loc] have "τExec_mover_a P t e h ([], loc, 0, None) ([v'], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [v, Null], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v'] @ [v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by(rule AAss_τExecrI3)
also (rtranclp_trans)
have "exec_move_a P t (a⌊i⌉ := e) h ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
h ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [v', v, Null] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (THROW NullPointer, loc) ↔ ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1_bisims1.bisim1AAssFail)
ultimately show ?thesis using s τ by auto blast
next
case (Red1AAssBounds A U len I v)
hence [simp]: "a' = addr A" "e' = THROW ArrayIndexOutOfBounds" "i = Val (Intg I)" "xs' = xs" "ta = ε" "h' = h" "e = Val v"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "I <s 0 ∨ int len ≤ sint I" by auto
have τ: "¬ τmove1 P h (AAss (addr A) i e)" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
by-(rule AAss_τExecrI1)
also from bisim2[of loc]
have "τExec_mover_a P t i h ([], loc, 0, None) ([Intg I], loc, length (compE2 i) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [Addr A], loc, length (compE2 a) + 0, None) ([Intg I] @ [Addr A], loc, length (compE2 a) + (length (compE2 i) + 0), None)"
by(rule AAss_τExecrI2)
also (rtranclp_trans) have "[Intg I] @ [Addr A] = [] @ [Intg I, Addr A]" by simp
also note add.assoc[symmetric]
also from bisim3[of loc]
have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by(rule AAss_τExecrI3)
also (rtranclp_trans) from hA I
have "exec_move_a P t (a⌊i⌉ := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayIndexOutOfBounds⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (THROW ArrayIndexOutOfBounds, loc) ↔ ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayIndexOutOfBounds⌋)"
by(rule bisim1_bisims1.bisim1AAssFail)
ultimately show ?thesis using s τ by auto blast
next
case (Red1AAssStore A U len I v U')
hence [simp]: "a' = addr A" "e' = THROW ArrayStore" "i = Val (Intg I)" "xs' = xs" "ta = ε" "h' = h" "e = Val v"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "0 <=s I" "sint I < int len"
and U: "¬ P ⊢ U' ≤ U" "typeof⇘h⇙ v = ⌊U'⌋" by auto
have τ: "¬ τmove1 P h (AAss (addr A) i e)" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
by-(rule AAss_τExecrI1)
also from bisim2[of loc]
have "τExec_mover_a P t i h ([], loc, 0, None) ([Intg I], loc, length (compE2 i) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [Addr A], loc, length (compE2 a) + 0, None) ([Intg I] @ [Addr A], loc, length (compE2 a) + (length (compE2 i) + 0), None)"
by(rule AAss_τExecrI2)
also (rtranclp_trans) have "[Intg I] @ [Addr A] = [] @ [Intg I, Addr A]" by simp
also note add.assoc[symmetric]
also from bisim3[of loc]
have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by(rule AAss_τExecrI3)
also (rtranclp_trans) from hA I U
have "exec_move_a P t (a⌊i⌉ := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayStore⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def compP2_def)
moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (THROW ArrayStore, loc) ↔ ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayStore⌋)"
by(rule bisim1_bisims1.bisim1AAssFail)
ultimately show ?thesis using s τ by auto blast
next
case (AAss1Throw1 A)
hence [simp]: "a' = Throw A" "ta = ε" "e' = Throw A" "h' = h" "xs' = xs" by auto
have τ: "τmove1 P h (Throw A⌊i⌉ := e)" by(rule τmove1AAssThrow1)
from bisim1 have "xcp = ⌊A⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊A⌋"
with bisim1 have "P, a⌊i⌉ := e, h ⊢ (Throw A, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1_bisims1.intros)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim1 obtain pc' where "τExec_mover_a P t a h (stk, loc, pc, None) ([Addr A], loc, pc', ⌊A⌋)"
and bisim': "P, a, h ⊢ (Throw A, xs) ↔ ([Addr A], loc, pc', ⌊A⌋)"
and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk, loc, pc, None) ([Addr A], loc, pc', ⌊A⌋)"
by-(rule AAss_τExecrI1)
moreover from bisim'
have "P, a⌊i⌉ := e, h ⊢ (Throw A, xs) ↔ ([Addr A], loc, pc', ⌊A⌋)"
by(auto intro: bisim1_bisims1.bisim1AAssThrow1)
ultimately show ?thesis using τ by auto
qed
next
case (AAss1Throw2 v ad)
note [simp] = ‹a' = Val v› ‹i = Throw ad› ‹ta = ε› ‹e' = Throw ad› ‹h' = h› ‹xs' = xs›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([v], loc, length (compE2 a), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊Throw ad⌉ := e) h (stk, loc, pc, xcp) ([v], loc, length (compE2 a), None)"
by-(rule AAss_τExecrI1)
also have "τExec_mover_a P t (a⌊Throw ad⌉:=e) h ([v], loc, length (compE2 a), None) ([Addr ad, v], loc, Suc (length (compE2 a)), ⌊ad⌋)"
by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
also (rtranclp_trans)
have "P,a⌊Throw ad⌉:=e,h ⊢ (Throw ad, loc) ↔ ([Addr ad] @ [v], loc, (length (compE2 a) + length (compE2 (addr ad))), ⌊ad⌋)"
by(rule bisim1AAssThrow2[OF bisim1Throw2])
moreover have "τmove1 P h (a'⌊Throw ad⌉:=e)" by(auto intro: τmove1AAssThrow2)
ultimately show ?thesis using s by auto
next
case (AAss1Throw3 va vi ad)
note [simp] = ‹a' = Val va› ‹i = Val vi› ‹e = Throw ad› ‹ta = ε› ‹e' = Throw ad› ‹h' = h› ‹xs' = xs›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([va], loc, length (compE2 a), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := Throw ad) h (stk, loc, pc, xcp) ([va], loc, length (compE2 a), None)"
by-(rule AAss_τExecrI1)
also from bisim2[of loc] have "τExec_mover_a P t i h ([], loc, 0, None) ([vi], loc, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
from AAss_τExecrI2[OF this, of a e va]
have "τExec_mover_a P t (a⌊i⌉ := Throw ad) h ([va], loc, length (compE2 a), None) ([vi, va], loc, length (compE2 a) + length (compE2 i), None)" by simp
also (rtranclp_trans)
have "τExec_mover_a P t (a⌊i⌉:=Throw ad) h ([vi, va], loc, length (compE2 a) + length (compE2 i), None) ([Addr ad, vi, va], loc, Suc (length (compE2 a) + length (compE2 i)), ⌊ad⌋)"
by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
also (rtranclp_trans)
have "P,a⌊i⌉:=Throw ad,h ⊢ (Throw ad, loc) ↔ ([Addr ad] @ [vi, va], loc, (length (compE2 a) + length (compE2 i) + length (compE2 (addr ad))), ⌊ad⌋)"
by(rule bisim1AAssThrow3[OF bisim1Throw2])
moreover have "τmove1 P h (AAss a' (Val vi) (Throw ad))" by(auto intro: τmove1AAssThrow3)
ultimately show ?thesis using s by auto
qed
next
case (bisim1AAss2 i n i' xs stk loc pc xcp a e v1)
note IH2 = bisim1AAss2.IH(2)
note IH3 = bisim1AAss2.IH(6)
note bisim2 = ‹P,i,h ⊢ (i', xs) ↔ (stk, loc, pc, xcp)›
note bisim1 = ‹⋀xs. P,a,h ⊢ (a, xs) ↔ ([], xs, 0, None)›
note bisim3 = ‹⋀xs. P,e,h ⊢ (e, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok (a⌊i⌉ := e) n›
from ‹True,P,t ⊢1 ⟨Val v1⌊i'⌉ := e,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (AAss1Red2 E')
note [simp] = ‹e' = Val v1⌊E'⌉ := e›
and red = ‹True,P,t ⊢1 ⟨i',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v1⌊i'⌉ := e) = τmove1 P h i'" by(auto simp add: τmove1.simps τmoves1.simps)
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,i,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta i i' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (a⌊i⌉ := e) (Val v1⌊i'⌉ := e) (Val v1⌊E'⌉ := e) h (stk @ [v1]) loc (length (compE2 a) + pc) xcp h' (length (compE2 a) + pc'') (stk'' @ [v1]) loc'' xcp''"
proof(cases "τmove1 P h (Val v1⌊i'⌉ := e)")
case True
with exec' τ have [simp]: "h = h'" and e: "sim_move i' E' P t i h (stk, loc, pc, xcp) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (Val v1⌊i'⌉ := e) (Val v1⌊E'⌉ := e) P t (a⌊i⌉ := e) h (stk @ [v1], loc, length (compE2 a) + pc, xcp) (stk'' @ [v1], loc'', length (compE2 a) + pc'', xcp'')"
by(fastforce dest: AAss_τExecrI2 AAss_τExectI2 simp del: compE2.simps compEs2.simps)
with True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t i h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
and e': "exec_move_a P t i h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' i pc' xcp'"
and call: "call1 i' = None ∨ no_call2 i pc ∨ pc' = pc ∧ stk' = stk ∧ loc' = loc ∧ xcp' = xcp" by auto
from e have "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [v1], loc, length (compE2 a) + pc, xcp) (stk' @ [v1], loc', length (compE2 a) + pc', xcp')" by(rule AAss_τExecrI2)
moreover from e' have "exec_move_a P t (a⌊i⌉ := e) h (stk' @ [v1], loc', length (compE2 a) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v1], loc'', length (compE2 a) + pc'', xcp'')"
by(rule exec_move_AAssI2)
moreover from e' have "pc' < length (compE2 i)" by(auto elim: exec_meth.cases)
with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v1]) (a⌊i⌉ := e) (length (compE2 a) + pc') xcp'"
by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
moreover from red have "call1 (Val v1⌊i'⌉ := e) = call1 i'" by auto
moreover have "no_call2 i pc ⟹ no_call2 (a⌊i⌉ := e) (length (compE2 a) + pc)"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps)
qed
moreover from bisim'
have "P,a⌊i⌉ := e,h' ⊢ (Val v1⌊E'⌉ := e, xs') ↔ ((stk'' @ [v1]), loc'', length (compE2 a) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1AAss2)
ultimately show ?thesis
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans)+
done
next
case (AAss1Red3 E' v')
note [simp] = ‹i' = Val v'› ‹e' = Val v1⌊Val v'⌉ := E'›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v1⌊Val v'⌉ := e) = τmove1 P h e"
by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t i h (stk, loc, pc, xcp) ([v'], xs, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [v1], loc, length (compE2 a) + pc, xcp) ([v'] @ [v1], xs, length (compE2 a) + length (compE2 i), None)"
by-(rule AAss_τExecrI2)
moreover from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e e E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (a⌊i⌉ := e) (Val v1⌊Val v'⌉ := e) (Val v1⌊Val v'⌉ := E') h ([] @ [v', v1]) xs (length (compE2 a) + length (compE2 i) + 0) None h' (length (compE2 a) + length (compE2 i) + pc'') (stk'' @ [v', v1]) loc'' xcp''"
proof(cases "τmove1 P h (Val v1⌊Val v'⌉ := e)")
case True
with exec' τ have [simp]: "h = h'"
and e: "sim_move e E' P t e h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (Val v1⌊Val v'⌉ := e) (Val v1⌊Val v'⌉ := E') P t (a⌊i⌉ := e) h ([] @ [v', v1], xs, length (compE2 a) + length (compE2 i) + 0, None) (stk'' @ [v', v1], loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
by(fastforce dest: AAss_τExectI3 AAss_τExecrI3 simp del: compE2.simps compEs2.simps)
with True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t e h ([], xs, 0, None) (stk', loc', pc', xcp')"
and e': "exec_move_a P t e h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' e pc' xcp'"
and call: "call1 e = None ∨ no_call2 e 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs ∧ xcp' = None" by auto
from e have "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [v', v1], xs, length (compE2 a) + length (compE2 i) + 0, None) (stk' @ [v', v1], loc', length (compE2 a) + length (compE2 i) + pc', xcp')" by(rule AAss_τExecrI3)
moreover from e' have "exec_move_a P t (a⌊i⌉ := e) h (stk' @ [v', v1], loc', length (compE2 a) + length (compE2 i) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v', v1], loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
by(rule exec_move_AAssI3)
moreover from e' τ' have "¬ τmove2 (compP2 P) h (stk' @ [v', v1]) (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + pc') xcp'"
by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
moreover from red have "call1 (Val v1⌊Val v'⌉ := e) = call1 e" by auto
moreover have "no_call2 e 0 ⟹ no_call2 (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P,a⌊i⌉ := e,h' ⊢ (Val v1⌊Val v'⌉ := E', xs') ↔ ((stk'' @ [v', v1]), loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1AAss3)
moreover from bisim2 have "pc ≠ length (compE2 i) ⟶ no_call2 (a⌊i⌉ := e) (length (compE2 a) + pc)"
by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
ultimately show ?thesis using τ exec1 s
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
done
next
case (Red1AAss A U len I v U')
hence [simp]: "v1 = Addr A" "e' = unit" "i' = Val (Intg I)"
"ta = ⦃WriteMem A (ACell (nat (sint I))) v⦄" "xs' = xs" "e = Val v"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "0 <=s I" "sint I < int len"
and v: "typeof⇘h⇙ v = ⌊U'⌋" "P ⊢ U' ≤ U"
and h': "heap_write h A (ACell (nat (sint I))) v h'" by auto
have τ: "¬ τmove1 P h (AAss (addr A) (Val (Intg I)) (Val v))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([Intg I], loc, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
by-(rule AAss_τExecrI2)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None)" by simp
also from bisim3[of loc] have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by(rule AAss_τExecrI3)
also (rtranclp_trans) from hA I v h'
have "exec_move_a P t (a⌊i⌉ := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)
⦃WriteMem A (ACell (nat (sint I))) v⦄
h' ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (unit, loc) ↔ ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
by(rule bisim1_bisims1.bisim1AAss4)
ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
next
case (Red1AAssNull v v')
note [simp] = ‹v1 = Null› ‹e' = THROW NullPointer› ‹i' = Val v› ‹xs' = xs› ‹ta = ε› ‹h' = h› ‹e = Val v'›
have τ: "¬ τmove1 P h (AAss null (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([v], loc, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [Null], loc, length (compE2 a) + pc, xcp) ([v] @ [Null], loc, length (compE2 a) + length (compE2 i), None)"
by-(rule AAss_τExecrI2)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [Null], loc, length (compE2 a) + pc, xcp) ([] @ [v, Null], loc, length (compE2 a) + length (compE2 i) + 0, None)" by simp
also from bisim3[of loc] have "τExec_mover_a P t e h ([], loc, 0, None) ([v'], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [v, Null], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v'] @ [v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by(rule AAss_τExecrI3)
also (rtranclp_trans)
have "exec_move_a P t (a⌊i⌉ := e) h ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
h ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [v', v, Null] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (THROW NullPointer, loc) ↔ ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1_bisims1.bisim1AAssFail)
ultimately show ?thesis using s τ by auto blast
next
case (Red1AAssBounds A U len I v)
hence [simp]: "v1 = Addr A" "e' = THROW ArrayIndexOutOfBounds" "i' = Val (Intg I)" "xs' = xs" "ta = ε" "h' = h" "e = Val v"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "I <s 0 ∨ int len ≤ sint I" by auto
have τ: "¬ τmove1 P h (addr A⌊i'⌉ := e)" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([Intg I], loc, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
by-(rule AAss_τExecrI2)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None)" by simp
also from bisim3[of loc] have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by(rule AAss_τExecrI3)
also (rtranclp_trans) from hA I
have "exec_move_a P t (a⌊i⌉ := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayIndexOutOfBounds⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (THROW ArrayIndexOutOfBounds, loc) ↔ ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayIndexOutOfBounds⌋)"
by(rule bisim1_bisims1.bisim1AAssFail)
ultimately show ?thesis using s τ by auto blast
next
case (Red1AAssStore A U len I v U')
hence [simp]: "v1 = Addr A" "e' = THROW ArrayStore" "i' = Val (Intg I)" "xs' = xs" "ta = ε" "h' = h" "e = Val v"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "0 <=s I" "sint I < int len"
and U: "¬ P ⊢ U' ≤ U" "typeof⇘h⇙ v = ⌊U'⌋" by auto
have τ: "¬ τmove1 P h (addr A⌊i'⌉ := e)" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([Intg I], loc, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
by-(rule AAss_τExecrI2)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None)" by simp
also from bisim3[of loc]
have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by(rule AAss_τExecrI3)
also (rtranclp_trans) from hA I U
have "exec_move_a P t (a⌊i⌉ := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayStore⌋)"
unfolding exec_move_def by- (rule exec_instr, auto simp add: is_Ref_def compP2_def)
moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (THROW ArrayStore, loc) ↔ ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayStore⌋)"
by(rule bisim1_bisims1.bisim1AAssFail)
ultimately show ?thesis using s τ by auto fast
next
case (AAss1Throw2 A)
note [simp] = ‹i' = Throw A› ‹ta = ε› ‹e' = Throw A› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (Val v1⌊Throw A⌉ := e)" by(rule τmove1AAssThrow2)
from bisim2 have "xcp = ⌊A⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊A⌋"
with bisim2
have "P, a⌊i⌉ := e, h ⊢ (Throw A, xs) ↔ (stk @ [v1], loc, length (compE2 a) + pc, xcp)"
by(auto intro: bisim1_bisims1.intros)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim2 obtain pc' where "τExec_mover_a P t i h (stk, loc, pc, None) ([Addr A], loc, pc', ⌊A⌋)"
and bisim': "P, i, h ⊢ (Throw A, xs) ↔ ([Addr A], loc, pc', ⌊A⌋)"
and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [v1], loc, length (compE2 a) + pc, None) ([Addr A] @ [v1], loc, length (compE2 a) + pc', ⌊A⌋)"
by-(rule AAss_τExecrI2)
moreover from bisim'
have "P, a⌊i⌉ := e, h ⊢ (Throw A, xs) ↔ ([Addr A] @ [v1], loc, length (compE2 a) + pc', ⌊A⌋)"
by(rule bisim1_bisims1.bisim1AAssThrow2)
ultimately show ?thesis using τ by auto
qed
next
case (AAss1Throw3 vi ad)
note [simp] = ‹i' = Val vi› ‹e = Throw ad› ‹ta = ε› ‹e' = Throw ad› ‹h' = h› ‹xs' = xs›
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([vi], loc, length (compE2 i), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := Throw ad) h (stk @ [v1], loc, length (compE2 a) + pc, xcp) ([vi] @ [v1], loc, length (compE2 a) + length (compE2 i), None)"
by-(rule AAss_τExecrI2)
also have "τExec_mover_a P t (a⌊i⌉:=Throw ad) h ([vi] @ [v1], loc, length (compE2 a) + length (compE2 i), None) ([Addr ad, vi, v1], loc, Suc (length (compE2 a) + length (compE2 i)), ⌊ad⌋)"
by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
also (rtranclp_trans)
have "P,a⌊i⌉:=Throw ad,h ⊢ (Throw ad, loc) ↔ ([Addr ad] @ [vi, v1], loc, (length (compE2 a) + length (compE2 i) + length (compE2 (addr ad))), ⌊ad⌋)"
by(rule bisim1AAssThrow3[OF bisim1Throw2])
moreover have "τmove1 P h (AAss (Val v1) (Val vi) (Throw ad))" by(auto intro: τmove1AAssThrow3)
ultimately show ?thesis using s by auto
qed auto
next
case (bisim1AAss3 e n ee xs stk loc pc xcp a i v v')
note IH3 = bisim1AAss3.IH(2)
note bisim3 = ‹P,e,h ⊢ (ee, xs) ↔ (stk, loc, pc, xcp)›
note bsok = ‹bsok (a⌊i⌉ := e) n›
from ‹True,P,t ⊢1 ⟨Val v⌊Val v'⌉ := ee,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (AAss1Red3 E')
note [simp] = ‹e' = Val v⌊Val v'⌉ := E'›
and red = ‹True,P,t ⊢1 ⟨ee,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v⌊Val v'⌉ := ee) = τmove1 P h ee" by(auto simp add: τmove1.simps τmoves1.simps)
from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e ee E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "no_call2 e pc ⟹ no_call2 (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + pc)"
by(auto simp add: no_call2_def)
hence "?exec ta (a⌊i⌉ := e) (Val v⌊Val v'⌉ := ee) (Val v⌊Val v'⌉ := E') h (stk @ [v', v]) loc (length (compE2 a) + length (compE2 i) + pc) xcp h' (length (compE2 a) + length (compE2 i) + pc'') (stk'' @ [v', v]) loc'' xcp''"
using exec' τ
apply(cases "τmove1 P h (Val v⌊Val v'⌉ := ee)")
apply(auto)
apply(blast intro: AAss_τExecrI3 AAss_τExectI3 exec_move_AAssI3)
apply(blast intro: AAss_τExecrI3 AAss_τExectI3 exec_move_AAssI3)
apply(rule exI conjI AAss_τExecrI3 exec_move_AAssI3|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
apply(rule exI conjI AAss_τExecrI3 exec_move_AAssI3|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
apply(rule exI conjI AAss_τExecrI3 exec_move_AAssI3 rtranclp.rtrancl_refl|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)+
done
moreover from bisim'
have "P,a⌊i⌉ := e,h' ⊢ (Val v⌊Val v'⌉ := E', xs') ↔ (stk''@[v',v], loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1AAss3)
ultimately show ?thesis using τ by auto blast+
next
case (Red1AAss A U len I V U')
hence [simp]: "v = Addr A" "e' = unit" "v' = Intg I" "xs' = xs" "ee = Val V"
"ta = ⦃WriteMem A (ACell (nat (sint I))) V⦄"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "0 <=s I" "sint I < int len"
and v: "typeof⇘h⇙ V = ⌊U'⌋" "P ⊢ U' ≤ U"
and h': "heap_write h A (ACell (nat (sint I))) V h'" by auto
have τ: "¬ τmove1 P h (AAss (addr A) (Val (Intg I)) (Val V))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim3 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t e h (stk, loc, pc, xcp) ([V], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + pc, xcp) ([V] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by-(rule AAss_τExecrI3)
moreover from hA I v h'
have "exec_move_a P t (a⌊i⌉ := e) h ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)
⦃WriteMem A (ACell (nat (sint I))) V⦄
h' ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
moreover have "τmove2 (compP2 P) h [V, Intg I, Addr A] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (unit, loc) ↔ ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
by(rule bisim1_bisims1.bisim1AAss4)
ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
next
case (Red1AAssNull V')
note [simp] = ‹v = Null› ‹e' = THROW NullPointer› ‹xs' = xs› ‹ta = ε› ‹h' = h› ‹ee = Val V'›
have τ: "¬ τmove1 P h (AAss null (Val v') (Val V'))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim3 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e h (stk, loc, pc, xcp) ([V'], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [v', Null], loc, length (compE2 a) + length (compE2 i) + pc, xcp) ([V'] @ [v', Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by-(rule AAss_τExecrI3)
moreover
have "exec_move_a P t (a⌊i⌉ := e) h ([V', v', Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
h ([V', v', Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [V', v', Null] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (THROW NullPointer, loc) ↔ ([V', v', Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1_bisims1.bisim1AAssFail)
ultimately show ?thesis using s τ by auto blast
next
case (Red1AAssBounds A U len I V)
hence [simp]: "v = Addr A" "e' = THROW ArrayIndexOutOfBounds" "v' = Intg I" "xs' = xs" "ta = ε" "h' = h" "ee = Val V"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "I <s 0 ∨ int len ≤ sint I" by auto
have τ: "¬ τmove1 P h (addr A⌊Val (Intg I)⌉ := ee)" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim3 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e h (stk, loc, pc, xcp) ([V], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + pc, xcp) ([V] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by-(rule AAss_τExecrI3)
moreover from hA I
have "exec_move_a P t (a⌊i⌉ := e) h ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
h ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayIndexOutOfBounds⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [V, Intg I, Addr A] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (THROW ArrayIndexOutOfBounds, loc) ↔ ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayIndexOutOfBounds⌋)"
by(rule bisim1_bisims1.bisim1AAssFail)
ultimately show ?thesis using s τ by auto blast
next
case (Red1AAssStore A U len I V U')
hence [simp]: "v = Addr A" "e' = THROW ArrayStore" "v' = Intg I" "xs' = xs" "ta = ε" "h' = h" "ee = Val V"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" and I: "0 <=s I" "sint I < int len"
and U: "¬ P ⊢ U' ≤ U" "typeof⇘h⇙ V = ⌊U'⌋" by auto
have τ: "¬ τmove1 P h (addr A⌊Val (Intg I)⌉ := ee)" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim3 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e h (stk, loc, pc, xcp) ([V], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + pc, xcp) ([V] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
by-(rule AAss_τExecrI3)
moreover from hA I U
have "exec_move_a P t (a⌊i⌉ := e) h ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
h ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayStore⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def compP2_def)
moreover have "τmove2 (compP2 P) h [V, Intg I, Addr A] (a⌊i⌉ := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, a⌊i⌉ := e, h' ⊢ (THROW ArrayStore, loc) ↔ ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊addr_of_sys_xcpt ArrayStore⌋)"
by(rule bisim1_bisims1.bisim1AAssFail)
ultimately show ?thesis using s τ by auto blast
next
case (AAss1Throw3 A)
note [simp] = ‹ee = Throw A› ‹ta = ε› ‹e' = Throw A› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (AAss (Val v) (Val v') (Throw A))" by(rule τmove1AAssThrow3)
from bisim3 have "xcp = ⌊A⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊A⌋"
with bisim3
have "P, a⌊i⌉ := e, h ⊢ (Throw A, xs) ↔ (stk @ [v', v], loc, length (compE2 a) + length (compE2 i) + pc, xcp)"
by(auto intro: bisim1_bisims1.intros)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim3 obtain pc' where "τExec_mover_a P t e h (stk, loc, pc, None) ([Addr A], loc, pc', ⌊A⌋)"
and bisim': "P, e, h ⊢ (Throw A, xs) ↔ ([Addr A], loc, pc', ⌊A⌋)"
and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (a⌊i⌉ := e) h (stk @ [v', v], loc, length (compE2 a) + length (compE2 i) + pc, None) ([Addr A] @ [v', v], loc, length (compE2 a) + length (compE2 i) + pc', ⌊A⌋)"
by-(rule AAss_τExecrI3)
moreover from bisim'
have "P, a⌊i⌉ := e, h ⊢ (Throw A, xs) ↔ ([Addr A] @ [v', v], loc, length (compE2 a) + length (compE2 i) + pc', ⌊A⌋)"
by(rule bisim1_bisims1.bisim1AAssThrow3)
ultimately show ?thesis using τ by auto
qed
qed auto
next
case bisim1AAssThrow1 thus ?case by auto
next
case bisim1AAssThrow2 thus ?case by auto
next
case bisim1AAssThrow3 thus ?case by auto
next
case bisim1AAssFail thus ?case by auto
next
case bisim1AAss4 thus ?case by auto
next
case (bisim1ALength a n a' xs stk loc pc xcp)
note IH = bisim1ALength.IH(2)
note bisim = ‹P,a,h ⊢ (a', xs) ↔ (stk, loc, pc, xcp)›
note red = ‹True,P,t ⊢1 ⟨a'∙length,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (a∙length) n›
from red show ?case
proof cases
case (ALength1Red ee')
note [simp] = ‹e' = ee'∙length›
and red = ‹True,P,t ⊢1 ⟨a',(h, xs)⟩ -ta→ ⟨ee', (h', xs')⟩›
from red have "τmove1 P h (a'∙length) = τmove1 P h a'" by(auto simp add: τmove1.simps τmoves1.simps)
moreover have "call1 (a'∙length) = call1 a'" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,a,h' ⊢ (ee', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta a a' ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim have "P,a∙length,h' ⊢ (ee'∙length, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1ALength)
moreover {
assume "no_call2 a pc"
hence "no_call2 (a∙length) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: ALength_τExecrI ALength_τExectI exec_move_ALengthI)+
next
case (Red1ALength A U len)
hence [simp]: "a' = addr A" "ta = ε" "e' = Val (Intg (word_of_int (int len)))"
"h' = h" "xs' = xs"
and hA: "typeof_addr h A = ⌊Array_type U len⌋" by auto
from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
from bisim have "τExec_mover_a P t a h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a∙length) h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
by(rule ALength_τExecrI)
moreover from hA
have "exec_move_a P t (a∙length) h ([Addr A], loc, length (compE2 a), None) ε h' ([Intg (word_of_int (int len))], loc, Suc (length (compE2 a)), None)"
by(auto intro!: exec_instr simp add: is_Ref_def exec_move_def)
moreover have "τmove2 (compP2 P) h [Addr A] (a∙length) (length (compE2 a)) None ⟹ False" by(simp add: τmove2_iff)
moreover have "¬ τmove1 P h (addr A∙length)" by(auto simp add: τmove1.simps τmoves1.simps)
moreover
have "P, a∙length, h' ⊢ (Val (Intg (word_of_int (int len))), loc) ↔ ([Intg (word_of_int (int len))], loc, length (compE2 (a∙length)), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s by(auto) blast
next
case Red1ALengthNull
note [simp] = ‹a' = null› ‹e' = THROW NullPointer› ‹h' = h› ‹xs' = xs› ‹ta = ε›
have "¬ τmove1 P h (null∙length)" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from bisim have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([Null], loc, length (compE2 a), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (a∙length) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 a), None)"
by-(rule ALength_τExecrI)
moreover have "exec_move_a P t (a∙length) h ([Null], loc, length (compE2 a), None) ε h ([Null], loc, length (compE2 a), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by -(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [Null] (a∙length) (length (compE2 a)) None ⟹ False" by(simp add: τmove2_iff)
moreover
have "P,a∙length,h ⊢ (THROW NullPointer, loc) ↔ ([Null], loc, length (compE2 a), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(auto intro!: bisim1_bisims1.bisim1ALengthNull)
ultimately show ?thesis using s by auto blast
next
case (ALength1Throw A)
note [simp] = ‹a' = Throw A› ‹h' = h› ‹xs' = xs› ‹ta = ε› ‹e' = Throw A›
have τ: "τmove1 P h (Throw A∙length)" by(auto intro: τmove1ALengthThrow)
from bisim have "xcp = ⌊A⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊A⌋"
with bisim have "P,a∙length, h ⊢ (Throw A, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1_bisims1.bisim1ALengthThrow)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim obtain pc'
where "τExec_mover_a P t a h (stk, loc, pc, None) ([Addr A], loc, pc', ⌊A⌋)"
and bisim': "P, a, h ⊢ (Throw A, xs) ↔ ([Addr A], loc, pc', ⌊A⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (a∙length) h (stk, loc, pc, None) ([Addr A], loc, pc', ⌊A⌋)"
by-(rule ALength_τExecrI)
moreover from bisim' have "P, a∙length, h ⊢ (Throw A, xs) ↔ ([Addr A], loc, pc', ⌊A⌋)"
by(rule bisim1_bisims1.bisim1ALengthThrow)
ultimately show ?thesis using τ by auto
qed
qed
next
case bisim1ALengthThrow thus ?case by auto
next
case bisim1ALengthNull thus ?case by auto
next
case (bisim1FAcc E n e xs stk loc pc xcp F D)
note IH = bisim1FAcc.IH(2)
note bisim = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note red = ‹True,P,t ⊢1 ⟨e∙F{D},(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (E∙F{D}) n›
from red show ?case
proof cases
case (FAcc1Red ee')
note [simp] = ‹e' = ee'∙F{D}›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -ta→ ⟨ee', (h', xs')⟩›
from red have "τmove1 P h (e∙F{D}) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
moreover have "call1 (e∙F{D}) = call1 e" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h' ⊢ (ee', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta E e ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,E∙F{D},h' ⊢ (ee'∙F{D}, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1FAcc)
moreover {
assume "no_call2 E pc"
hence "no_call2 (E∙F{D}) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: FAcc_τExecrI FAcc_τExectI exec_move_FAccI)+
next
case (Red1FAcc a v)
hence [simp]: "e = addr a" "ta = ⦃ReadMem a (CField D F) v⦄" "e' = Val v" "h' = h" "xs' = xs"
and read: "heap_read h a (CField D F) v" by auto
from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
from bisim have "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (E∙F{D}) h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 E), None)"
by(rule FAcc_τExecrI)
moreover from read
have "exec_move_a P t (E∙F{D}) h ([Addr a], loc, length (compE2 E), None)
⦃ReadMem a (CField D F) v⦄ h' ([v], loc, Suc (length (compE2 E)), None)"
unfolding exec_move_def by(auto intro!: exec_instr)
moreover have "τmove2 (compP2 P) h [Addr a] (E∙F{D}) (length (compE2 E)) None ⟹ False" by(simp add: τmove2_iff)
moreover have "¬ τmove1 P h (addr a∙F{D})" by(auto simp add: τmove1.simps τmoves1.simps)
moreover
have "P, E∙F{D}, h' ⊢ (Val v, loc) ↔ ([v], loc, length (compE2 (E∙F{D})), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s by(auto simp add: ta_upd_simps) blast
next
case Red1FAccNull
note [simp] = ‹e = null› ‹e' = THROW NullPointer› ‹h' = h› ‹xs' = xs› ‹ta = ε›
have "¬ τmove1 P h (null∙F{D})" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from bisim have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Null], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (E∙F{D}) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 E), None)"
by-(rule FAcc_τExecrI)
moreover
have "exec_move_a P t (E∙F{D}) h ([Null], loc, length (compE2 E), None) ε h ([Null], loc, length (compE2 E), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by -(rule exec_instr, auto simp add: compP2_def dest: sees_field_idemp)
moreover have "τmove2 (compP2 P) h [Null] (E∙F{D}) (length (compE2 E)) None ⟹ False" by(simp add: τmove2_iff)
moreover
have "P,E∙F{D},h ⊢ (THROW NullPointer, loc) ↔ ([Null], loc, length (compE2 E), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1_bisims1.bisim1FAccNull)
ultimately show ?thesis using s by auto blast
next
case (FAcc1Throw a)
note [simp] = ‹e = Throw a› ‹h' = h› ‹xs' = xs› ‹ta = ε› ‹e' = Throw a›
have τ: "τmove1 P h (e∙F{D})" by(auto intro: τmove1FAccThrow)
from bisim have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim have "P,E∙F{D}, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1_bisims1.bisim1FAccThrow)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim obtain pc'
where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (E∙F{D}) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule FAcc_τExecrI)
moreover from bisim' have "P, E∙F{D}, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by(rule bisim1_bisims1.bisim1FAccThrow)
ultimately show ?thesis using τ by auto
qed
qed
next
case bisim1FAccThrow thus ?case by auto
next
case bisim1FAccNull thus ?case by auto
next
case (bisim1FAss1 e1 n e1' xs stk loc pc xcp e2 F D)
note IH1 = bisim1FAss1.IH(2)
note IH2 = bisim1FAss1.IH(4)
note bisim1 = ‹P,e1,h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok (e1∙F{D} := e2) n›
from ‹True,P,t ⊢1 ⟨e1'∙F{D} := e2,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (FAss1Red1 E')
note [simp] = ‹e' = E'∙F{D} := e2›
and red = ‹True,P,t ⊢1 ⟨e1',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have "τmove1 P h (e1'∙F{D} := e2) = τmove1 P h e1'" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from red have "call1 (e1'∙F{D} := e2) = call1 e1'" by auto
moreover from IH1[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,e1,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta e1 e1' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,e1∙F{D} := e2,h' ⊢ (E'∙F{D} := e2, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1FAss1)
moreover {
assume "no_call2 e1 pc"
hence "no_call2 (e1∙F{D} := e2) pc ∨ pc = length (compE2 e1)" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: FAss_τExecrI1 FAss_τExectI1 exec_move_FAssI1)+
next
case (FAss1Red2 E' v)
note [simp] = ‹e1' = Val v› ‹e' = Val v∙F{D} := E'›
and red = ‹True,P,t ⊢1 ⟨e2,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v∙F{D} := e2) = τmove1 P h e2" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t e1 h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
from exec1 have "τExec_mover_a P t (e1∙F{D} := e2) h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
by(rule FAss_τExecrI1)
moreover
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e2,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e2 e2 E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (e1∙F{D} := e2) (Val v∙F{D} := e2) (Val v∙F{D} := E') h ([] @ [v]) xs (length (compE2 e1) + 0) None h' (length (compE2 e1) + pc'') (stk'' @ [v]) loc'' xcp''"
proof(cases "τmove1 P h (Val v∙F{D} := e2)")
case True
with exec' τ have [simp]: "h = h'" and e: "sim_move e2 E' P t e2 h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (Val v∙F{D} := e2) (Val v∙F{D} := E') P t (e1∙F{D} := e2) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
by(fastforce dest: FAss_τExecrI2 FAss_τExectI2 simp del: compE2.simps compEs2.simps)
with True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t e2 h ([], xs, 0, None) (stk', loc', pc', xcp')"
and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'"
and call: "call1 e2 = None ∨ no_call2 e2 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs ∧ xcp' = None" by auto
from e have "τExec_mover_a P t (e1∙F{D} := e2) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk' @ [v], loc', length (compE2 e1) + pc', xcp')"
by(rule FAss_τExecrI2)
moreover from e' have "exec_move_a P t (e1∙F{D} := e2) h (stk' @ [v], loc', length (compE2 e1) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
by(rule exec_move_FAssI2)
moreover from e' have "pc' < length (compE2 e2)" by(auto elim: exec_meth.cases)
with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v]) (e1∙F{D} := e2) (length (compE2 e1) + pc') xcp'"
by(auto simp add: τmove2_iff τinstr_stk_drop_exec_move)
moreover have "call1 (e1'∙F{D} := e2) = call1 e2" by simp
moreover have "no_call2 e2 0 ⟹ no_call2 (e1∙F{D} := e2) (length (compE2 e1))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call
by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P,e1∙F{D} := e2,h' ⊢ (Val v∙F{D} := E', xs') ↔ ((stk'' @ [v]), loc'', length (compE2 e1) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1FAss2)
moreover from bisim1 have "pc ≠ length (compE2 e1) ⟶ no_call2 (e1∙F{D} := e2) pc"
by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
ultimately show ?thesis using τ exec1 s
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
done
next
case (Red1FAss a v)
note [simp] = ‹e1' = addr a› ‹e2 = Val v› ‹ta = ⦃WriteMem a (CField D F) v⦄› ‹e' = unit› ‹xs' = xs›
and "write" = ‹heap_write h a (CField D F) v h'›
have τ: "¬ τmove1 P h (e1'∙F{D} := e2)" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙F{D} := e2) h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 e1), None)"
by-(rule FAss_τExecrI1)
also have "τmove2 (compP2 P) h [Addr a] (e1∙F{D} := Val v) (length (compE2 e1)) None" by(simp add: τmove2_iff)
hence "τExec_mover_a P t (e1∙F{D} := e2) h ([Addr a], loc, length (compE2 e1), None) ([v, Addr a], loc, Suc (length (compE2 e1)), None)"
by-(rule τExecr1step, auto intro!: exec_instr simp add: exec_move_def compP2_def)
also (rtranclp_trans) from "write"
have "exec_move_a P t (e1∙F{D} := e2) h ([v, Addr a], loc, Suc (length (compE2 e1)), None) ⦃WriteMem a (CField D F) v⦄
h' ([], loc, Suc (Suc (length (compE2 e1))), None)"
unfolding exec_move_def by(auto intro!: exec_instr)
moreover have "τmove2 (compP2 P) h [v, Addr a] (e1∙F{D} := e2) (Suc (length (compE2 e1))) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙F{D} := e2, h' ⊢ (unit, loc) ↔ ([], loc, Suc (length (compE2 e1) + length (compE2 e2)), None)"
by(rule bisim1_bisims1.bisim1FAss3)
ultimately show ?thesis using s τ by(auto simp del: fun_upd_apply simp add: ta_upd_simps) blast
next
case (Red1FAssNull v)
note [simp] = ‹e1' = null› ‹e2 = Val v› ‹xs' = xs› ‹ta = ε› ‹e' = THROW NullPointer› ‹h' = h›
have τ: "¬ τmove1 P h (e1'∙F{D} := e2)" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([Null], loc, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙F{D} := e2) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 e1), None)"
by-(rule FAss_τExecrI1)
also have "τmove2 (compP2 P) h [Null] (e1∙F{D} := Val v) (length (compE2 e1)) None" by(simp add: τmove2_iff)
hence "τExec_mover_a P t (e1∙F{D} := e2) h ([Null], loc, length (compE2 e1), None) ([v, Null], loc, Suc (length (compE2 e1)), None)"
by-(rule τExecr1step, auto intro!: exec_instr simp add: exec_move_def compP2_def)
also (rtranclp_trans)
have "exec_move_a P t (e1∙F{D} := e2) h ([v, Null], loc, Suc (length (compE2 e1)), None) ε
h' ([v, Null], loc, Suc (length (compE2 e1)), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(auto intro!: exec_instr simp add: exec_move_def)
moreover have "τmove2 (compP2 P) h [v, Null] (e1∙F{D} := e2) (Suc (length (compE2 e1))) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙F{D} := e2, h ⊢ (THROW NullPointer, loc) ↔ ([v, Null], loc, length (compE2 e1) + length (compE2 e2), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1_bisims1.bisim1FAssNull)
ultimately show ?thesis using s τ by(auto simp del: fun_upd_apply) blast
next
case (FAss1Throw1 a)
note [simp] = ‹e1' = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (Throw a∙F{D} := e2)" by(rule τmove1FAssThrow1)
from bisim1 have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim1
have "P, e1∙F{D} := e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1_bisims1.intros)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim1 obtain pc' where "τExec_mover_a P t e1 h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, e1, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (e1∙F{D} := e2) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule FAss_τExecrI1)
moreover from bisim'
have "P, e1∙F{D} := e2, h⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by(rule bisim1_bisims1.bisim1FAssThrow1)
ultimately show ?thesis using τ by auto
qed
next
case (FAss1Throw2 v ad)
note [simp] = ‹e1' = Val v› ‹e2 = Throw ad› ‹e' = Throw ad› ‹h' = h› ‹xs' = xs›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙F{D} := Throw ad) h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
by-(rule FAss_τExecrI1)
also have "τExec_mover_a P t (e1∙F{D} := Throw ad) h ([v], loc, length (compE2 e1), None) ([Addr ad, v], loc, Suc (length (compE2 e1)), ⌊ad⌋)"
by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
also (rtranclp_trans)
have "P,e1∙F{D}:=Throw ad,h ⊢ (Throw ad, loc) ↔ ([Addr ad] @ [v], loc, (length (compE2 e1) + length (compE2 (addr ad))), ⌊ad⌋)"
by(rule bisim1FAssThrow2[OF bisim1Throw2])
moreover have "τmove1 P h (FAss e1' F D (Throw ad))" by(auto intro: τmove1FAssThrow2)
ultimately show ?thesis using s by auto
qed
next
case (bisim1FAss2 e2 n e2' xs stk loc pc xcp e1 F D v1)
note IH2 = bisim1FAss2.IH(2)
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
note bsok = ‹bsok (e1∙F{D} := e2) n›
note red = ‹True,P,t ⊢1 ⟨Val v1∙F{D} := e2',(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
from red show ?case
proof cases
case (FAss1Red2 E')
note [simp] = ‹e' = Val v1∙F{D} := E'›
and red = ‹True,P,t ⊢1 ⟨e2',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e2,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e2 e2' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from red have τ: "τmove1 P h (Val v1∙F{D} := e2') = τmove1 P h e2'" by(auto simp add: τmove1.simps τmoves1.simps)
have "no_call2 e2 pc ⟹ no_call2 (e1∙F{D} := e2) (length (compE2 e1) + pc)" by(auto simp add: no_call2_def)
hence "?exec ta (e1∙F{D} := e2) (Val v1∙F{D} := e2') (Val v1∙F{D} := E') h (stk @ [v1]) loc (length (compE2 e1) + pc) xcp h' (length (compE2 e1) + pc'') (stk'' @ [v1]) loc'' xcp''"
using exec' τ
apply(cases "τmove1 P h (Val v1∙F{D} := e2')")
apply(auto)
apply(blast intro: FAss_τExecrI2 FAss_τExectI2 exec_move_FAssI2)
apply(blast intro: FAss_τExecrI2 FAss_τExectI2 exec_move_FAssI2)
apply(rule exI conjI FAss_τExecrI2 exec_move_FAssI2|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
apply(rule exI conjI FAss_τExecrI2 exec_move_FAssI2|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
apply(rule exI conjI FAss_τExecrI2 exec_move_FAssI2 rtranclp.rtrancl_refl|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)+
done
moreover from bisim'
have "P,e1∙F{D} := e2,h' ⊢ (Val v1∙F{D} := E', xs') ↔ (stk''@[v1], loc'', length (compE2 e1) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1FAss2)
ultimately show ?thesis using τ by auto blast+
next
case (Red1FAss a v)
note [simp] = ‹v1 = Addr a› ‹e2' = Val v› ‹ta = ⦃WriteMem a (CField D F) v⦄› ‹e' = unit› ‹xs' = xs›
and ha = ‹heap_write h a (CField D F) v h'›
have τ: "¬ τmove1 P h (addr a∙F{D} := e2')" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙F{D} := e2) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v] @ [v1], loc, length (compE2 e1) + length (compE2 e2), None)"
by-(rule FAss_τExecrI2)
moreover from ha
have "exec_move_a P t (e1∙F{D} := e2) h ([v, Addr a], loc, length (compE2 e1) + length (compE2 e2), None) ⦃WriteMem a (CField D F) v⦄
h' ([], loc, Suc (length (compE2 e1) + length (compE2 e2)), None)"
by(auto intro!: exec_instr simp add: exec_move_def)
moreover have "τmove2 (compP2 P) h [v, Addr a] (e1∙F{D} := e2) (length (compE2 e1) + length (compE2 e2)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙F{D} := e2, h' ⊢ (unit, loc) ↔ ([], loc, Suc (length (compE2 e1) + length (compE2 e2)), None)"
by(rule bisim1_bisims1.bisim1FAss3)
ultimately show ?thesis using s τ by(auto simp del: fun_upd_apply simp add: ta_upd_simps) blast
next
case (Red1FAssNull v)
note [simp] = ‹v1 = Null› ‹e2' = Val v› ‹xs' = xs› ‹ta = ε› ‹e' = THROW NullPointer› ‹h' = h›
have τ: "¬ τmove1 P h (null∙F{D} := e2')" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙F{D} := e2) h (stk @ [Null], loc, length (compE2 e1) + pc, xcp) ([v] @ [Null], loc, length (compE2 e1) + length (compE2 e2), None)"
by-(rule FAss_τExecrI2)
moreover have "exec_move_a P t (e1∙F{D} := e2) h ([v, Null], loc, length (compE2 e1) + length (compE2 e2), None) ε
h' ([v, Null], loc, length (compE2 e1) + length (compE2 e2), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(auto intro!: exec_instr simp add: exec_move_def)
moreover have "τmove2 (compP2 P) h [v, Null] (e1∙F{D} := e2) (length (compE2 e1) + length (compE2 e2)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙F{D} := e2, h ⊢ (THROW NullPointer, loc) ↔ ([v, Null], loc, length (compE2 e1) + length (compE2 e2), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1_bisims1.bisim1FAssNull)
ultimately show ?thesis using s τ by(auto simp del: fun_upd_apply) blast
next
case (FAss1Throw2 a)
note [simp] = ‹e2' = Throw a› ‹ta = ε› ‹h' = h› ‹xs' = xs› ‹e' = Throw a›
have τ: "τmove1 P h (FAss (Val v1) F D (Throw a))" by(rule τmove1FAssThrow2)
from bisim2 have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim2
have "P, e1∙F{D} := e2, h ⊢ (Throw a, xs) ↔ (stk @ [v1], loc, length (compE2 e1) + pc, xcp)"
by(auto intro: bisim1FAssThrow2)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim2 obtain pc'
where "τExec_mover_a P t e2 h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, e2, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (e1∙F{D} := e2) h (stk @ [v1], loc, length (compE2 e1) + pc, None) ([Addr a] @ [v1], loc, length (compE2 e1) + pc', ⌊a⌋)"
by-(rule FAss_τExecrI2)
moreover from bisim'
have "P, e1∙F{D} := e2, h ⊢ (Throw a, xs) ↔ ([Addr a]@[v1], loc, length (compE2 e1) + pc', ⌊a⌋)"
by-(rule bisim1FAssThrow2, auto)
ultimately show ?thesis using τ by auto
qed
qed auto
next
case bisim1FAssThrow1 thus ?case by fastforce
next
case bisim1FAssThrow2 thus ?case by fastforce
next
case bisim1FAssNull thus ?case by fastforce
next
case bisim1FAss3 thus ?case by fastforce
next
case (bisim1CAS1 e1 n e1' xs stk loc pc xcp e2 e3 D F)
note IH1 = bisim1CAS1.IH(2)
note IH2 = bisim1CAS1.IH(4)
note IH3 = bisim1CAS1.IH(6)
note bisim1 = ‹P,e1,h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note bisim3 = ‹⋀xs. P,e3,h ⊢ (e3, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok _ n›
from ‹True,P,t ⊢1 ⟨_,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (CAS1Red1 E')
note [simp] = ‹e' = E'∙compareAndSwap(D∙F, e2, e3)›
and red = ‹True,P,t ⊢1 ⟨e1',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have "τmove1 P h (e1'∙compareAndSwap(D∙F, e2, e3)) = τmove1 P h e1'" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from red have "call1 (e1'∙compareAndSwap(D∙F, e2, e3)) = call1 e1'" by auto
moreover from IH1[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,e1,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta e1 e1' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,e1∙compareAndSwap(D∙F, e2, e3),h' ⊢ (E'∙compareAndSwap(D∙F, e2, e3), xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1CAS1)
moreover {
assume "no_call2 e1 pc"
hence "no_call2 (e1∙compareAndSwap(D∙F, e2, e3)) pc ∨ pc = length (compE2 e1)" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: CAS_τExecrI1 CAS_τExectI1 exec_move_CASI1)+
next
case (CAS1Red2 E' v)
note [simp] = ‹e1' = Val v› ‹e' = Val v∙compareAndSwap(D∙F, E', e3)›
and red = ‹True,P,t ⊢1 ⟨e2,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v∙compareAndSwap(D∙F, e2, e3)) = τmove1 P h e2" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t e1 h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
from exec1 have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
by(rule CAS_τExecrI1)
moreover
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e2,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e2 e2 E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (e1∙compareAndSwap(D∙F, e2, e3)) (Val v∙compareAndSwap(D∙F, e2, e3)) (Val v∙compareAndSwap(D∙F, E', e3)) h ([] @ [v]) xs (length (compE2 e1) + 0) None h' (length (compE2 e1) + pc'') (stk'' @ [v]) loc'' xcp''"
proof(cases "τmove1 P h (Val v∙compareAndSwap(D∙F, e2, e3))")
case True
with exec' τ have [simp]: "h = h'" and e: "sim_move e2 E' P t e2 h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (e1∙compareAndSwap(D∙F, e2, e3)) (e1∙compareAndSwap(D∙F, E', e3)) P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
by(fastforce dest: CAS_τExecrI2 CAS_τExectI2)
with True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t e2 h ([], xs, 0, None) (stk', loc', pc', xcp')"
and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'"
and call: "call1 e2 = None ∨ no_call2 e2 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs ∧ xcp' = None" by auto
from e have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk' @ [v], loc', length (compE2 e1) + pc', xcp')" by(rule CAS_τExecrI2)
moreover from e' have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk' @ [v], loc', length (compE2 e1) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
by(rule exec_move_CASI2)
moreover from e' have "pc' < length (compE2 e2)" by(auto elim: exec_meth.cases)
with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v]) (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + pc') xcp'"
by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
moreover from red have "call1 (e1'∙compareAndSwap(D∙F, e2, e3)) = call1 e2" by auto
moreover have "no_call2 e2 0 ⟹ no_call2 (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call
by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P,e1∙compareAndSwap(D∙F, e2, e3),h' ⊢ (Val v∙compareAndSwap(D∙F, E', e3), xs') ↔ ((stk'' @ [v]), loc'', length (compE2 e1) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1CAS2)
moreover from bisim1 have "pc ≠ length (compE2 e1) ⟶ no_call2 (e1∙compareAndSwap(D∙F, e2, e3)) pc"
by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
ultimately show ?thesis using τ exec1 s
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
done
next
case (CAS1Red3 E' v v')
note [simp] = ‹e2 = Val v'› ‹e1' = Val v› ‹e' = Val v∙compareAndSwap(D∙F, Val v', E')›
and red = ‹True,P,t ⊢1 ⟨e3,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v∙compareAndSwap(D∙F, Val v', e3)) = τmove1 P h e3" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t e1 h (stk, loc, pc, None) ([] @ [v], xs, length (compE2 e1) + 0, None)"
by(auto dest: bisim1Val2D1)
from exec1 have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk, loc, pc, None) ([] @ [v], xs, length (compE2 e1) + 0, None)"
by(rule CAS_τExecrI1)
also from bisim2[of xs]
have "τExec_mover_a P t e2 h ([], xs, 0, None) ([v'], xs, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v], xs, length (compE2 e1) + 0, None) ([v'] @ [v], xs, length (compE2 e1) + length (compE2 e2), None)"
by(rule CAS_τExecrI2)
also (rtranclp_trans) from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e3,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e3 e3 E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (e1∙compareAndSwap(D∙F, e2, e3)) (Val v∙compareAndSwap(D∙F, Val v', e3)) (Val v∙compareAndSwap(D∙F, Val v', E')) h ([] @ [v', v]) xs (length (compE2 e1) + length (compE2 e2) + 0) None h' (length (compE2 e1) + length (compE2 e2) + pc'') (stk'' @ [v', v]) loc'' xcp''"
proof(cases "τmove1 P h (Val v∙compareAndSwap(D∙F, Val v', e3))")
case True
with exec' τ have [simp]: "h = h'" and e: "sim_move e3 E' P t e3 h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (Val v∙compareAndSwap(D∙F, Val v', e3)) (Val v∙compareAndSwap(D∙F, Val v', E')) P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v', v], xs, length (compE2 e1) + length (compE2 e2) + 0, None) (stk'' @ [v', v], loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
by(fastforce dest: CAS_τExectI3 CAS_τExecrI3 simp del: compE2.simps compEs2.simps)
with True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t e3 h ([], xs, 0, None) (stk', loc', pc', xcp')"
and e': "exec_move_a P t e3 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' e3 pc' xcp'"
and call: "call1 e3 = None ∨ no_call2 e3 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs ∧ xcp' = None" by auto
from e have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v', v], xs, length (compE2 e1) + length (compE2 e2) + 0, None) (stk' @ [v', v], loc', length (compE2 e1) + length (compE2 e2) + pc', xcp')" by(rule CAS_τExecrI3)
moreover from e' have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk' @ [v', v], loc', length (compE2 e1) + length (compE2 e2) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v', v], loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
by(rule exec_move_CASI3)
moreover from e' τ'
have "¬ τmove2 (compP2 P) h (stk' @ [v', v]) (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + pc') xcp'"
by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
moreover have "call1 (e1'∙compareAndSwap(D∙F, e2, e3)) = call1 e3" by simp
moreover have "no_call2 e3 0 ⟹ no_call2 (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call
by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P,e1∙compareAndSwap(D∙F, e2, e3),h' ⊢ (Val v∙compareAndSwap(D∙F, Val v', E'), xs') ↔ ((stk'' @ [v', v]), loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1CAS3)
moreover from bisim1 have "pc ≠ length (compE2 e1) + length (compE2 e2) ⟶ no_call2 (e1∙compareAndSwap(D∙F, e2, e3)) pc"
by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
ultimately show ?thesis using τ exec1 s
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
done
next
case (CAS1Null v v')
note [simp] = ‹e1' = null› ‹e' = THROW NullPointer› ‹e2 = Val v› ‹xs' = xs› ‹ta = ε› ‹h' = h› ‹e3 = Val v'›
have τ: "¬ τmove1 P h (AAss null (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([] @ [Null], loc, length (compE2 e1) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk, loc, pc, xcp) ([] @ [Null], loc, length (compE2 e1) + 0, None)"
by-(rule CAS_τExecrI1)
also from bisim2[of loc] have "τExec_mover_a P t e2 h ([], loc, 0, None) ([v], loc, length (compE2 e2) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [Null], loc, length (compE2 e1) + 0, None) ([v] @ [Null], loc, length (compE2 e1) + (length (compE2 e2) + 0), None)"
by(rule CAS_τExecrI2)
also (rtranclp_trans) have "[v] @ [Null] = [] @ [v, Null]" by simp
also note add.assoc[symmetric]
also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v, Null], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
by(rule CAS_τExecrI3)
also (rtranclp_trans)
have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None) ε
h ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [v', v, Null] (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙compareAndSwap(D∙F, e2, e3), h' ⊢ (THROW NullPointer, loc) ↔ ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1_bisims1.bisim1CASFail)
ultimately show ?thesis using s τ by(auto simp add: τmove1.simps) blast
next
case (Red1CASSucceed a v v')
hence [simp]: "e1' = addr a" "e' = true" "e2 = Val v"
"ta = ⦃ReadMem a (CField D F) v, WriteMem a (CField D F) v'⦄" "xs' = xs" "e3 = Val v'"
and read: "heap_read h a (CField D F) v"
and "write": "heap_write h a (CField D F) v' h'" by auto
have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([] @ [Addr a], loc, length (compE2 e1) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk, loc, pc, xcp) ([] @ [Addr a], loc, length (compE2 e1) + 0, None)"
by-(rule CAS_τExecrI1)
also from bisim2[of loc]
have "τExec_mover_a P t e2 h ([], loc, 0, None) ([v], loc, length (compE2 e2) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [Addr a], loc, length (compE2 e1) + 0, None) ([v] @ [Addr a], loc, length (compE2 e1) + (length (compE2 e2) + 0), None)"
by(rule CAS_τExecrI2)
also (rtranclp_trans) have "[v] @ [Addr a] = [] @ [v, Addr a]" by simp
also note add.assoc[symmetric]
also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
by(rule CAS_τExecrI3)
also (rtranclp_trans) from read "write"
have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v', v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)
⦃ ReadMem a (CField D F) v, WriteMem a (CField D F) v' ⦄
h' ([Bool True], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
moreover have "τmove2 (compP2 P) h [v', v, Addr a] (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙compareAndSwap(D∙F, e2, e3), h' ⊢ (true, loc) ↔ ([Bool True], loc, length (compE2 (e1∙compareAndSwap(D∙F, e2, e3))), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
next
case (Red1CASFail a v'' v v')
hence [simp]: "e1' = addr a" "e' = false" "e2 = Val v" "h' = h"
"ta = ⦃ReadMem a (CField D F) v''⦄" "xs' = xs" "e3 = Val v'"
and read: "heap_read h a (CField D F) v''" "v ≠ v''" by auto
have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([] @ [Addr a], loc, length (compE2 e1) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk, loc, pc, xcp) ([] @ [Addr a], loc, length (compE2 e1) + 0, None)"
by-(rule CAS_τExecrI1)
also from bisim2[of loc]
have "τExec_mover_a P t e2 h ([], loc, 0, None) ([v], loc, length (compE2 e2) + 0, None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [Addr a], loc, length (compE2 e1) + 0, None) ([v] @ [Addr a], loc, length (compE2 e1) + (length (compE2 e2) + 0), None)"
by(rule CAS_τExecrI2)
also (rtranclp_trans) have "[v] @ [Addr a] = [] @ [v, Addr a]" by simp
also note add.assoc[symmetric]
also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
by(rule CAS_τExecrI3)
also (rtranclp_trans) from read
have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v', v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)
⦃ ReadMem a (CField D F) v'' ⦄
h ([Bool False], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
moreover have "τmove2 (compP2 P) h [v', v, Addr a] (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (false, loc) ↔ ([Bool False], loc, length (compE2 (e1∙compareAndSwap(D∙F, e2, e3))), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps)blast
next
case (CAS1Throw a)
hence [simp]: "e1' = Throw a" "ta = ε" "e' = Throw a" "h' = h" "xs' = xs" by auto
have τ: "τmove1 P h (Throw a∙compareAndSwap(D∙F, e2, e3))" by(rule τmove1CASThrow1)
from bisim1 have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim1 have "P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Throw a, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1_bisims1.intros)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim1 obtain pc' where "τExec_mover_a P t e1 h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, e1, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule CAS_τExecrI1)
moreover from bisim'
have "P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by(auto intro: bisim1_bisims1.bisim1CASThrow1)
ultimately show ?thesis using τ by auto
qed
next
case (CAS1Throw2 v ad)
note [simp] = ‹e1' = Val v› ‹e2 = Throw ad› ‹ta = ε› ‹e' = Throw ad› ‹h' = h› ‹xs' = xs›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, Throw ad, e3)) h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
by-(rule CAS_τExecrI1)
also have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, Throw ad, e3)) h ([v], loc, length (compE2 e1), None) ([Addr ad, v], loc, Suc (length (compE2 e1)), ⌊ad⌋)"
by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
also (rtranclp_trans)
have "P,e1∙compareAndSwap(D∙F, Throw ad, e3),h ⊢ (Throw ad, loc) ↔ ([Addr ad] @ [v], loc, (length (compE2 e1) + length (compE2 (addr ad))), ⌊ad⌋)"
by(rule bisim1CASThrow2[OF bisim1Throw2])
moreover have "τmove1 P h (e1'∙compareAndSwap(D∙F, Throw ad, e3))" by(auto intro: τmove1CASThrow2)
ultimately show ?thesis using s by auto
next
case (CAS1Throw3 v v' ad)
note [simp] = ‹e1' = Val v› ‹e2 = Val v'› ‹e3 = Throw ad› ‹ta = ε› ‹e' = Throw ad› ‹h' = h› ‹xs' = xs›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, Throw ad)) h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
by-(rule CAS_τExecrI1)
also from bisim2[of loc] have "τExec_mover_a P t e2 h ([], loc, 0, None) ([v'], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
from CAS_τExecrI2[OF this, of e1 D F e3 v]
have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, Throw ad)) h ([v], loc, length (compE2 e1), None) ([v', v], loc, length (compE2 e1) + length (compE2 e2), None)" by simp
also (rtranclp_trans)
have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, Throw ad)) h ([v', v], loc, length (compE2 e1) + length (compE2 e2), None) ([Addr ad, v', v], loc, Suc (length (compE2 e1) + length (compE2 e2)), ⌊ad⌋)"
by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
also (rtranclp_trans)
have "P,e1∙compareAndSwap(D∙F, e2, Throw ad),h ⊢ (Throw ad, loc) ↔ ([Addr ad] @ [v', v], loc, (length (compE2 e1) + length (compE2 e2) + length (compE2 (addr ad))), ⌊ad⌋)"
by(rule bisim1CASThrow3[OF bisim1Throw2])
moreover have "τmove1 P h (Val v∙compareAndSwap(D∙F, Val v', Throw ad))" by(auto intro: τmove1CASThrow3)
ultimately show ?thesis using s by auto
qed
next
case (bisim1CAS2 e2 n e2' xs stk loc pc xcp e1 e3 D F v1)
note IH2 = bisim1CAS2.IH(2)
note IH3 = bisim1CAS2.IH(6)
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
note bisim3 = ‹⋀xs. P,e3,h ⊢ (e3, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok (e1∙compareAndSwap(D∙F, e2, e3)) n›
from ‹True,P,t ⊢1 ⟨Val v1∙compareAndSwap(D∙F, e2', e3),(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (CAS1Red2 E')
note [simp] = ‹e' = Val v1∙compareAndSwap(D∙F, E', e3)›
and red = ‹True,P,t ⊢1 ⟨e2',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v1∙compareAndSwap(D∙F, e2', e3)) = τmove1 P h e2'" by(auto simp add: τmove1.simps τmoves1.simps)
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e2,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e2 e2' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (e1∙compareAndSwap(D∙F, e2, e3)) (Val v1∙compareAndSwap(D∙F, e2', e3)) (Val v1∙compareAndSwap(D∙F, E', e3)) h (stk @ [v1]) loc (length (compE2 e1) + pc) xcp h' (length (compE2 e1) + pc'') (stk'' @ [v1]) loc'' xcp''"
proof(cases "τmove1 P h (Val v1∙compareAndSwap(D∙F, e2', e3))")
case True
with exec' τ have [simp]: "h = h'" and e: "sim_move e2' E' P t e2 h (stk, loc, pc, xcp) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (Val v1∙compareAndSwap(D∙F, e2', e3)) (Val v1∙compareAndSwap(D∙F, E', e3)) P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) (stk'' @ [v1], loc'', length (compE2 e1) + pc'', xcp'')"
by(fastforce dest: CAS_τExecrI2 CAS_τExectI2 simp del: compE2.simps compEs2.simps)
with True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'"
and call: "call1 e2' = None ∨ no_call2 e2 pc ∨ pc' = pc ∧ stk' = stk ∧ loc' = loc ∧ xcp' = xcp" by auto
from e have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) (stk' @ [v1], loc', length (compE2 e1) + pc', xcp')" by(rule CAS_τExecrI2)
moreover from e' have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk' @ [v1], loc', length (compE2 e1) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v1], loc'', length (compE2 e1) + pc'', xcp'')"
by(rule exec_move_CASI2)
moreover from e' have "pc' < length (compE2 e2)" by(auto elim: exec_meth.cases)
with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v1]) (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + pc') xcp'"
by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
moreover from red have "call1 (Val v1∙compareAndSwap(D∙F, e2', e3)) = call1 e2'" by auto
moreover have "no_call2 e2 pc ⟹ no_call2 (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + pc)"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps)
qed
moreover from bisim'
have "P,e1∙compareAndSwap(D∙F, e2, e3),h' ⊢ (Val v1∙compareAndSwap(D∙F, E', e3), xs') ↔ ((stk'' @ [v1]), loc'', length (compE2 e1) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1CAS2)
ultimately show ?thesis
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans)+
done
next
case (CAS1Red3 E' v')
note [simp] = ‹e2' = Val v'› ‹e' = Val v1∙compareAndSwap(D∙F, Val v', E')›
and red = ‹True,P,t ⊢1 ⟨e3,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v1∙compareAndSwap(D∙F, Val v', e3)) = τmove1 P h e3"
by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v'], xs, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v'] @ [v1], xs, length (compE2 e1) + length (compE2 e2), None)"
by-(rule CAS_τExecrI2)
moreover from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e3,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e3 e3 E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (e1∙compareAndSwap(D∙F, e2, e3)) (Val v1∙compareAndSwap(D∙F, Val v', e3)) (Val v1⌊Val v'⌉ := E') h ([] @ [v', v1]) xs (length (compE2 e1) + length (compE2 e2) + 0) None h' (length (compE2 e1) + length (compE2 e2) + pc'') (stk'' @ [v', v1]) loc'' xcp''"
proof(cases "τmove1 P h (Val v1∙compareAndSwap(D∙F, Val v', e3))")
case True
with exec' τ have [simp]: "h = h'"
and e: "sim_move e3 E' P t e3 h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
from e have "sim_move (Val v1∙compareAndSwap(D∙F, Val v', e3)) (Val v1∙compareAndSwap(D∙F, Val v', E')) P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v', v1], xs, length (compE2 e1) + length (compE2 e2) + 0, None) (stk'' @ [v', v1], loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
by(fastforce dest: CAS_τExectI3 CAS_τExecrI3 simp del: compE2.simps compEs2.simps)
with True show ?thesis by auto
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t e3 h ([], xs, 0, None) (stk', loc', pc', xcp')"
and e': "exec_move_a P t e3 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' e3 pc' xcp'"
and call: "call1 e3 = None ∨ no_call2 e3 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs ∧ xcp' = None" by auto
from e have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v', v1], xs, length (compE2 e1) + length (compE2 e2) + 0, None) (stk' @ [v', v1], loc', length (compE2 e1) + length (compE2 e2) + pc', xcp')" by(rule CAS_τExecrI3)
moreover from e' have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk' @ [v', v1], loc', length (compE2 e1) + length (compE2 e2) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v', v1], loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
by(rule exec_move_CASI3)
moreover from e' τ' have "¬ τmove2 (compP2 P) h (stk' @ [v', v1]) (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + pc') xcp'"
by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
moreover from red have "call1 (Val v1∙compareAndSwap(D∙F, Val v', e3)) = call1 e3" by auto
moreover have "no_call2 e3 0 ⟹ no_call2 (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P,e1∙compareAndSwap(D∙F, e2, e3),h' ⊢ (Val v1∙compareAndSwap(D∙F, Val v', E'), xs') ↔ ((stk'' @ [v', v1]), loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1CAS3)
moreover from bisim2 have "pc ≠ length (compE2 e2) ⟶ no_call2 (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + pc)"
by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
ultimately show ?thesis using τ exec1 s
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
done
next
case (CAS1Null v v')
note [simp] = ‹v1 = Null› ‹e' = THROW NullPointer› ‹e2' = Val v› ‹xs' = xs› ‹ta = ε› ‹h' = h› ‹e3 = Val v'›
have τ: "¬ τmove1 P h (CompareAndSwap null D F (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [Null], loc, length (compE2 e1) + pc, xcp) ([v] @ [Null], loc, length (compE2 e1) + length (compE2 e2), None)"
by-(rule CAS_τExecrI2)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [Null], loc, length (compE2 e1) + pc, xcp) ([] @ [v, Null], loc, length (compE2 e1) + length (compE2 e2) + 0, None)" by simp
also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v, Null], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
by(rule CAS_τExecrI3)
also (rtranclp_trans)
have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None) ε
h ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [v', v, Null] (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙compareAndSwap(D∙F, e2, e3), h' ⊢ (THROW NullPointer, loc) ↔ ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1_bisims1.bisim1CASFail)
ultimately show ?thesis using s τ by auto blast
next
case (Red1CASSucceed a v v')
hence [simp]: "v1 = Addr a" "e' = true" "e2' = Val v"
"ta = ⦃ReadMem a (CField D F) v, WriteMem a (CField D F) v'⦄" "xs' = xs" "e3 = Val v'"
and read: "heap_read h a (CField D F) v"
and "write": "heap_write h a (CField D F) v' h'" by auto
have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [Addr a], loc, length (compE2 e1) + pc, xcp) ([v] @ [Addr a], loc, length (compE2 e1) + length (compE2 e2), None)"
by-(rule CAS_τExecrI2)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [Addr a], loc, length (compE2 e1) + pc, xcp) ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None)" by simp
also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
by(rule CAS_τExecrI3)
also (rtranclp_trans) from read "write"
have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v', v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)
⦃ ReadMem a (CField D F) v, WriteMem a (CField D F) v' ⦄
h' ([Bool True], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
moreover have "τmove2 (compP2 P) h [v', v, Addr a] (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙compareAndSwap(D∙F, e2, e3), h' ⊢ (true, loc) ↔ ([Bool True], loc, length (compE2 (e1∙compareAndSwap(D∙F, e2, e3))), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
next
case (Red1CASFail a v'' v v')
hence [simp]: "v1 = Addr a" "e' = false" "e2' = Val v" "h' = h"
"ta = ⦃ReadMem a (CField D F) v''⦄" "xs' = xs" "e3 = Val v'"
and read: "heap_read h a (CField D F) v''" "v ≠ v''" by auto
have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [Addr a], loc, length (compE2 e1) + pc, xcp) ([v] @ [Addr a], loc, length (compE2 e1) + length (compE2 e2), None)"
by-(rule CAS_τExecrI2)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [Addr a], loc, length (compE2 e1) + pc, xcp) ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None)" by simp
also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
by(rule CAS_τExecrI3)
also (rtranclp_trans) from read
have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v', v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)
⦃ ReadMem a (CField D F) v'' ⦄
h' ([Bool False], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
moreover have "τmove2 (compP2 P) h [v', v, Addr a] (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙compareAndSwap(D∙F, e2, e3), h' ⊢ (false, loc) ↔ ([Bool False], loc, length (compE2 (e1∙compareAndSwap(D∙F, e2, e3))), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
next
case (CAS1Throw2 ad)
note [simp] = ‹e2' = Throw ad› ‹ta = ε› ‹e' = Throw ad› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (Val v1∙compareAndSwap(D∙F, Throw ad, e3))" by(rule τmove1CASThrow2)
from bisim2 have "xcp = ⌊ad⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊ad⌋"
with bisim2
have "P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Throw ad, xs) ↔ (stk @ [v1], loc, length (compE2 e1) + pc, xcp)"
by(auto intro: bisim1_bisims1.intros)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim2 obtain pc' where "τExec_mover_a P t e2 h (stk, loc, pc, None) ([Addr ad], loc, pc', ⌊ad⌋)"
and bisim': "P, e2, h ⊢ (Throw ad, xs) ↔ ([Addr ad], loc, pc', ⌊ad⌋)"
and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [v1], loc, length (compE2 e1) + pc, None) ([Addr ad] @ [v1], loc, length (compE2 e1) + pc', ⌊ad⌋)"
by-(rule CAS_τExecrI2)
moreover from bisim'
have "P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Throw ad, xs) ↔ ([Addr ad] @ [v1], loc, length (compE2 e1) + pc', ⌊ad⌋)"
by(rule bisim1_bisims1.bisim1CASThrow2)
ultimately show ?thesis using τ by auto
qed
next
case (CAS1Throw3 v' ad)
note [simp] = ‹e2' = Val v'› ‹e3 = Throw ad› ‹ta = ε› ‹e' = Throw ad› ‹h' = h› ‹xs' = xs›
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v'], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, Throw ad)) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v'] @ [v1], loc, length (compE2 e1) + length (compE2 e2), None)"
by-(rule CAS_τExecrI2)
also have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, Throw ad)) h ([v'] @ [v1], loc, length (compE2 e1) + length (compE2 e2), None) ([Addr ad, v', v1], loc, Suc (length (compE2 e1) + length (compE2 e2)), ⌊ad⌋)"
by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
also (rtranclp_trans)
have "P,e1∙compareAndSwap(D∙F, e2, Throw ad),h ⊢ (Throw ad, loc) ↔ ([Addr ad] @ [v', v1], loc, (length (compE2 e1) + length (compE2 e2) + length (compE2 (addr ad))), ⌊ad⌋)"
by(rule bisim1CASThrow3[OF bisim1Throw2])
moreover have "τmove1 P h (CompareAndSwap (Val v1) D F (Val v') (Throw ad))" by(auto intro: τmove1CASThrow3)
ultimately show ?thesis using s by auto
qed auto
next
case (bisim1CAS3 e3 n e3' xs stk loc pc xcp e1 e2 D F v v')
note IH3 = bisim1CAS3.IH(2)
note bisim3 = ‹P,e3,h ⊢ (e3', xs) ↔ (stk, loc, pc, xcp)›
note bsok = ‹bsok (e1∙compareAndSwap(D∙F, e2, e3)) n›
from ‹True,P,t ⊢1 ⟨Val v∙compareAndSwap(D∙F, Val v', e3'),(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (CAS1Red3 E')
note [simp] = ‹e' = Val v∙compareAndSwap(D∙F, Val v', E')›
and red = ‹True,P,t ⊢1 ⟨e3',(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h (Val v∙compareAndSwap(D∙F, Val v', e3')) = τmove1 P h e3'" by(auto simp add: τmove1.simps τmoves1.simps)
from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e3,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e3 e3' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "no_call2 e3 pc ⟹ no_call2 (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + pc)"
by(auto simp add: no_call2_def)
hence "?exec ta (e1∙compareAndSwap(D∙F, e2, e3)) (Val v∙compareAndSwap(D∙F, Val v', e3')) (Val v∙compareAndSwap(D∙F, Val v', E')) h (stk @ [v', v]) loc (length (compE2 e1) + length (compE2 e2) + pc) xcp h' (length (compE2 e1) + length (compE2 e2) + pc'') (stk'' @ [v', v]) loc'' xcp''"
using exec' τ
apply(cases "τmove1 P h (Val v∙compareAndSwap(D∙F, Val v', e3'))")
apply(auto)
apply(blast intro: CAS_τExecrI3 CAS_τExectI3 exec_move_CASI3)
apply(blast intro: CAS_τExecrI3 CAS_τExectI3 exec_move_CASI3)
apply(rule exI conjI CAS_τExecrI3 exec_move_CASI3|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
apply(rule exI conjI CAS_τExecrI3 exec_move_CASI3|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
apply(rule exI conjI CAS_τExecrI3 exec_move_CASI3 rtranclp.rtrancl_refl|assumption)+
apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)+
done
moreover from bisim'
have "P,e1∙compareAndSwap(D∙F, e2, e3),h' ⊢ (Val v∙compareAndSwap(D∙F, Val v', E'), xs') ↔ (stk''@[v',v], loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1CAS3)
ultimately show ?thesis using τ by auto blast+
next
case (CAS1Null v'')
note [simp] = ‹v = Null› ‹e' = THROW NullPointer› ‹xs' = xs› ‹ta = ε› ‹h' = h› ‹e3' = Val v''›
have τ: "¬ τmove1 P h (CompareAndSwap null D F (Val v') (Val v''))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim3 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e3 h (stk, loc, pc, xcp) ([v''], loc, length (compE2 e3), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [v', Null], loc, length (compE2 e1) + length (compE2 e2) + pc, xcp) ([v''] @ [v', Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
by-(rule CAS_τExecrI3)
moreover
have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v'', v', Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None) ε
h ([v'', v', Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
moreover have "τmove2 (compP2 P) h [v'', v', Null] (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙compareAndSwap(D∙F, e2, e3), h' ⊢ (THROW NullPointer, loc) ↔ ([v'', v', Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1_bisims1.bisim1CASFail)
ultimately show ?thesis using s τ by auto blast
next
case (Red1CASSucceed a v'')
hence [simp]: "v = Addr a" "e' = true" "e3' = Val v''"
"ta = ⦃ReadMem a (CField D F) v', WriteMem a (CField D F) v''⦄" "xs' = xs"
and read: "heap_read h a (CField D F) v'"
and "write": "heap_write h a (CField D F) v'' h'" by auto
have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v') (Val v''))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim3 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t e3 h (stk, loc, pc, xcp) ([v''], loc, length (compE2 e3), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + pc, xcp) ([v''] @ [v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
by-(rule CAS_τExecrI3)
moreover from read "write"
have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v'', v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)
⦃ReadMem a (CField D F) v', WriteMem a (CField D F) v''⦄
h' ([Bool True], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
moreover have "τmove2 (compP2 P) h [v'', v', Addr a] (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙compareAndSwap(D∙F, e2, e3), h' ⊢ (true, loc) ↔ ([Bool True], loc, length (compE2 (e1∙compareAndSwap(D∙F, e2, e3))), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps ac_simps) blast
next
case (Red1CASFail a v'' v''')
hence [simp]: "v = Addr a" "e' = false" "e3' = Val v'''" "h' = h"
"ta = ⦃ReadMem a (CField D F) v''⦄" "xs' = xs"
and read: "heap_read h a (CField D F) v''" "v' ≠ v''" by auto
have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v') (Val v'''))" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim3 have s: "xcp = None" "xs = loc"
and exec1: "τExec_mover_a P t e3 h (stk, loc, pc, xcp) ([v'''], loc, length (compE2 e3), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + pc, xcp) ([v'''] @ [v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
by-(rule CAS_τExecrI3)
moreover from read
have "exec_move_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v''', v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)
⦃ReadMem a (CField D F) v''⦄
h' ([Bool False], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
moreover have "τmove2 (compP2 P) h [v''', v', Addr a] (e1∙compareAndSwap(D∙F, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None ⟹ False"
by(simp add: τmove2_iff)
moreover
have "P, e1∙compareAndSwap(D∙F, e2, e3), h' ⊢ (false, loc) ↔ ([Bool False], loc, length (compE2 (e1∙compareAndSwap(D∙F, e2, e3))), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps ac_simps) blast
next
case (CAS1Throw3 A)
note [simp] = ‹e3' = Throw A› ‹ta = ε› ‹e' = Throw A› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (CompareAndSwap (Val v) D F (Val v') (Throw A))" by(rule τmove1CASThrow3)
from bisim3 have "xcp = ⌊A⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊A⌋"
with bisim3
have "P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Throw A, xs) ↔ (stk @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc, xcp)"
by(auto intro: bisim1_bisims1.intros)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim3 obtain pc' where "τExec_mover_a P t e3 h (stk, loc, pc, None) ([Addr A], loc, pc', ⌊A⌋)"
and bisim': "P, e3, h ⊢ (Throw A, xs) ↔ ([Addr A], loc, pc', ⌊A⌋)"
and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc, None) ([Addr A] @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc', ⌊A⌋)"
by-(rule CAS_τExecrI3)
moreover from bisim'
have "P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Throw A, xs) ↔ ([Addr A] @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc', ⌊A⌋)"
by(rule bisim1_bisims1.bisim1CASThrow3)
ultimately show ?thesis using τ by auto
qed
qed auto
next
case bisim1CASThrow1 thus ?case by auto
next
case bisim1CASThrow2 thus ?case by auto
next
case bisim1CASThrow3 thus ?case by auto
next
case bisim1CASFail thus ?case by auto
next
case (bisim1CallParams ps n ps' xs stk loc pc xcp obj M' v)
note IHparam = bisim1CallParams.IH(2)
note bisim1 = ‹⋀xs. P,obj,h ⊢ (obj, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹P,ps,h ⊢ (ps', xs) [↔] (stk, loc, pc, xcp)›
note red = ‹True,P,t ⊢1 ⟨Val v∙M'(ps'),(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (obj∙M'(ps)) n›
from bisim2 ‹ps ≠ []› have ps': "ps' ≠ []" by(auto dest: bisims1_lengthD)
from red show ?case
proof cases
case (Call1Params es')
note [simp] = ‹e' = Val v∙M'(es')›
and red = ‹True,P,t ⊢1 ⟨ps', (h, xs)⟩ [-ta→] ⟨es', (h', xs')⟩›
from red have τ: "τmove1 P h (Val v∙M'(ps')) = τmoves1 P h ps'" by(auto simp add: τmove1.simps τmoves1.simps)
from IHparam[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,ps,h' ⊢ (es', xs') [↔] (stk'', loc'', pc'', xcp'')"
and exec': "?execs ta ps ps' es' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (obj∙M'(ps)) (Val v∙M'(ps')) (Val v∙M'(es')) h (stk @ [v]) loc (length (compE2 obj) + pc) xcp h' (length (compE2 obj) + pc'') (stk'' @ [v]) loc'' xcp''"
proof(cases "τmove1 P h (Val v∙M'(ps'))")
case True
with exec' τ show ?thesis by (auto intro: Call_τExecrI2 Call_τExectI2)
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_movesr_a P t ps h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
and e': "exec_moves_a P t ps h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmoves2 (compP2 P) h stk' ps pc' xcp'"
and call: "(calls1 ps' = None ∨ no_calls2 ps pc ∨ pc' = pc ∧ stk' = stk ∧ loc' = loc ∧ xcp' = xcp)" by auto
from e have "τExec_mover_a P t (obj∙M'(ps)) h (stk @ [v], loc, length (compE2 obj) + pc, xcp) (stk' @ [v], loc', length (compE2 obj) + pc', xcp')" by(rule Call_τExecrI2)
moreover from e' have "exec_move_a P t (obj∙M'(ps)) h (stk' @ [v], loc', length (compE2 obj) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 obj) + pc'', xcp'')"
by(rule exec_move_CallI2)
moreover from τ' e' have "τmove2 (compP2 P) h (stk' @ [v]) (obj∙M'(ps)) (length (compE2 obj) + pc') xcp' ⟹ False"
by(auto simp add: τmove2_iff τmoves2_iff τinstr_stk_drop_exec_moves split: if_split_asm)
moreover from red have "call1 (Val v∙M'(ps')) = calls1 ps'" by(auto simp add: is_vals_conv)
moreover from red have "no_calls2 ps pc ⟹ no_call2 (obj∙M'(ps)) (length (compE2 obj) + pc) ∨ pc = length (compEs2 ps)"
by(auto simp add: no_call2_def no_calls2_def)
ultimately show ?thesis using False call e
by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast+
qed
moreover from bisim'
have "P,obj∙M'(ps),h' ⊢ (Val v∙M'(es'), xs') ↔ ((stk'' @ [v]), loc'', length (compE2 obj) + pc'', xcp'')"
by(rule bisim1_bisims1.bisim1CallParams)
ultimately show ?thesis using τ
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split) blast+
next
case (Red1CallNull vs)
note [simp] = ‹h' = h› ‹xs' = xs› ‹ta = ε› ‹v = Null› ‹ps' = map Val vs› ‹e' = THROW NullPointer›
from bisim2 have length: "length ps = length vs" by(auto dest: bisims1_lengthD)
have "xs = loc ∧ xcp = None ∧ τExec_movesr_a P t ps h (stk, loc, pc, xcp) (rev vs, loc, length (compEs2 ps), None)"
proof(cases "pc < length (compEs2 ps)")
case True
with bisim2 show ?thesis by(auto dest: bisims1_Val_τExec_moves)
next
case False
with bisim2 have "pc = length (compEs2 ps)"
by(auto dest: bisims1_pc_length_compEs2)
with bisim2 show ?thesis by(auto dest: bisims1_Val_length_compEs2D)
qed
hence s: "xs = loc" "xcp = None"
and "τExec_movesr_a P t ps h (stk, loc, pc, xcp) (rev vs, loc, length (compEs2 ps), None)" by auto
hence "τExec_mover_a P t (obj∙M'(ps)) h (stk @ [Null], loc, length (compE2 obj) + pc, xcp) (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 ps), None)"
by -(rule Call_τExecrI2)
also {
from length have "exec_move_a P t (obj∙M'(ps)) h (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 ps), None) ε h (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 ps), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by(cases ps)(auto intro: exec_instr)
moreover have "τmove2 P h (rev vs @ [Null]) (obj∙M'(ps)) (length (compE2 obj) + length (compEs2 ps)) None"
using length by(simp add: τmove2_iff)
ultimately have "τExec_movet_a P t (obj∙M'(ps)) h (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 ps), None) (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 ps), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(auto intro: τexec_moveI) }
also have "τmove1 P h (null∙M'(map Val vs))"
by(auto simp add: τmove1.simps τmoves1.simps map_eq_append_conv)
moreover
from length have "P,obj∙M'(ps),h ⊢ (THROW NullPointer, loc) ↔ ((rev vs @ [Null]), loc, length (compE2 obj) + length (compEs2 ps), ⌊addr_of_sys_xcpt NullPointer⌋)"
by-(rule bisim1CallThrow, simp)
ultimately show ?thesis using s by auto
next
case (Call1ThrowParams vs a es')
note [simp] = ‹ta = ε› ‹e' = Throw a› ‹ps' = map Val vs @ Throw a # es'› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (Val v∙M'(map Val vs @ Throw a # es'))" by(rule τmove1CallThrowParams)
from bisim2 have [simp]: "xs = loc" and "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisims1_ThrowD)
from ‹xcp = ⌊a⌋ ∨ xcp = None› show ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim2
have "P,obj∙M'(ps),h ⊢ (Throw a, loc) ↔ (stk @ [v], loc, length (compE2 obj) + pc, ⌊a⌋)"
by -(rule bisim1CallThrowParams, auto)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim2 obtain pc'
where exec: "τExec_movesr_a P t ps h (stk, loc, pc, None) (Addr a # rev vs, loc, pc', ⌊a⌋)"
and bisim': "P, ps, h ⊢ (map Val vs @ Throw a # es', loc) [↔] (Addr a # rev vs, loc, pc', ⌊a⌋)"
by(auto dest: bisims1_Throw_τExec_movesr)
from bisim'
have "P,obj∙M'(ps),h ⊢ (Throw a, loc) ↔ ((Addr a # rev vs) @ [v], loc, length (compE2 obj) + pc', ⌊a⌋)"
by(rule bisim1CallThrowParams)
with Call_τExecrI2[OF exec, of obj M' v] τ
show ?thesis by auto
qed
next
case (Red1CallExternal a Ta Ts Tr D vs va H')
hence [simp]: "v = Addr a" "ps' = map Val vs" "e' = extRet2J (addr a∙M'(map Val vs)) va" "H' = h'" "xs' = xs"
and Ta: "typeof_addr h a = ⌊Ta⌋"
and iec: "P ⊢ class_type_of Ta sees M': Ts→Tr = Native in D"
and redex: "P,t ⊢ ⟨a∙M'(vs),h⟩ -ta→ext ⟨va,h'⟩" by auto
from bisim2 have [simp]: "xs = loc" by(auto dest: bisims_Val_loc_eq_xcp_None)
moreover from bisim2 have "length ps = length ps'"
by(rule bisims1_lengthD)
hence τ: "τmove1 P h (addr a∙M'(map Val vs) :: 'addr expr1) = τmove2 (compP2 P) h (rev vs @ [Addr a]) (obj∙M'(ps)) (length (compE2 obj) + length (compEs2 ps)) None"
using Ta iec by(auto simp add: τmove1.simps τmoves1.simps map_eq_append_conv τmove2_iff compP2_def)
obtain s: "xcp = None" "xs = loc"
and "τExec_movesr_a P t ps h (stk, loc, pc, xcp) (rev vs, loc, length (compEs2 ps), None)"
proof(cases "pc < length (compEs2 ps)")
case True
with bisim2 show ?thesis by(auto dest: bisims1_Val_τExec_moves intro: that)
next
case False
with bisim2 have "pc = length (compEs2 ps)" by(auto dest: bisims1_pc_length_compEs2)
with bisim2 show ?thesis by -(rule that, auto dest!: bisims1_pc_length_compEs2D)
qed
from Call_τExecrI2[OF this(3), of obj M' v]
have "τExec_mover_a P t (obj∙M'(ps)) h (stk @ [Addr a], loc, length (compE2 obj) + pc, xcp) (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 ps), None)" by simp
moreover from bisim2 have "pc ≤ length (compEs2 ps)" by(rule bisims1_pc_length_compEs2)
hence "no_call2 (obj∙M'(ps)) (length (compE2 obj) + pc) ∨ pc = length (compEs2 ps)"
using bisim2 by(auto simp add: no_call2_def neq_Nil_conv dest: bisims_Val_pc_not_Invoke)
moreover {
assume "pc = length (compEs2 ps)"
with ‹τExec_movesr_a P t ps h (stk, loc, pc, xcp) (rev vs, loc, length (compEs2 ps), None)›
have "stk = rev vs" "xcp = None" by auto }
moreover
let ?ret = "extRet2JVM (length ps) h' (rev vs @ [Addr a]) loc undefined undefined (length (compE2 obj) + length (compEs2 ps)) [] va"
let ?stk' = "fst (hd (snd (snd ?ret)))"
let ?xcp' = "fst ?ret"
let ?pc' = "snd (snd (snd (snd (hd (snd (snd ?ret))))))"
from bisim2 have [simp]: "length ps = length vs" by(auto dest: bisims1_lengthD)
from redex have redex': "(ta, va, h') ∈ red_external_aggr (compP2 P) t a M' vs h"
by -(rule red_external_imp_red_external_aggr, simp add: compP2_def)
with Ta iec
have "exec_move_a P t (obj∙M'(ps)) h (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 ps), None) (extTA2JVM (compP2 P) ta) h' (?stk', loc, ?pc', ?xcp')"
unfolding exec_move_def
by -(rule exec_instr,cases va,(force simp add: compP2_def is_Ref_def simp del: split_paired_Ex intro: external_WT'.intros)+)
moreover have "P,obj∙M'(ps),h' ⊢ (extRet2J1 (addr a∙M'(map Val vs)) va, loc) ↔ (?stk', loc, ?pc', ?xcp')"
proof(cases va)
case (RetVal v)
have "P,obj∙M'(ps),h' ⊢ (Val v, loc) ↔ ([v], loc, length (compE2 (obj∙M'(ps))), None)"
by(rule bisim1Val2) simp
thus ?thesis unfolding RetVal by simp
next
case (RetExc ad) thus ?thesis by(auto intro: bisim1CallThrow)
next
case RetStaySame
from bisims1_map_Val_append[OF bisims1Nil, of ps vs P h' loc]
have "P,ps,h' ⊢ (map Val vs, loc) [↔] (rev vs, loc, length (compEs2 ps), None)" by simp
hence "P,obj∙M'(ps),h' ⊢ (addr a∙M'(map Val vs), loc) ↔ (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 ps), None)"
by(rule bisim1_bisims1.bisim1CallParams)
thus ?thesis using RetStaySame by simp
qed
moreover from redex Ta iec
have "τmove1 P h (addr a∙M'(map Val vs) :: 'addr expr1) ⟹ ta = ε ∧ h' = h"
by(fastforce simp add: τmove1.simps τmoves1.simps map_eq_append_conv τexternal'_def τexternal_def dest: τexternal'_red_external_TA_empty τexternal'_red_external_heap_unchanged sees_method_fun)
ultimately show ?thesis using τ
apply(cases "τmove1 P h (addr a∙M'(map Val vs) :: 'addr expr1)")
apply(auto simp del: split_paired_Ex simp add: compP2_def)
apply(blast intro: rtranclp.rtrancl_into_rtrancl rtranclp_into_tranclp1 τexec_moveI)+
done
qed(insert ps', auto)
next
case bisim1CallThrowObj thus ?case by fastforce
next
case bisim1CallThrowParams thus ?case by auto
next
case bisim1CallThrow thus ?case by fastforce
next
case (bisim1BlockSome1 e n V Ty v xs e')
from ‹True,P,t ⊢1 ⟨{V:Ty=⌊v⌋; e},(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof(cases)
case Block1Some
note [simp] = ‹ta = ε› ‹e' = {V:Ty=None; e}› ‹h' = h› ‹xs' = xs[V := v]›
and len = ‹V < length xs›
from len have exec: "τExec_movet_a P t {V:Ty=⌊v⌋; e} h ([], xs, 0, None) ([], xs[V := v], Suc (Suc 0), None)"
by-(rule τExect2step, auto intro: exec_instr simp add: exec_move_def τmove2_iff)
moreover have "P,{V:Ty=⌊v⌋; e},h ⊢ ({V:Ty=None; e}, xs[V := v]) ↔ ([], xs[V := v], Suc (Suc 0), None)"
by(rule bisim1BlockSome4)(rule bisim1_refl)
moreover have "τmove1 P h {V:Ty=⌊v⌋; e}" by(auto intro: τmove1BlockSome)
ultimately show ?thesis by auto
qed
next
case (bisim1BlockSome2 e n V Ty v xs)
from ‹True,P,t ⊢1 ⟨{V:Ty=⌊v⌋; e},(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof(cases)
case Block1Some
note [simp] = ‹ta = ε› ‹e' = {V:Ty=None; e}› ‹h' = h› ‹xs' = xs[V := v]›
and len = ‹V < length xs›
from len have exec: "τExec_movet_a P t {V:Ty=⌊v⌋; e} h ([v], xs, Suc 0, None) ([], xs[V := v], Suc (Suc 0), None)"
by-(rule τExect1step, auto intro: exec_instr τmove2BlockSome2 simp: exec_move_def)
moreover have "P,{V:Ty=⌊v⌋; e},h ⊢ ({V:Ty=None; e}, xs[V := v]) ↔ ([], xs[V := v], Suc (Suc 0), None)"
by(rule bisim1BlockSome4)(rule bisim1_refl)
moreover have "τmove1 P h {V:Ty=⌊v⌋; e}" by(auto intro: τmove1BlockSome)
ultimately show ?thesis by auto
qed
next
case (bisim1BlockSome4 E n e xs stk loc pc xcp V Ty v)
note IH = bisim1BlockSome4.IH(2)
note bisim = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note bsok = ‹bsok {V:Ty=⌊v⌋; E} n›
hence [simp]: "n = V" by simp
from ‹True,P,t ⊢1 ⟨{V:Ty=None; e},(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Block1Red E')
note [simp] = ‹e' = {V:Ty=None; E'}›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h {V:Ty=None; e} = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
from IH[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,E,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "no_call2 E pc ⟹ no_call2 ({V:Ty=⌊v⌋; E}) (Suc (Suc pc))" by(auto simp add: no_call2_def)
hence "?exec ta {V:Ty=⌊v⌋; E} {V:Ty=None; e} {V:Ty=None; E'} h stk loc (Suc (Suc pc)) xcp h' (Suc (Suc pc'')) stk'' loc'' xcp''"
using exec' τ
by(cases "τmove1 P h {V:Ty=None; e}")(auto, (blast intro: exec_move_BlockSomeI Block_τExecrI_Some Block_τExectI_Some)+)
with bisim' τ show ?thesis by auto(blast intro: bisim1_bisims1.bisim1BlockSome4)+
next
case (Red1Block u)
note [simp] = ‹e = Val u› ‹ta = ε› ‹e' = Val u› ‹h' = h› ‹xs' = xs›
have "τmove1 P h {V:Ty=None; Val u}" by(rule τmove1BlockRed)
moreover from bisim have [simp]: "xcp = None" "loc = xs"
and exec: "τExec_mover_a P t E h (stk, loc, pc, xcp) ([u], loc, length (compE2 E), None)" by(auto dest: bisim1Val2D1)
moreover
have "P,{V:Ty=⌊v⌋; E},h ⊢ (Val u, xs) ↔ ([u], xs, length (compE2 {V:Ty=⌊v⌋; E}), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis by(fastforce elim!: Block_τExecrI_Some)
next
case (Block1Throw a)
note [simp] = ‹e = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h {V:Ty=None; e}" by(auto intro: τmove1BlockThrow)
from bisim have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim have "P, {V:Ty=⌊v⌋; E}, h ⊢ (Throw a, xs) ↔ (stk, loc, Suc (Suc pc), xcp)"
by(auto intro: bisim1BlockThrowSome)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim obtain pc'
where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t {V:Ty=⌊v⌋; E} h (stk, loc, Suc (Suc pc), None) ([Addr a], loc, Suc (Suc pc'), ⌊a⌋)"
by(auto intro: Block_τExecrI_Some)
moreover from bisim' have "P, {V:Ty=⌊v⌋; E}, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, Suc (Suc pc'), ⌊a⌋)"
by(auto intro: bisim1_bisims1.bisim1BlockThrowSome)
ultimately show ?thesis using τ by auto
qed
qed
next
case bisim1BlockThrowSome thus ?case by auto
next
case (bisim1BlockNone E n e xs stk loc pc xcp V Ty)
note IH = bisim1BlockNone.IH(2)
note bisim = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note bsok = ‹bsok {V:Ty=None; E} n›
hence [simp]: "n = V" by simp
from ‹True,P,t ⊢1 ⟨{V:Ty=None; e},(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Block1Red E')
note [simp] = ‹e' = {V:Ty=None; E'}›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmove1 P h {V:Ty=None; e} = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
moreover have "call1 ({V:Ty=None; e}) = call1 e" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,{V:Ty=None; E},h' ⊢ ({V:Ty=None; E'}, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1BlockNone)
moreover {
assume "no_call2 E pc"
hence "no_call2 {V:Ty=None; E} pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp add: exec_move_BlockNone simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Block_τExecrI_None Block_τExectI_None)+
next
case (Red1Block u)
note [simp] = ‹e = Val u› ‹ta = ε› ‹e' = Val u› ‹h' = h› ‹xs' = xs›
have "τmove1 P h {V:Ty=None; Val u}" by(rule τmove1BlockRed)
moreover from bisim have [simp]: "xcp = None" "loc = xs"
and exec: "τExec_mover_a P t E h (stk, loc, pc, xcp) ([u], loc, length (compE2 E), None)" by(auto dest: bisim1Val2D1)
moreover
have "P,{V:Ty=None; E},h ⊢ (Val u, xs) ↔ ([u], xs, length (compE2 {V:Ty=None; E}), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis by(fastforce intro: Block_τExecrI_None)
next
case (Block1Throw a)
note [simp] = ‹e = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h {V:Ty=None; e}" by(auto intro: τmove1BlockThrow)
from bisim have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim have "P, {V:Ty=None; E}, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1BlockThrowNone)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim obtain pc'
where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t {V:Ty=None; E} h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by(auto intro: Block_τExecrI_None)
moreover from bisim' have "P, {V:Ty=None; E}, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by(auto intro: bisim1_bisims1.bisim1BlockThrowNone)
ultimately show ?thesis using τ by auto
qed
qed
next
case bisim1BlockThrowNone thus ?case by auto
next
case (bisim1Sync1 e1 n e1' xs stk loc pc xcp e2 V)
note IH = bisim1Sync1.IH(2)
note bisim1 = ‹P,e1,h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note red = ‹True,P,t ⊢1 ⟨sync⇘V⇙ (e1') e2,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (sync⇘V⇙ (e1) e2) n›
hence [simp]: "n = V" by simp
from red show ?case
proof cases
case (Synchronized1Red1 E1')
note [simp] = ‹e' = sync⇘V⇙ (E1') e2›
and red = ‹True,P,t ⊢1 ⟨e1', (h, xs)⟩ -ta→ ⟨E1', (h', xs')⟩›
from red have τ: "τmove1 P h (sync⇘V⇙ (e1') e2) = τmove1 P h e1'" by(auto simp add: τmove1.simps τmoves1.simps)
moreover have "call1 (sync⇘V⇙ (e1') e2) = call1 e1'" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,e1,h' ⊢ (E1', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta e1 e1' E1' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,sync⇘V⇙ (e1) e2,h' ⊢ (sync⇘V⇙ (E1') e2, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1Sync1)
moreover {
assume "no_call2 e1 pc"
hence "no_call2 (sync⇘V⇙ (e1) e2) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Sync_τExecrI Sync_τExectI exec_move_SyncI1)+
next
case Synchronized1Null
note [simp] = ‹e1' = null› ‹e' = THROW NullPointer› ‹ta = ε› ‹h' = h› ‹xs' = xs[V := Null]›
and V = ‹V < length xs›
from bisim1 have [simp]: "xcp = None" "xs = loc"
and exec: "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([Null], loc, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
from Sync_τExecrI[OF exec]
have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 e1), None)" by simp
also from V
have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h ([Null], loc, length (compE2 e1), None) ([Null], loc[V := Null], Suc (Suc (length (compE2 e1))), None)"
by -(rule τExecr2step,auto intro: exec_instr τmove2_τmoves2.intros simp add: exec_move_def)
also (rtranclp_trans)
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Null], loc[V := Null], Suc (Suc (length (compE2 e1))), None) ε
h ([Null], loc[V := Null], Suc (Suc (length (compE2 e1))), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by(rule exec_instr) auto
moreover have "¬ τmove2 (compP2 P) h [Null] (sync⇘V⇙ (e1) e2) (Suc (Suc (length (compE2 e1)))) None"
by(simp add: τmove2_iff)
moreover
have "P,sync⇘V⇙ (e1) e2,h ⊢ (THROW NullPointer, loc[V := Null]) ↔ ([Null], (loc[V := Null]), Suc (Suc (length (compE2 e1))), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1Sync11)
moreover have "¬ τmove1 P h (sync⇘V⇙ (null) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by auto blast
next
case (Lock1Synchronized a)
note [simp] = ‹e1' = addr a› ‹ta = ⦃Lock→a, SyncLock a⦄› ‹e' = insync⇘V⇙ (a) e2› ‹h' = h› ‹xs' = xs[V := Addr a]›
and V = ‹V < length xs›
from bisim1 have [simp]: "xcp = None" "xs = loc"
and exec: "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
from Sync_τExecrI[OF exec]
have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 e1), None)" by simp
also from V
have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h ([Addr a], loc, length (compE2 e1), None) ([Addr a], loc[V := Addr a], Suc (Suc (length (compE2 e1))), None)"
by -(rule τExecr2step,auto intro: exec_instr τmove2_τmoves2.intros simp add: exec_move_def)
also (rtranclp_trans)
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a], loc[V := Addr a], Suc (Suc (length (compE2 e1))), None)
(⦃Lock→a, SyncLock a⦄)
h ([], loc[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)"
unfolding exec_move_def by -(rule exec_instr, auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a] (sync⇘V⇙ (e1) e2) (Suc (Suc (length (compE2 e1)))) None"
by(simp add: τmove2_iff)
moreover
from bisim1Sync4[OF bisim1_refl, of P h V e1 e2 a "loc[V := Addr a]"]
have "P,sync⇘V⇙ (e1) e2,h ⊢ (insync⇘V⇙ (a) e2, loc[V := Addr a]) ↔ ([], loc[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)" by simp
moreover have "¬ τmove1 P h (sync⇘V⇙ (addr a) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: eval_nat_numeral ta_upd_simps) blast
next
case (Synchronized1Throw1 a)
note [simp] = ‹e1' = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (sync⇘V⇙ (Throw a) e2)" by(rule τmove1SyncThrow)
from bisim1 have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim1
have "P, sync⇘V⇙ (e1) e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
by(auto intro: bisim1SyncThrow)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim1 obtain pc'
where "τExec_mover_a P t e1 h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, e1, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule Sync_τExecrI)
moreover from bisim'
have "P, sync⇘V⇙ (e1) e2, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by -(rule bisim1_bisims1.bisim1SyncThrow, auto)
ultimately show ?thesis using τ by fastforce
qed
qed
next
case (bisim1Sync2 e1 n e2 V v xs)
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
from ‹True,P,t ⊢1 ⟨sync⇘V⇙ (Val v) e2,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Lock1Synchronized a)
note [simp] = ‹v = Addr a› ‹ta = ⦃Lock→a, SyncLock a⦄› ‹e' = insync⇘V⇙ (a) e2›
‹h' = h› ‹xs' = xs[V := Addr a]›
and V = ‹V < length xs›
from V
have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h ([Addr a, Addr a], xs, Suc (length (compE2 e1)), None) ([Addr a], xs[V := Addr a], Suc (Suc (length (compE2 e1))), None)"
by -(rule τExecr1step,auto intro: exec_instr simp add: τmove2_iff exec_move_def)
moreover
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a], xs[V := Addr a], Suc (Suc (length (compE2 e1))), None)
(⦃Lock→a, SyncLock a⦄)
h ([], xs[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)"
unfolding exec_move_def by -(rule exec_instr, auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a] (sync⇘V⇙ (e1) e2) (Suc (Suc (length (compE2 e1)))) None"
by(simp add: τmove2_iff)
moreover
from bisim1Sync4[OF bisim1_refl, of P h V e1 e2 a "xs[V := Addr a]"]
have "P,sync⇘V⇙ (e1) e2,h ⊢ (insync⇘V⇙ (a) e2, xs[V := Addr a]) ↔ ([], xs[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)" by simp
moreover have "¬ τmove1 P h (sync⇘V⇙ (addr a) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: eval_nat_numeral ta_upd_simps) blast
next
case Synchronized1Null
note [simp] = ‹v = Null› ‹e' = THROW NullPointer› ‹ta = ε› ‹h' = h› ‹xs' = xs[V := Null]›
and V = ‹V < length xs›
from V
have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h ([Null, Null], xs, Suc (length (compE2 e1)), None) ([Null], xs[V := Null], Suc (Suc (length (compE2 e1))), None)"
by -(rule τExecr1step,auto intro: exec_instr simp add: exec_move_def τmove2_iff)
also have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Null], xs[V := Null], Suc (Suc (length (compE2 e1))), None) ε
h ([Null], xs[V := Null], Suc (Suc (length (compE2 e1))), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by(rule exec_instr) auto
moreover have "¬ τmove2 (compP2 P) h [Null] (sync⇘V⇙ (e1) e2) (Suc (Suc (length (compE2 e1)))) None"
by(simp add: τmove2_iff)
moreover
have "P,sync⇘V⇙ (e1) e2,h ⊢ (THROW NullPointer, xs[V := Null]) ↔ ([Null], (xs[V := Null]), Suc (Suc (length (compE2 e1))), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1Sync11)
moreover have "¬ τmove1 P h (sync⇘V⇙ (null) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: eval_nat_numeral) blast
qed auto
next
case (bisim1Sync3 e1 n e2 V v xs)
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
from ‹True,P,t ⊢1 ⟨sync⇘V⇙ (Val v) e2,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Lock1Synchronized a)
note [simp] = ‹v = Addr a› ‹ta = ⦃Lock→a, SyncLock a⦄› ‹e' = insync⇘V⇙ (a) e2› ‹h' = h› ‹xs' = xs[V := Addr a]›
and V = ‹V < length xs›
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a], xs[V := Addr a], Suc (Suc (length (compE2 e1))), None)
(⦃Lock→a, SyncLock a⦄)
h ([], xs[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)"
unfolding exec_move_def by -(rule exec_instr, auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a] (sync⇘V⇙ (e1) e2) (Suc (Suc (length (compE2 e1)))) None"
by(simp add: τmove2_iff)
moreover
from bisim1Sync4[OF bisim1_refl, of P h V e1 e2 a "xs[V := Addr a]"]
have "P,sync⇘V⇙ (e1) e2,h ⊢ (insync⇘V⇙ (a) e2, xs[V := Addr a]) ↔ ([], xs[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)" by simp
moreover have "¬ τmove1 P h (sync⇘V⇙ (addr a) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: eval_nat_numeral ta_upd_simps) blast
next
case Synchronized1Null
note [simp] = ‹v = Null› ‹e' = THROW NullPointer› ‹ta = ε› ‹h' = h› ‹xs' = xs[V := Null]›
and V = ‹V < length xs›
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Null], xs[V := Null], Suc (Suc (length (compE2 e1))), None) ε
h ([Null], xs[V := Null], Suc (Suc (length (compE2 e1))), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by(rule exec_instr) auto
moreover have "¬ τmove2 (compP2 P) h [Null] (sync⇘V⇙ (e1) e2) (Suc (Suc (length (compE2 e1)))) None"
by(simp add: τmove2_iff)
moreover
have "P,sync⇘V⇙ (e1) e2,h ⊢ (THROW NullPointer, xs[V := Null]) ↔ ([Null], (xs[V := Null]), Suc (Suc (length (compE2 e1))), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule bisim1Sync11)
moreover have "¬ τmove1 P h (sync⇘V⇙ (null) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: eval_nat_numeral) blast
qed auto
next
case (bisim1Sync4 e2 n e2' xs stk loc pc xcp e1 V a)
note IH = bisim1Sync4.IH(2)
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok (sync⇘V⇙ (e1) e2) n›
note red = ‹True,P,t ⊢1 ⟨insync⇘V⇙ (a) e2',(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
from red show ?case
proof cases
case (Synchronized1Red2 E')
note [simp] = ‹e' = insync⇘V⇙ (a) E'›
and red = ‹True,P,t ⊢1 ⟨e2', (h, xs)⟩ -ta→ ⟨E', (h', xs')⟩›
from red have τ: "τmove1 P h (insync⇘V⇙ (a) e2') = τmove1 P h e2'" by(auto simp add: τmove1.simps τmoves1.simps)
from IH[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e2,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e2 e2' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "no_call2 e2 pc ⟹ no_call2 (sync⇘V⇙(e1) e2) (Suc (Suc (Suc (length (compE2 e1) + pc))))"
by(auto simp add: no_call2_def)
hence "?exec ta (sync⇘V⇙ (e1) e2) (insync⇘V⇙ (a) e2') (insync⇘V⇙ (a) E') h stk loc (Suc (Suc (Suc (length (compE2 e1) + pc)))) xcp h' (Suc (Suc (Suc (length (compE2 e1) + pc'')))) stk'' loc'' xcp''"
using exec' τ
by(cases "τmove1 P h (insync⇘V⇙ (a) e2')")(auto,(blast intro: exec_move_SyncI2 Insync_τExecrI Insync_τExectI)+)
moreover from bisim'
have "P,sync⇘V⇙ (e1) e2,h' ⊢ (insync⇘V⇙ (a) E', xs') ↔ (stk'', loc'', (Suc (Suc (Suc (length (compE2 e1) + pc'')))), xcp'')"
by(rule bisim1_bisims1.bisim1Sync4)
ultimately show ?thesis using τ by auto blast+
next
case (Unlock1Synchronized a' v)
note [simp] = ‹e2' = Val v› ‹e' = Val v› ‹ta = ⦃Unlock→a', SyncUnlock a'⦄› ‹h' = h› ‹xs' = xs›
and V = ‹V < length xs› and xsV = ‹xs ! V = Addr a'›
from bisim2 have [simp]: "xcp = None" "xs = loc"
and exec: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
let ?pc1 = "(Suc (Suc (Suc (length (compE2 e1) + length (compE2 e2)))))"
note Insync_τExecrI[OF exec, of V e1]
also from V xsV have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h ([v], loc, ?pc1, None) ([Addr a', v], loc, Suc ?pc1, None)"
by -(rule τExecr1step,auto simp add: exec_move_def intro: exec_instr τmove2_τmoves2.intros)
also (rtranclp_trans)
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a', v], loc, Suc ?pc1, None) (⦃Unlock→a', SyncUnlock a'⦄) h ([v], loc, Suc (Suc ?pc1), None)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a', v] (sync⇘V⇙ (e1) e2) (Suc ?pc1) None" by(simp add: τmove2_iff)
moreover
from bisim1Sync6[of P h V e1 e2 v xs]
have "P,sync⇘V⇙ (e1) e2,h ⊢ (Val v, xs) ↔ ([v], xs, Suc (Suc ?pc1), None)"
by(auto simp add: eval_nat_numeral)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) e2')" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: ta_upd_simps) blast
next
case (Unlock1SynchronizedNull v)
note [simp] = ‹e2' = Val v› ‹e' = THROW NullPointer› ‹ta = ε› ‹h' = h› ‹xs' = xs›
and V = ‹V < length xs› and xsV = ‹xs ! V = Null›
from bisim2 have [simp]: "xcp = None" "xs = loc"
and exec: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
let ?pc1 = "(Suc (Suc (Suc (length (compE2 e1) + length (compE2 e2)))))"
note Insync_τExecrI[OF exec, of V e1]
also from V xsV have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h ([v], loc, ?pc1, None) ([Null, v], loc, Suc ?pc1, None)"
by -(rule τExecr1step,auto intro: exec_instr τmove2_τmoves2.intros simp add: exec_move_def)
also (rtranclp_trans)
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Null, v], loc, Suc ?pc1, None) ε h ([Null, v], loc, Suc ?pc1, ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Null, v] (sync⇘V⇙ (e1) e2) (Suc ?pc1) None" by(simp add: τmove2_iff)
moreover
from bisim1Sync12[of P h V e1 e2 "addr_of_sys_xcpt NullPointer" xs]
have "P,sync⇘V⇙ (e1) e2,h ⊢ (THROW NullPointer,xs) ↔ ([Null, v],xs,Suc ?pc1,⌊addr_of_sys_xcpt NullPointer⌋)"
by(auto simp add: eval_nat_numeral)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) e2')" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by auto blast
next
case (Unlock1SynchronizedFail a' v)
note [simp] = ‹e2' = Val v› ‹e' = THROW IllegalMonitorState› ‹ta = ⦃UnlockFail→a'⦄› ‹xs' = xs› ‹h' = h›
and V = ‹V < length xs› and xsV = ‹xs ! V = Addr a'›
from bisim2 have [simp]: "xcp = None" "xs = loc"
and exec: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
let ?pc1 = "(Suc (Suc (Suc (length (compE2 e1) + length (compE2 e2)))))"
note Insync_τExecrI[OF exec, of V e1]
also from V xsV have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h ([v], loc, ?pc1, None) ([Addr a', v], loc, Suc ?pc1, None)"
by -(rule τExecr1step,auto intro: exec_instr τmove2_τmoves2.intros simp add: exec_move_def)
also (rtranclp_trans)
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a', v], loc, Suc ?pc1, None) ⦃UnlockFail→a'⦄ h ([Addr a', v], loc, Suc ?pc1, ⌊addr_of_sys_xcpt IllegalMonitorState⌋)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a', v] (sync⇘V⇙ (e1) e2) (Suc ?pc1) None" by(simp add: τmove2_iff)
moreover
from bisim1Sync12[of P h V e1 e2 "addr_of_sys_xcpt IllegalMonitorState" xs "Addr a'" v]
have "P,sync⇘V⇙ (e1) e2,h ⊢ (THROW IllegalMonitorState,xs) ↔ ([Addr a', v],xs,Suc ?pc1,⌊addr_of_sys_xcpt IllegalMonitorState⌋)"
by(auto simp add: eval_nat_numeral)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) Val v)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: ta_upd_simps) blast
next
case (Synchronized1Throw2 a' ad)
note [simp] = ‹e2' = Throw ad› ‹ta = ⦃Unlock→a', SyncUnlock a'⦄› ‹e' = Throw ad›
‹h' = h› ‹xs' = xs› and xsV = ‹xs ! V = Addr a'› and V = ‹V < length xs›
let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
let ?stk = "Addr ad # drop (size stk - 0) stk"
from bisim2 have [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
from bisim2
have "τExec_movet_a P t (sync⇘V⇙ (e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), xcp) ([Addr ad], loc, ?pc, None)"
by(auto intro: bisim1_insync_Throw_exec)
also from xsV V
have "τExec_movet_a P t (sync⇘V⇙ (e1) e2) h ([Addr ad], loc, ?pc, None) ([Addr a', Addr ad], loc, Suc ?pc, None)"
by -(rule τExect1step,auto intro: exec_instr τmove2Sync7 simp add: exec_move_def)
also (tranclp_trans)
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a', Addr ad], loc, Suc ?pc, None) (⦃Unlock→a', SyncUnlock a'⦄) h ([Addr ad], loc, Suc (Suc ?pc), None)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V⇙ (e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
moreover
hence "P, sync⇘V⇙ (e1) e2, h ⊢ (Throw ad, loc) ↔ ([Addr ad], loc, 8 + length (compE2 e1) + length (compE2 e2), None)"
by(auto intro: bisim1Sync9)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: add.assoc ta_upd_simps)(blast intro: tranclp_into_rtranclp)
next
case (Synchronized1Throw2Fail a' ad)
note [simp] = ‹e2' = Throw ad› ‹ta = ⦃UnlockFail→a'⦄› ‹e' = THROW IllegalMonitorState› ‹h' = h› ‹xs' = xs›
and xsV = ‹xs ! V = Addr a'› and V = ‹V < length xs›
let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
let ?stk = "Addr ad # drop (size stk - 0) stk"
from bisim2 have [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
from bisim2
have "τExec_movet_a P t (sync⇘V⇙ (e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), xcp) ([Addr ad], loc, ?pc, None)"
by(auto intro: bisim1_insync_Throw_exec)
also from xsV V
have "τExec_movet_a P t (sync⇘V⇙ (e1) e2) h ([Addr ad], loc, ?pc, None) ([Addr a', Addr ad], loc, Suc ?pc, None)"
by -(rule τExect1step,auto intro: exec_instr τmove2Sync7 simp add: exec_move_def)
also (tranclp_trans)
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a', Addr ad], loc, Suc ?pc, None) ⦃UnlockFail→a'⦄ h ([Addr a', Addr ad], loc, Suc ?pc, ⌊addr_of_sys_xcpt IllegalMonitorState⌋)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V⇙ (e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
moreover
hence "P, sync⇘V⇙ (e1) e2, h ⊢ (THROW IllegalMonitorState, loc) ↔ ([Addr a', Addr ad], loc, 7 + length (compE2 e1) + length (compE2 e2), ⌊addr_of_sys_xcpt IllegalMonitorState⌋)"
by(auto intro: bisim1Sync14)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) e2')" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: add.assoc ta_upd_simps)(blast intro: tranclp_into_rtranclp)
next
case (Synchronized1Throw2Null ad)
note [simp] = ‹e2' = Throw ad› ‹ta = ε› ‹e' = THROW NullPointer› ‹h' = h› ‹xs' = xs›
and xsV = ‹xs ! V = Null› and V = ‹V < length xs›
let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
let ?stk = "Addr ad # drop (size stk - 0) stk"
from bisim2 have [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
from bisim2
have "τExec_movet_a P t (sync⇘V⇙ (e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), xcp) ([Addr ad], loc, ?pc, None)"
by(auto intro: bisim1_insync_Throw_exec)
also from xsV V
have "τExec_movet_a P t (sync⇘V⇙ (e1) e2) h ([Addr ad], loc, ?pc, None) ([Null, Addr ad], loc, Suc ?pc, None)"
by -(rule τExect1step,auto intro: exec_instr simp add: exec_move_def τmove2_iff)
also (tranclp_trans)
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Null, Addr ad], loc, Suc ?pc, None) ε h ([Null, Addr ad], loc, Suc ?pc, ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Null, Addr ad] (sync⇘V⇙ (e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
moreover
hence "P, sync⇘V⇙ (e1) e2, h ⊢ (THROW NullPointer, loc) ↔ ([Null, Addr ad], loc, 7 + length (compE2 e1) + length (compE2 e2), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(auto intro: bisim1Sync14)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) e2')" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: add.assoc)(blast intro: tranclp_into_rtranclp)
qed
next
case (bisim1Sync5 e1 n e2 V a v xs)
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
from ‹True,P,t ⊢1 ⟨insync⇘V⇙ (a) Val v,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Unlock1Synchronized a')
note [simp] = ‹e' = Val v› ‹ta = ⦃Unlock→a', SyncUnlock a'⦄› ‹h' = h› ‹xs' = xs›
and V = ‹V < length xs› and xsV = ‹xs ! V = Addr a'›
let ?pc1 = "4 + length (compE2 e1) + length (compE2 e2)"
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a', v], xs, ?pc1, None) ⦃Unlock→a', SyncUnlock a'⦄ h ([v], xs, Suc ?pc1, None)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a', v] (sync⇘V⇙ (e1) e2) ?pc1 None" by(simp add: τmove2_iff)
moreover
from bisim1Sync6[of P h V e1 e2 v xs]
have "P,sync⇘V⇙ (e1) e2,h ⊢ (Val v, xs) ↔ ([v], xs, Suc ?pc1, None)"
by(auto simp add: eval_nat_numeral)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) Val v)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis using xsV by(auto simp add: eval_nat_numeral ta_upd_simps) blast
next
case Unlock1SynchronizedNull
note [simp] = ‹e' = THROW NullPointer› ‹ta = ε› ‹h' = h› ‹xs' = xs›
and V = ‹V < length xs› and xsV = ‹xs ! V = Null›
let ?pc1 = "4 + length (compE2 e1) + length (compE2 e2)"
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Null, v], xs, ?pc1, None) ε h ([Null, v], xs, ?pc1, ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Null, v] (sync⇘V⇙ (e1) e2) ?pc1 None" by(simp add: τmove2_iff)
moreover
from bisim1Sync12[of P h V e1 e2 "addr_of_sys_xcpt NullPointer" xs Null v]
have "P,sync⇘V⇙ (e1) e2,h ⊢ (THROW NullPointer,xs) ↔ ([Null, v],xs,?pc1,⌊addr_of_sys_xcpt NullPointer⌋)"
by(auto simp add: eval_nat_numeral)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) Val v)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis using xsV by(auto simp add: eval_nat_numeral) blast
next
case (Unlock1SynchronizedFail a')
note [simp] = ‹e' = THROW IllegalMonitorState› ‹ta = ⦃UnlockFail→a'⦄› ‹xs' = xs› ‹h' = h›
and V = ‹V < length xs› and xsV = ‹xs ! V = Addr a'›
let ?pc1 = "4 + length (compE2 e1) + length (compE2 e2)"
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a', v], xs, ?pc1, None) ⦃UnlockFail→a'⦄ h ([Addr a', v], xs, ?pc1, ⌊addr_of_sys_xcpt IllegalMonitorState⌋)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a', v] (sync⇘V⇙ (e1) e2) ?pc1 None" by(simp add: τmove2_iff)
moreover
from bisim1Sync12[of P h V e1 e2 "addr_of_sys_xcpt IllegalMonitorState" xs "Addr a'" v]
have "P,sync⇘V⇙ (e1) e2,h ⊢ (THROW IllegalMonitorState,xs) ↔ ([Addr a', v],xs,?pc1,⌊addr_of_sys_xcpt IllegalMonitorState⌋)"
by(auto simp add: eval_nat_numeral)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) Val v)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis using xsV by(auto simp add: eval_nat_numeral ta_upd_simps) blast
qed auto
next
case bisim1Sync6 thus ?case by auto
next
case (bisim1Sync7 e1 n e2 V a ad xs)
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
from ‹True,P,t ⊢1 ⟨insync⇘V⇙ (a) Throw ad,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Synchronized1Throw2 a')
note [simp] = ‹ta = ⦃Unlock→a', SyncUnlock a'⦄› ‹e' = Throw ad› ‹h' = h› ‹xs' = xs›
and xsV = ‹xs ! V = Addr a'› and V = ‹V < length xs›
let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
from xsV V
have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h ([Addr ad], xs, ?pc, None) ([Addr a', Addr ad], xs, Suc ?pc, None)"
by -(rule τExecr1step,auto intro: exec_instr simp add: exec_move_def τmove2_iff)
moreover have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a', Addr ad], xs, Suc ?pc, None) ⦃Unlock→a', SyncUnlock a'⦄ h ([Addr ad], xs, Suc (Suc ?pc), None)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V⇙ (e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
moreover
have "P, sync⇘V⇙ (e1) e2, h ⊢ (Throw ad, xs) ↔ ([Addr ad], xs, 8 + length (compE2 e1) + length (compE2 e2), None)"
by(auto intro: bisim1Sync9)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: add.assoc eval_nat_numeral ta_upd_simps) blast
next
case (Synchronized1Throw2Fail a')
note [simp] = ‹ta = ⦃UnlockFail→a'⦄› ‹e' = THROW IllegalMonitorState› ‹h' = h› ‹xs' = xs›
and xsV = ‹xs ! V = Addr a'› and V = ‹V < length xs›
let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
from xsV V
have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h ([Addr ad], xs, ?pc, None) ([Addr a', Addr ad], xs, Suc ?pc, None)"
by -(rule τExecr1step,auto intro: exec_instr simp add: exec_move_def τmove2_iff)
moreover have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a', Addr ad], xs, Suc ?pc, None) ⦃UnlockFail→a'⦄ h ([Addr a', Addr ad], xs, Suc ?pc, ⌊addr_of_sys_xcpt IllegalMonitorState⌋)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V⇙ (e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
moreover
have "P, sync⇘V⇙ (e1) e2, h ⊢ (THROW IllegalMonitorState, xs) ↔ ([Addr a', Addr ad], xs, 7 + length (compE2 e1) + length (compE2 e2), ⌊addr_of_sys_xcpt IllegalMonitorState⌋)"
by(auto intro: bisim1Sync14)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: add.assoc ta_upd_simps) blast
next
case Synchronized1Throw2Null
note [simp] = ‹ta = ε› ‹e' = THROW NullPointer› ‹h' = h› ‹xs' = xs›
and xsV = ‹xs ! V = Null› and V = ‹V < length xs›
let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
from xsV V
have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h ([Addr ad], xs, ?pc, None) ([Null, Addr ad], xs, Suc ?pc, None)"
by -(rule τExecr1step,auto intro: exec_instr simp add: exec_move_def τmove2_iff)
moreover have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Null, Addr ad], xs, Suc ?pc, None) ε h ([Null, Addr ad], xs, Suc ?pc, ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Null, Addr ad] (sync⇘V⇙ (e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
moreover
have "P, sync⇘V⇙ (e1) e2, h ⊢ (THROW NullPointer, xs) ↔ ([Null, Addr ad], xs, 7 + length (compE2 e1) + length (compE2 e2), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(auto intro: bisim1Sync14)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis by(auto simp add: add.assoc) blast
qed auto
next
case (bisim1Sync8 e1 n e2 V a ad xs)
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
from ‹True,P,t ⊢1 ⟨insync⇘V⇙ (a) Throw ad,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Synchronized1Throw2 a')
note [simp] = ‹ta = ⦃Unlock→a', SyncUnlock a'⦄› ‹e' = Throw ad› ‹h' = h› ‹xs' = xs›
and xsV = ‹xs ! V = Addr a'› and V = ‹V < length xs›
let ?pc = "7 + length (compE2 e1) + length (compE2 e2)"
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a', Addr ad], xs, ?pc, None) ⦃Unlock→a', SyncUnlock a'⦄ h ([Addr ad], xs, Suc ?pc, None)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V⇙ (e1) e2) ?pc None" by(simp add: τmove2_iff)
moreover
have "P, sync⇘V⇙ (e1) e2, h ⊢ (Throw ad, xs) ↔ ([Addr ad], xs, 8 + length (compE2 e1) + length (compE2 e2), None)"
by(auto intro: bisim1Sync9)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis using xsV by(auto simp add: add.assoc eval_nat_numeral ta_upd_simps) blast
next
case (Synchronized1Throw2Fail a')
note [simp] = ‹ta = ⦃UnlockFail→a'⦄› ‹e' = THROW IllegalMonitorState› ‹h' = h› ‹xs' = xs›
and xsV = ‹xs ! V = Addr a'› and V = ‹V < length xs›
let ?pc = "7 + length (compE2 e1) + length (compE2 e2)"
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Addr a', Addr ad], xs, ?pc, None) ⦃UnlockFail→a'⦄ h ([Addr a', Addr ad], xs, ?pc, ⌊addr_of_sys_xcpt IllegalMonitorState⌋)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V⇙ (e1) e2) ?pc None" by(simp add: τmove2_iff)
moreover
have "P, sync⇘V⇙ (e1) e2, h ⊢ (THROW IllegalMonitorState, xs) ↔ ([Addr a', Addr ad], xs, ?pc, ⌊addr_of_sys_xcpt IllegalMonitorState⌋)"
by(auto intro: bisim1Sync14)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis using xsV by(auto simp add: add.assoc ta_upd_simps) blast
next
case Synchronized1Throw2Null
note [simp] = ‹ta = ε› ‹e' = THROW NullPointer› ‹h' = h› ‹xs' = xs›
and xsV = ‹xs ! V = Null› and V = ‹V < length xs›
let ?pc = "7 + length (compE2 e1) + length (compE2 e2)"
have "exec_move_a P t (sync⇘V⇙ (e1) e2) h ([Null, Addr ad], xs, ?pc, None) ε h ([Null, Addr ad], xs, ?pc, ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
moreover have "¬ τmove2 (compP2 P) h [Null, Addr ad] (sync⇘V⇙ (e1) e2) ?pc None" by(simp add: τmove2_iff)
moreover
have "P, sync⇘V⇙ (e1) e2, h ⊢ (THROW NullPointer, xs) ↔ ([Null, Addr ad], xs, ?pc, ⌊addr_of_sys_xcpt NullPointer⌋)"
by(auto intro: bisim1Sync14)
moreover have "¬ τmove1 P h (insync⇘V⇙ (a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
ultimately show ?thesis using xsV by(auto simp add: add.assoc) blast
qed auto
next
case bisim1Sync9 thus ?case by auto
next
case bisim1Sync10 thus ?case by auto
next
case bisim1Sync11 thus ?case by auto
next
case bisim1Sync12 thus ?case by auto
next
case bisim1Sync14 thus ?case by auto
next
case bisim1SyncThrow thus ?case by auto
next
case bisim1InSync thus ?case by simp
next
case (bisim1Seq1 e1 n e1' xs stk loc pc xcp e2)
note IH = bisim1Seq1.IH(2)
note bisim1 = ‹P,e1,h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note red = ‹True,P,t ⊢1 ⟨e1';; e2,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (e1;; e2) n›
from red show ?case
proof cases
case (Seq1Red E')
note [simp] = ‹e' = E';;e2›
and red = ‹True,P,t ⊢1 ⟨e1', (h, xs)⟩ -ta→ ⟨E', (h', xs')⟩›
from red have τ: "τmove1 P h (e1';; e2) = τmove1 P h e1'" by(auto simp add: τmove1.simps τmoves1.simps)
moreover have "call1 (e1';; e2) = call1 e1'" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,e1,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta e1 e1' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim have "P,e1;; e2,h' ⊢ (E';; e2, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1Seq1)
moreover {
assume "no_call2 e1 pc"
hence "no_call2 (e1;; e2) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Seq_τExecrI1 Seq_τExectI1 exec_move_SeqI1)+
next
case (Red1Seq v)
note [simp] = ‹e1' = Val v› ‹ta = ε› ‹h' = h› ‹xs' = xs› ‹e' = e2›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (e1;; e2) h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
by-(rule Seq_τExecrI1)
moreover have "exec_move_a P t (e1;; e2) h ([v], loc, length (compE2 e1), None) ε h ([], loc, Suc (length (compE2 e1)), None)"
unfolding exec_move_def by(rule exec_instr, auto)
moreover have "τmove2 (compP2 P) h [v] (e1;;e2) (length (compE2 e1)) None" by(simp add: τmove2_iff)
ultimately have "τExec_mover_a P t (e1;; e2) h (stk, loc, pc, xcp) ([], loc, Suc (length (compE2 e1)), None)"
by(auto intro: rtranclp.rtrancl_into_rtrancl τexec_moveI simp add: compP2_def)
moreover from bisim1_refl
have "P, e1;; e2, h ⊢ (e2, xs) ↔ ([], loc, Suc (length (compE2 e1) + 0), None)"
unfolding s by(rule bisim1Seq2)
moreover have "τmove1 P h (Val v;; e2)" by(rule τmove1SeqRed)
ultimately show ?thesis by(auto)
next
case (Seq1Throw a)
note [simp] = ‹e1' = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (Throw a;; e2)" by(rule τmove1SeqThrow)
from bisim1 have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim1 have "P, e1;; e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, xcp)"
by(auto intro: bisim1SeqThrow1)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim1 obtain pc'
where "τExec_mover_a P t e1 h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, e1, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (e1;;e2) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule Seq_τExecrI1)
moreover from bisim'
have "P, e1;;e2, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by(rule bisim1SeqThrow1)
ultimately show ?thesis using τ by auto
qed
qed
next
case bisim1SeqThrow1 thus ?case by fastforce
next
case (bisim1Seq2 e2 n e2' xs stk loc pc xcp e1)
note IH = bisim1Seq2.IH(2)
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
note red = ‹True,P,t ⊢1 ⟨e2',(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (e1;; e2) n›
from IH[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e2,h' ⊢ (e', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e2 e2' e' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "no_call2 e2 pc ⟹ no_call2 (e1;; e2) (Suc (length (compE2 e1) + pc))"
by(auto simp add: no_call2_def)
hence "?exec ta (e1;; e2) e2' e' h stk loc (Suc (length (compE2 e1) + pc)) xcp h' (Suc (length (compE2 e1) + pc'')) stk'' loc'' xcp''"
using exec' by(cases "τmove1 P h e2'")(auto, (blast intro: Seq_τExecrI2 Seq_τExectI2 exec_move_SeqI2)+)
moreover from bisim'
have "P,e1;;e2,h' ⊢ (e', xs') ↔ (stk'', loc'', Suc (length (compE2 e1) + pc''), xcp'')"
by(rule bisim1_bisims1.bisim1Seq2)
ultimately show ?case by(auto split: if_split_asm) blast+
next
case (bisim1Cond1 E n e xs stk loc pc xcp e1 e2)
note IH = bisim1Cond1.IH(2)
note bisim = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok (if (E) e1 else e2) n›
from ‹True,P,t ⊢1 ⟨if (e) e1 else e2,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Cond1Red b')
note [simp] = ‹e' = if (b') e1 else e2›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -ta→ ⟨b',(h', xs')⟩›
from red have "τmove1 P h (if (e) e1 else e2) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
moreover have "call1 (if (e) e1 else e2) = call1 e" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h' ⊢ (b', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta E e b' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,if (E) e1 else e2,h' ⊢ (if (b') e1 else e2, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1Cond1)
moreover {
assume "no_call2 E pc"
hence "no_call2 (if (E) e1 else e2) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Cond_τExecrI1 Cond_τExectI1 exec_move_CondI1)+
next
case Red1CondT
note [simp] = ‹e = true› ‹e' = e1› ‹ta = ε› ‹h' = h› ‹xs' = xs›
from bisim have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Bool True], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (if (E) e1 else e2) h (stk, loc, pc, xcp) ([Bool True], loc, length (compE2 E), None)"
by-(rule Cond_τExecrI1)
moreover have "exec_move_a P t (if (E) e1 else e2) h ([Bool True], loc, length (compE2 E), None) ε h ([], loc, Suc (length (compE2 E)), None)"
unfolding exec_move_def by(rule exec_instr, auto)
moreover have "τmove2 (compP2 P) h [Bool True] (if (E) e1 else e2) (length (compE2 E)) None" by(simp add: τmove2_iff)
ultimately have "τExec_movet_a P t (if (E) e1 else e2) h (stk, loc, pc, xcp) ([], loc, Suc (length (compE2 E)), None)"
by(auto intro: rtranclp_into_tranclp1 τexec_moveI simp add: compP2_def)
moreover have "τmove1 P h (if (true) e1 else e2)" by(rule τmove1CondRed)
moreover
from bisim1_refl
have "P, if (E) e1 else e2, h ⊢ (e1, xs) ↔ ([], loc, Suc (length (compE2 E) + 0), None)"
unfolding s by(rule bisim1CondThen)
ultimately show ?thesis by (fastforce)
next
case Red1CondF
note [simp] = ‹e = false› ‹e' = e2› ‹ta = ε› ‹h' = h› ‹xs' = xs›
from bisim have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Bool False], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (if (E) e1 else e2) h (stk, loc, pc, xcp) ([Bool False], loc, length (compE2 E), None)"
by-(rule Cond_τExecrI1)
moreover have "exec_move_a P t (if (E) e1 else e2) h ([Bool False], loc, length (compE2 E), None) ε h ([], loc, Suc (Suc (length (compE2 E) + length (compE2 e1))), None)"
unfolding exec_move_def by(rule exec_instr)(auto)
moreover have "τmove2 (compP2 P) h [Bool False] (if (E) e1 else e2) (length (compE2 E)) None" by(rule τmove2CondRed)
ultimately have "τExec_movet_a P t (if (E) e1 else e2) h (stk, loc, pc, xcp) ([], loc, Suc (Suc (length (compE2 E) + length (compE2 e1))), None)"
by(auto intro: rtranclp_into_tranclp1 τexec_moveI simp add: compP2_def)
moreover have "τmove1 P h (if (false) e1 else e2)" by(rule τmove1CondRed)
moreover
from bisim1_refl
have "P, if (E) e1 else e2, h ⊢ (e2, loc) ↔ ([], loc, (Suc (Suc (length (compE2 E) + length (compE2 e1) + 0))), None)"
unfolding s by(rule bisim1CondElse)
ultimately show ?thesis using s by auto(blast intro: tranclp_into_rtranclp)
next
case (Cond1Throw a)
note [simp] = ‹e = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (if (Throw a) e1 else e2)" by(rule τmove1CondThrow)
from bisim have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim
have "P, if (E) e1 else e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
by(auto intro: bisim1_bisims1.bisim1CondThrow)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim obtain pc'
where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (if (E) e1 else e2) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule Cond_τExecrI1)
moreover from bisim'
have "P, if (E) e1 else e2, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by-(rule bisim1CondThrow, auto)
ultimately show ?thesis using τ by auto
qed
qed
next
case (bisim1CondThen e1 n e1' xs stk loc pc xcp e e2)
note IH = bisim1CondThen.IH(2)
note bisim1 = ‹P,e1,h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)›
note bisim = ‹⋀xs. P,e,h ⊢ (e, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok (if (e) e1 else e2) n›
from IH[OF ‹True,P,t ⊢1 ⟨e1',(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e1,h' ⊢ (e', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e1 e1' e' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "no_call2 e1 pc ⟹ no_call2 (if (e) e1 else e2) (Suc (length (compE2 e) + pc))"
by(auto simp add: no_call2_def)
hence "?exec ta (if (e) e1 else e2) e1' e' h stk loc (Suc (length (compE2 e) + pc)) xcp h' (Suc (length (compE2 e) + pc'')) stk'' loc'' xcp''"
using exec' by(cases "τmove1 P h e1'")(auto, (blast intro: Cond_τExecrI2 Cond_τExectI2 exec_move_CondI2)+)
moreover from bisim'
have "P,if (e) e1 else e2,h' ⊢ (e', xs') ↔ (stk'', loc'', Suc (length (compE2 e) + pc''), xcp'')"
by(rule bisim1_bisims1.bisim1CondThen)
ultimately show ?case
by(auto split: if_split_asm) blast+
next
case (bisim1CondElse e2 n e2' xs stk loc pc xcp e e1)
note IH = bisim1CondElse.IH(2)
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
note bisim = ‹⋀xs. P,e,h ⊢ (e, xs) ↔ ([], xs, 0, None)›
note bisim1 = ‹⋀xs. P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
from IH[OF ‹True,P,t ⊢1 ⟨e2',(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›] ‹bsok (if (e) e1 else e2) n›
obtain pc'' stk'' loc'' xcp''
where bisim': "P,e2,h' ⊢ (e', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e2 e2' e' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "no_call2 e2 pc ⟹ no_call2 (if (e) e1 else e2) (Suc (Suc (length (compE2 e) + length (compE2 e1) + pc)))"
by(auto simp add: no_call2_def)
hence "?exec ta (if (e) e1 else e2) e2' e' h stk loc (Suc (Suc (length (compE2 e) + length (compE2 e1) + pc))) xcp h' (Suc (Suc (length (compE2 e) + length (compE2 e1) + pc''))) stk'' loc'' xcp''"
using exec' by(cases "τmove1 P h e2'")(auto, (blast intro: Cond_τExecrI3 Cond_τExectI3 exec_move_CondI3)+)
moreover from bisim'
have "P,if (e) e1 else e2,h' ⊢ (e', xs') ↔ (stk'', loc'', Suc (Suc (length (compE2 e) + length (compE2 e1) + pc'')), xcp'')"
by(rule bisim1_bisims1.bisim1CondElse)
ultimately show ?case
by(auto split: if_split_asm) blast+
next
case bisim1CondThrow thus ?case by auto
next
case (bisim1While1 c n e xs)
note bisim1 = ‹⋀xs. P,c,h ⊢ (c, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹⋀xs. P,e,h ⊢ (e, xs) ↔ ([], xs, 0, None)›
from ‹True,P,t ⊢1 ⟨while (c) e,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case Red1While
note [simp] = ‹ta = ε› ‹e' = if (c) (e;; while (c) e) else unit› ‹h' = h› ‹xs' = xs›
have "τmove1 P h (while (c) e)" by(rule τmove1WhileRed)
moreover
have "P,while (c) e,h ⊢ (if (c) (e;; while (c) e) else unit, xs) ↔ ([], xs, 0, None)"
by(rule bisim1_bisims1.bisim1While3[OF bisim1_refl])
moreover have "sim12_size (while (c) e) > sim12_size e'" by(simp)
ultimately show ?thesis by auto
qed
next
case (bisim1While3 c n c' xs stk loc pc xcp e)
note IH = bisim1While3.IH(2)
note bisim1 = ‹P,c,h ⊢ (c', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹⋀xs. P,e,h⊢ (e, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok (while (c) e) n›
from ‹True,P,t ⊢1 ⟨if (c') (e;; while (c) e) else unit,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Cond1Red b')
note [simp] = ‹e' = if (b') (e;; while (c) e) else unit›
and red = ‹True,P,t ⊢1 ⟨c',(h, xs)⟩ -ta→ ⟨b',(h', xs')⟩›
from red have "τmove1 P h (if (c') (e;; while (c) e) else unit) = τmove1 P h c'" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from red have "call1 (if (c') (e;;while (c) e) else unit) = call1 c'" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,c,h' ⊢ (b', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta c c' b' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,while (c) e,h' ⊢ (if (b') (e;; while (c) e) else unit, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1While3)
moreover {
assume "no_call2 c pc"
hence "no_call2 (while (c) e) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: While_τExecrI1 While_τExectI1 exec_move_WhileI1)+
next
case Red1CondT
note [simp] = ‹c' = true› ‹e' = e;; while (c) e› ‹ta = ε› ‹h' = h› ‹xs' = xs›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t c h (stk, loc, pc, xcp) ([Bool True], loc, length (compE2 c), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (while (c) e) h (stk, loc, pc, xcp) ([Bool True], loc, length (compE2 c), None)"
by-(rule While_τExecrI1)
moreover have "exec_move_a P t (while (c) e) h ([Bool True], loc, length (compE2 c), None) ε h ([], loc, Suc (length (compE2 c)), None)"
unfolding exec_move_def by(rule exec_instr, auto)
moreover have "τmove2 (compP2 P) h [Bool True] (while (c) e) (length (compE2 c)) None" by(simp add: τmove2_iff)
ultimately have "τExec_movet_a P t (while (c) e) h (stk, loc, pc, xcp) ([], loc, Suc (length (compE2 c)), None)"
by(auto intro: rtranclp_into_tranclp1 τexec_moveI simp add: compP2_def)
moreover have "τmove1 P h (if (c') (e;; while (c) e) else unit)" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from bisim1_refl
have "P, while (c) e, h ⊢ (e;; while (c) e, xs) ↔ ([], loc, Suc (length (compE2 c) + 0), None)"
unfolding s by(rule bisim1While4)
ultimately show ?thesis by (fastforce)
next
case Red1CondF
note [simp] = ‹c' = false› ‹e' = unit› ‹ta = ε› ‹h' = h› ‹xs' = xs›
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t c h (stk, loc, pc, xcp) ([Bool False], loc, length (compE2 c), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (while (c) e) h (stk, loc, pc, xcp) ([Bool False], loc, length (compE2 c), None)"
by-(rule While_τExecrI1)
moreover have "exec_move_a P t (while (c) e) h ([Bool False], loc, length (compE2 c), None) ε h ([], loc, Suc (Suc (Suc (length (compE2 c) + length (compE2 e)))), None)"
by(auto intro!: exec_instr simp add: exec_move_def)
moreover have "τmove2 (compP2 P) h [Bool False] (while (c) e) (length (compE2 c)) None" by(simp add: τmove2_iff)
ultimately have "τExec_mover_a P t (while (c) e) h (stk, loc, pc, xcp) ([], loc, Suc (Suc (Suc (length (compE2 c) + length (compE2 e)))), None)"
by(auto intro: rtranclp.rtrancl_into_rtrancl τexec_moveI simp add: compP2_def)
moreover have "τmove1 P h (if (false) (e;;while (c) e) else unit)" by(rule τmove1CondRed)
moreover have "P, while (c) e, h ⊢ (unit, xs) ↔ ([], loc, (Suc (Suc (Suc (length (compE2 c) + length (compE2 e))))), None)"
unfolding s by(rule bisim1While7)
ultimately show ?thesis using s by auto
next
case (Cond1Throw a)
note [simp] = ‹c' = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (if (c') (e;; while (c) e) else unit)" by(auto intro: τmove1CondThrow)
from bisim1 have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim1
have "P, while (c) e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
by(auto intro: bisim1_bisims1.bisim1WhileThrow1)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim1 obtain pc'
where "τExec_mover_a P t c h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, c, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (while (c) e) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule While_τExecrI1)
moreover from bisim'
have "P, while (c) e, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by-(rule bisim1WhileThrow1, auto)
ultimately show ?thesis using τ by auto
qed
qed
next
case (bisim1While4 E n e xs stk loc pc xcp c)
note IH = bisim1While4.IH(2)
note bisim2 = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note bisim1 = ‹⋀xs. P,c,h ⊢ (c, xs) ↔ ([], xs, 0, None)›
note bsok = ‹bsok (while (c) E) n›
from ‹True,P,t ⊢1 ⟨e;; while (c) E,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case (Seq1Red E')
note [simp] = ‹e' = E';;while (c) E›
and red = ‹True,P,t ⊢1 ⟨e, (h, xs)⟩ -ta→ ⟨E', (h', xs')⟩›
from red have τ: "τmove1 P h (e;; while (c) E) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
with IH[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim: "P,E,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (while (c) E) (e;;while (c) E) (E';;while (c) E) h stk loc (Suc (length (compE2 c) + pc)) xcp h' (Suc (length (compE2 c) + pc'')) stk'' loc'' xcp''"
proof(cases "τmove1 P h (e;; while (c) E)")
case True
with exec' show ?thesis using τ by(fastforce intro: While_τExecrI2 While_τExectI2)
next
case False
with exec' τ obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t E h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
and e': "exec_move_a P t E h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' E pc' xcp'"
and call: "(call1 e = None ∨ no_call2 E pc ∨ pc' = pc ∧ stk' = stk ∧ loc' = loc ∧ xcp' = xcp)" by auto
from e have "τExec_mover_a P t (while (c) E) h (stk, loc, Suc (length (compE2 c) + pc), xcp) (stk', loc', Suc (length (compE2 c) + pc'), xcp')" by(rule While_τExecrI2)
moreover
from e' have "exec_move_a P t (while (c) E) h (stk', loc', Suc (length (compE2 c) + pc'), xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', Suc (length (compE2 c) + pc''), xcp'')"
by(rule exec_move_WhileI2)
moreover from τ' e' have "¬ τmove2 (compP2 P) h stk' (while (c) E) (Suc (length (compE2 c) + pc')) xcp'"
by(auto simp add: τmove2_iff)
moreover have "call1 (e;; while (c) E) = call1 e" by simp
moreover have "no_call2 E pc ⟹ no_call2 (while (c) E) (Suc (length (compE2 c) + pc))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps)
qed
with bisim τ show ?thesis by auto (blast intro: bisim1_bisims1.bisim1While4)+
next
case (Red1Seq v)
note [simp] = ‹e = Val v› ‹ta = ε› ‹e' = while (c) E› ‹h' = h› ‹xs' = xs›
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (while (c) E) h (stk, loc, Suc (length (compE2 c) + pc), xcp) ([v], loc, Suc (length (compE2 c) + length (compE2 E)), None)"
by-(rule While_τExecrI2)
moreover
have "exec_move_a P t (while (c) E) h ([v], loc, Suc (length (compE2 c) + length (compE2 E)), None) ε h ([], loc, Suc (Suc (length (compE2 c) + length (compE2 E))), None)"
unfolding exec_move_def by(rule exec_instr, auto)
moreover have "τmove2 (compP2 P) h [v] (while (c) E) (Suc (length (compE2 c) + length (compE2 E))) None" by(simp add: τmove2_iff)
ultimately have "τExec_movet_a P t (while (c) E) h (stk, loc, Suc (length (compE2 c) + pc), xcp) ([], loc, Suc (Suc (length (compE2 c) + length (compE2 E))), None)"
by(auto intro: rtranclp_into_tranclp1 τexec_moveI simp add: compP2_def)
moreover
have "P, while (c) E, h ⊢ (while (c) E, xs) ↔ ([], xs, (Suc (Suc (length (compE2 c) + length (compE2 E)))), None)"
unfolding s by(rule bisim1While6)
moreover have "τmove1 P h (e;; while (c) E)" by(auto intro: τmove1SeqRed)
ultimately show ?thesis using s by(auto)(blast intro: tranclp_into_rtranclp)
next
case (Seq1Throw a)
note [simp] = ‹e = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (e;; while (c) E)" by(auto intro: τmove1SeqThrow)
from bisim2 have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim2
have "P, while (c) E, h ⊢ (Throw a, xs) ↔ (stk, loc, Suc (length (compE2 c) + pc), xcp)"
by(auto intro: bisim1WhileThrow2)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim2 obtain pc'
where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (while (c) E) h (stk, loc, Suc (length (compE2 c) + pc), None) ([Addr a], loc, Suc (length (compE2 c) + pc'), ⌊a⌋)"
by-(rule While_τExecrI2)
moreover from bisim'
have "P, while (c) E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, Suc (length (compE2 c) + pc'), ⌊a⌋)"
by-(rule bisim1WhileThrow2, auto)
ultimately show ?thesis using τ by auto
qed
qed
next
case (bisim1While6 c n e xs)
note bisim1 = ‹⋀xs. P,c,h ⊢ (c, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹⋀xs. P,e,h ⊢ (e, xs) ↔ ([], xs, 0, None)›
from ‹True,P,t ⊢1 ⟨while (c) e,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩› show ?case
proof cases
case Red1While
note [simp] = ‹ta = ε› ‹e' = if (c) (e;; while (c) e) else unit› ‹h' = h› ‹xs' = xs›
have "τmove1 P h (while (c) e)" by(rule τmove1WhileRed)
moreover
have "P,while (c) e,h ⊢ (if (c) (e;; while (c) e) else unit, xs) ↔ ([], xs, 0, None)"
by(rule bisim1_bisims1.bisim1While3[OF bisim1_refl])
moreover have "τExec_movet_a P t (while (c) e) h ([], xs, Suc (Suc (length (compE2 c) + length (compE2 e))), None) ([], xs, 0, None)"
by(rule τExect1step)(auto simp add: exec_move_def τmove2_iff intro: exec_instr)
ultimately show ?thesis by(fastforce)
qed
next
case bisim1While7 thus ?case by fastforce
next
case bisim1WhileThrow1 thus ?case by auto
next
case bisim1WhileThrow2 thus ?case by auto
next
case (bisim1Throw1 E n e xs stk loc pc xcp)
note IH = bisim1Throw1.IH(2)
note bisim = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note red = ‹True,P,t ⊢1 ⟨throw e,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (throw E) n›
from red show ?case
proof cases
case (Throw1Red E')
note [simp] = ‹e' = throw E'›
and red = ‹True,P,t ⊢1 ⟨e, (h, xs)⟩ -ta→ ⟨E', (h', xs')⟩›
from red have "τmove1 P h (throw e) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
moreover have "call1 (throw e) = call1 e" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,throw E,h' ⊢ (throw E', xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1Throw1)
moreover {
assume "no_call2 E pc"
hence "no_call2 (throw E) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Throw_τExecrI Throw_τExectI exec_move_ThrowI)+
next
case Red1ThrowNull
note [simp] = ‹e = null› ‹ta = ε› ‹e' = THROW NullPointer› ‹h' = h› ‹xs' = xs›
from bisim have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Null], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (throw E) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 E), None)"
by-(rule Throw_τExecrI)
also have "τExec_movet_a P t (throw E) h ([Null], loc, length (compE2 E), None) ([Null], loc, length (compE2 E), ⌊addr_of_sys_xcpt NullPointer⌋)"
by(rule τExect1step)(auto intro: exec_instr τmove2_τmoves2.intros simp add: exec_move_def)
also have "P, throw E, h ⊢ (THROW NullPointer, xs) ↔ ([Null], loc, length (compE2 E), ⌊addr_of_sys_xcpt NullPointer⌋)"
unfolding s by(rule bisim1ThrowNull)
moreover have "τmove1 P h (throw e)" by(auto intro: τmove1ThrowNull)
ultimately show ?thesis by auto
next
case (Throw1Throw a)
note [simp] = ‹e = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (throw (Throw a))" by(rule τmove1ThrowThrow)
from bisim have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume "xcp = ⌊a⌋"
with bisim show ?thesis using τ by(fastforce intro: bisim1ThrowThrow)
next
assume [simp]: "xcp = None"
from bisim obtain pc'
where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim: "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and s: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (throw E) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by -(rule Throw_τExecrI)
moreover from bisim have "P, throw E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by(rule bisim1ThrowThrow)
ultimately show ?thesis using τ by auto
qed
qed
next
case bisim1Throw2 thus ?case by auto
next
case bisim1ThrowNull thus ?case by auto
next
case bisim1ThrowThrow thus ?case by auto
next
case (bisim1Try E n e xs stk loc pc xcp e2 C' V)
note IH = bisim1Try.IH(2)
note bisim1 = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note red = ‹True,P,t ⊢1 ⟨try e catch(C' V) e2,(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (try E catch(C' V) e2) n›
from red show ?case
proof cases
case (Try1Red E')
note [simp] = ‹e' = try E' catch(C' V) e2›
and red = ‹True,P,t ⊢1 ⟨e, (h, xs)⟩ -ta→ ⟨E', (h', xs')⟩›
from red have "τmove1 P h (try e catch(C' V) e2) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
moreover have "call1 (try e catch(C' V) e2) = call1 e" by auto
moreover from IH[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,try E catch(C' V) e2,h' ⊢ (try E' catch(C' V) e2, xs') ↔ (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisim1Try)
moreover {
assume "no_call2 E pc"
hence "no_call2 (try E catch(C' V) e2) pc" by(auto simp add: no_call2_def) }
ultimately show ?thesis using redo
by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Try_τExecrI1 Try_τExectI1 exec_move_TryI1)+
next
case (Red1Try v)
note [simp] = ‹e = Val v› ‹ta = ε› ‹e' = Val v› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h (try Val v catch(C' V) e2)" by(rule τmove1TryRed)
from bisim1 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (try E catch(C' V) e2) h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
by-(rule Try_τExecrI1)
also have "τExec_mover_a P t (try E catch(C' V) e2) h ([v], loc, length (compE2 E), None) ([v], loc, length (compE2 (try E catch(C' V) e2)), None)"
by(rule τExecr1step)(auto intro: exec_instr simp add: exec_move_def τmove2_iff)
also (rtranclp_trans)
have "P, try E catch(C' V) e2, h ⊢ (Val v, xs) ↔ ([v], xs, length (compE2 (try E catch(C' V) e2)), None)"
by(rule bisim1Val2) simp
ultimately show ?thesis using s τ by(auto)
next
case (Red1TryCatch a D)
hence [simp]: "e = Throw a" "ta = ε" "e' = {V:Class C'=None; e2}" "h' = h" "xs' = xs[V := Addr a]"
and ha: "typeof_addr h a = ⌊Class_type D⌋" and sub: "P ⊢ D ≼⇧* C'"
and V: "V < length xs" by auto
from bisim1 have [simp]: "xs = loc" and xcp: "xcp = ⌊a⌋ ∨ xcp = None"
by(auto dest: bisim1_ThrowD)
from xcp have "τExec_mover_a P t (try E catch(C' V) e2) h (stk, loc, pc, xcp) ([Addr a], loc, Suc (length (compE2 E)), None)"
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim1 have "match_ex_table (compP2 P) (cname_of h a) pc (compxE2 E 0 0) = None"
by(auto dest: bisim1_xcp_Some_not_caught[where pc'=0] simp add: compP2_def)
moreover from bisim1 have "pc < length (compE2 E)"
by(auto dest: bisim1_ThrowD)
ultimately show ?thesis using ha sub unfolding ‹xcp = ⌊a⌋›
by-(rule τExecr1step[unfolded exec_move_def, OF exec_catch[where d=0, simplified]],
auto simp add: τmove2_iff matches_ex_entry_def compP2_def match_ex_table_append_not_pcs cname_of_def)
next
assume [simp]: "xcp = None"
with bisim1 obtain pc' where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and s: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (try E catch(C' V) e2) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule Try_τExecrI1)
also from bisim' have "match_ex_table (compP2 P) (cname_of h a) pc' (compxE2 E 0 0) = None"
by(auto dest: bisim1_xcp_Some_not_caught[where pc'=0] simp add: compP2_def)
with ha sub bisim1_ThrowD[OF bisim']
have "τExec_mover_a P t (try E catch(C' V) e2) h ([Addr a], loc, pc', ⌊a⌋) ([Addr a], loc, Suc (length (compE2 E)), None)"
by-(rule τExecr1step[unfolded exec_move_def, OF exec_catch[where d=0, simplified]], auto simp add: τmove2_iff matches_ex_entry_def compP2_def match_ex_table_append_not_pcs cname_of_def)
finally (rtranclp_trans) show ?thesis by simp
qed
also let ?pc' = "Suc (length (compE2 E))" from V
have exec: "τExec_movet_a P t (try E catch(C' V) e2) h ([Addr a], loc, ?pc', None) ([], loc[V := Addr a], Suc ?pc', None)"
by-(rule τExect1step[unfolded exec_move_def, OF exec_instr], auto simp add: nth_append intro: τmove2_τmoves2.intros)
also (rtranclp_tranclp_tranclp)
have bisim': "P,try E catch(C' V) e2, h ⊢ ({V:Class C'=None; e2}, xs[V := Addr a]) ↔ ([], loc[V := Addr a], Suc ?pc', None)"
unfolding ‹xs = loc› by(rule bisim1TryCatch2[OF bisim1_refl, simplified])
moreover have "τmove1 P h (try Throw a catch(C' V) e2)" by(rule τmove1TryThrow)
ultimately show ?thesis by(auto)(blast intro: tranclp_into_rtranclp)
next
case (Red1TryFail a D)
hence [simp]: "e = Throw a" "ta = ε" "e' = Throw a" "h' = h" "xs' = xs"
and ha: "typeof_addr h a = ⌊Class_type D⌋" and sub: "¬ P ⊢ D ≼⇧* C'" by auto
have τ: "τmove1 P h (try Throw a catch(C' V) e2)" by(rule τmove1TryThrow)
from bisim1 have [simp]: "xs = loc" and "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
from bisim1 have pc: "pc ≤ length (compE2 E)" by(rule bisim1_pc_length_compE2)
from ‹xcp = ⌊a⌋ ∨ xcp = None› show ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim1 ha sub
have "P,try E catch(C' V) e2,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
by(auto intro: bisim1TryFail)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim1 obtain pc'
where "τExec_mover_a P t E h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, E, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (try E catch(C' V) e2) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule Try_τExecrI1)
moreover from bisim' ha sub
have "P,try E catch(C' V) e2,h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)"
by(auto intro: bisim1TryFail)
ultimately show ?thesis using τ by auto
qed
qed
next
case (bisim1TryCatch1 e n a xs stk loc pc D C' e2 V)
note bisim1 = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note IH2 = bisim1TryCatch1.IH(6)
note ha = ‹typeof_addr h a = ⌊Class_type D⌋›
note sub = ‹P ⊢ D ≼⇧* C'›
note red = ‹True,P,t ⊢1 ⟨{V:Class C'=None; e2},(h, xs[V := Addr a])⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (try e catch(C' V) e2) n›
from bisim1 have [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
from red show ?case
proof cases
case (Block1Red E')
note [simp] = ‹e' = {V:Class C'=None; E'}›
and red = ‹True,P,t ⊢1 ⟨e2, (h, xs[V := Addr a])⟩ -ta→ ⟨E', (h', xs')⟩›
from red have τ: "τmove1 P h {V:Class C'=None; e2} = τmove1 P h e2" by(auto simp add: τmove1.simps τmoves1.simps)
have exec: "τExec_mover_a P t (try e catch(C' V) e2) h ([Addr a], xs, Suc (length (compE2 e) + 0), None) ([], xs[V := Addr a], Suc (Suc (length (compE2 e) + 0)), None)"
by -(rule τExecr1step, auto simp add: exec_move_def τmove2_iff intro: exec_instr)
moreover from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e2,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e2 e2 E' h [] (xs[V := Addr a]) 0 None h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (try e catch(C' V) e2) {V:Class C'=None; e2} {V:Class C'=None; E'} h [] (xs[V := Addr a]) (Suc (Suc (length (compE2 e)))) None h' (Suc (Suc (length (compE2 e) + pc''))) stk'' loc'' xcp''"
proof(cases "τmove1 P h {V:Class C'=None; e2}")
case True with τ exec' show ?thesis
by(fastforce dest: Try_τExecrI2 Try_τExectI2 simp del: compE2.simps compEs2.simps)
next
case False
with τ exec' obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t e2 h ([], xs[V := Addr a], 0, None) (stk', loc', pc', xcp')"
and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'"
and call: "call1 e2 = None ∨ no_call2 e2 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs[V := Addr a] ∧ xcp' = None" by auto
from e have "τExec_mover_a P t (try e catch(C' V) e2) h ([], xs[V := Addr a], Suc (Suc (length (compE2 e) + 0)), None) (stk', loc', Suc (Suc (length (compE2 e) + pc')), xcp')"
by(rule Try_τExecrI2)
moreover from e'
have "exec_move_a P t (try e catch(C' V) e2) h (stk', loc', Suc (Suc (length (compE2 e) + pc')), xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', Suc (Suc (length (compE2 e) + pc'')), xcp'')"
by(rule exec_move_TryI2)
moreover from τ' have "τmove2 (compP2 P) h stk' (try e catch(C' V) e2) (Suc (Suc (length (compE2 e) + pc'))) xcp' ⟹ False"
by(simp add: τmove2_iff)
moreover have "call1 {V:Class C'=None; e2} = call1 e2" by simp
moreover have "no_call2 e2 0 ⟹ no_call2 (try e catch(C' V) e2) (Suc (Suc (length (compE2 e))))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P, try e catch(C' V) e2, h' ⊢ ({V:Class C'=None; E'}, xs') ↔ (stk'', loc'', Suc (Suc (length (compE2 e) + pc'')), xcp'')"
by(rule bisim1TryCatch2)
moreover have "no_call2 (try e catch(C' V) e2) (Suc (length (compE2 e)))" by(simp add: no_call2_def)
ultimately show ?thesis using τ
by auto(blast intro: rtranclp_trans rtranclp_tranclp_tranclp)+
next
case (Red1Block u)
note [simp] = ‹e2 = Val u› ‹ta = ε› ‹e' = Val u› ‹h' = h› ‹xs' = xs[V := Addr a]›
have "τExec_mover_a P t (try e catch(C' V) Val u) h ([Addr a], xs, Suc (length (compE2 e) + 0), None) ([], xs[V := Addr a], Suc (Suc (length (compE2 e) + 0)), None)"
by -(rule τExecr1step, auto simp add: exec_move_def τmove2_iff intro: exec_instr)
also have "τExec_mover_a P t (try e catch(C' V) Val u) h ([], xs[V := Addr a], Suc (Suc (length (compE2 e) + 0)), None) ([u], xs[V := Addr a], Suc (Suc (length (compE2 e) + 1)), None)"
by -(rule Try_τExecrI2[OF τExecr1step[unfolded exec_move_def, OF exec_instr]], auto simp add: τmove2_iff)
also (rtranclp_trans)
have "P, try e catch(C' V) Val u, h ⊢ (Val u, xs[V := Addr a]) ↔ ([u], xs[V := Addr a], length (compE2 (try e catch(C' V) Val u)), None)"
by(rule bisim1Val2) simp
moreover have "τmove1 P h {V:Class C'=None; Val u}" by(rule τmove1BlockRed)
ultimately show ?thesis by(auto)
next
case (Block1Throw a')
note [simp] = ‹e2 = Throw a'› ‹h' = h› ‹ta = ε› ‹e' = Throw a'› ‹xs' = xs[V := Addr a]›
have "τmove1 P h {V:Class C'=None; Throw a'}" by(rule τmove1BlockThrow)
moreover have "τExec_mover_a P t (try e catch(C' V) e2) h ([Addr a], loc, Suc (length (compE2 e)), None)
([Addr a'], xs', Suc (Suc (Suc (length (compE2 e)))), ⌊a'⌋)"
by(rule τExecr3step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff)
moreover have "P, try e catch(C' V) Throw a', h ⊢ (Throw a', xs') ↔ ([Addr a'], xs', Suc (Suc (length (compE2 e) + length (compE2 (addr a')))), ⌊a'⌋)"
by(rule bisim1TryCatchThrow)(rule bisim1Throw2)
ultimately show ?thesis by auto
qed
next
case (bisim1TryCatch2 e2 n e2' xs stk loc pc xcp e C' V)
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
note bisim1 = ‹⋀xs. P,e,h ⊢ (e, xs) ↔ ([], xs, 0, None)›
note IH2 = bisim1TryCatch2.IH(2)
note red = ‹True,P,t ⊢1 ⟨{V:Class C'=None; e2'},(h, xs)⟩ -ta→ ⟨e',(h', xs')⟩›
note bsok = ‹bsok (try e catch(C' V) e2) n›
from red show ?case
proof cases
case (Block1Red E')
note [simp] = ‹e' = {V:Class C'=None; E'}›
and red = ‹True,P,t ⊢1 ⟨e2', (h, xs)⟩ -ta→ ⟨E', (h', xs')⟩›
from red have τ: "τmove1 P h {V:Class C'=None; e2'} = τmove1 P h e2'" by(auto simp add: τmove1.simps τmoves1.simps)
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,e2,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and exec': "?exec ta e2 e2' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have "?exec ta (try e catch(C' V) e2) {V:Class C'=None; e2'} {V:Class C'=None; E'} h stk loc (Suc (Suc (length (compE2 e) + pc))) xcp h' (Suc (Suc (length (compE2 e) + pc''))) stk'' loc'' xcp''"
proof (cases "τmove1 P h {V:Class C'=None; e2'}")
case True with τ exec' show ?thesis by(auto intro: Try_τExecrI2 Try_τExectI2)
next
case False
with τ exec' obtain pc' stk' loc' xcp'
where e: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'"
and call: "call1 e2' = None ∨ no_call2 e2 pc ∨ pc' = pc ∧ stk' = stk ∧ loc' = loc ∧ xcp' = xcp" by auto
from e have "τExec_mover_a P t (try e catch(C' V) e2) h (stk, loc, Suc (Suc (length (compE2 e) + pc)), xcp) (stk', loc', Suc (Suc (length (compE2 e) + pc')), xcp')"
by(rule Try_τExecrI2)
moreover from e'
have "exec_move_a P t (try e catch(C' V) e2) h (stk', loc', Suc (Suc (length (compE2 e) + pc')), xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', Suc (Suc (length (compE2 e) + pc'')), xcp'')"
by(rule exec_move_TryI2)
moreover from τ' have "τmove2 (compP2 P) h stk' (try e catch(C' V) e2) (Suc (Suc (length (compE2 e) + pc'))) xcp' ⟹ False"
by(simp add: τmove2_iff)
moreover have "call1 {V:Class C'=None; e2'} = call1 e2'" by simp
moreover have "no_call2 e2 pc ⟹ no_call2 (try e catch(C' V) e2) (Suc (Suc (length (compE2 e) + pc)))"
by(auto simp add: no_call2_def)
ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps)
qed
moreover from bisim'
have "P, try e catch(C' V) e2, h' ⊢ ({V:Class C'=None; E'}, xs') ↔ (stk'', loc'', Suc (Suc (length (compE2 e) + pc'')), xcp'')"
by(rule bisim1_bisims1.bisim1TryCatch2)
ultimately show ?thesis using τ by auto blast+
next
case (Red1Block u)
note [simp] = ‹e2' = Val u› ‹ta = ε› ‹e' = Val u› ‹h' = h› ‹xs' = xs›
from bisim2 have s: "xcp = None" "xs = loc"
and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([u], loc, length (compE2 e2), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_mover_a P t (try e catch(C' V) e2) h (stk, loc, Suc (Suc (length (compE2 e) + pc)), xcp) ([u], loc, Suc (Suc (length (compE2 e) + length (compE2 e2))), None)"
by -(rule Try_τExecrI2)
moreover
have "P, try e catch(C' V) e2, h ⊢ (Val u, xs) ↔ ([u], xs, length (compE2 (try e catch(C' V) e2)), None)"
by(rule bisim1Val2) simp
moreover have "τmove1 P h {V:Class C'=None; Val u}" by(rule τmove1BlockRed)
ultimately show ?thesis using s by auto
next
case (Block1Throw a)
note [simp] = ‹e2' = Throw a› ‹ta = ε› ‹e' = Throw a› ‹h' = h› ‹xs' = xs›
have τ: "τmove1 P h {V:Class C'=None; e2'}" by(auto simp add: τmove1.simps τmoves1.simps)
from bisim2 have "xcp = ⌊a⌋ ∨ xcp = None" by(auto dest: bisim1_ThrowD)
thus ?thesis
proof
assume [simp]: "xcp = ⌊a⌋"
with bisim2
have "P, try e catch(C' V) e2, h ⊢ (Throw a, xs) ↔ (stk, loc, Suc (Suc (length (compE2 e) + pc)), xcp)"
by(auto intro: bisim1TryCatchThrow)
thus ?thesis using τ by(fastforce)
next
assume [simp]: "xcp = None"
with bisim2 obtain pc'
where "τExec_mover_a P t e2 h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim': "P, e2, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, pc', ⌊a⌋)" and [simp]: "xs = loc"
by(auto dest: bisim1_Throw_τExec_mover)
hence "τExec_mover_a P t (try e catch(C' V) e2) h (stk, loc, Suc (Suc (length (compE2 e) + pc)), None) ([Addr a], loc, Suc (Suc (length (compE2 e) + pc')), ⌊a⌋)"
by-(rule Try_τExecrI2)
moreover from bisim'
have "P, try e catch(C' V) e2, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, Suc (Suc (length (compE2 e) + pc')), ⌊a⌋)"
by(rule bisim1TryCatchThrow)
ultimately show ?thesis using τ by auto
qed
qed
next
case bisim1TryFail thus ?case by auto
next
case bisim1TryCatchThrow thus ?case by auto
next
case bisims1Nil thus ?case by(auto elim!: reds1.cases)
next
case (bisims1List1 E n e xs stk loc pc xcp es)
note IH1 = bisims1List1.IH(2)
note IH2 = bisims1List1.IH(4)
note bisim1 = ‹P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹⋀xs. P,es,h ⊢ (es, xs) [↔] ([], xs, 0, None)›
note bsok = ‹bsoks (E # es) n›
from ‹True,P,t ⊢1 ⟨e # es,(h, xs)⟩ [-ta→] ⟨es',(h', xs')⟩› show ?case
proof cases
case (List1Red1 E')
note [simp] = ‹es' = E' # es›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -ta→ ⟨E',(h', xs')⟩›
from red have τ: "τmoves1 P h (e # es) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
moreover from IH1[OF red] bsok
obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h' ⊢ (E', xs') ↔ (stk'', loc'', pc'', xcp'')"
and redo: "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
from bisim
have "P,E#es,h' ⊢ (E'#es, xs') [↔] (stk'', loc'', pc'', xcp'')"
by(rule bisim1_bisims1.bisims1List1)
moreover {
assume "no_call2 E pc"
hence "no_calls2 (E # es) pc ∨ pc = length (compE2 E)" by(auto simp add: no_call2_def no_calls2_def) }
moreover from red have "calls1 (e # es) = call1 e" by auto
ultimately show ?thesis using redo
apply(auto simp add: exec_move_def exec_moves_def simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_mover_τExec_movesr τExec_movet_τExec_movest intro!: bisim1_bisims1.bisims1List1 elim: τmoves2.cases)+
done
next
case (List1Red2 ES' v)
note [simp] = ‹es' = Val v # ES'› ‹e = Val v›
and red = ‹True,P,t ⊢1 ⟨es,(h, xs)⟩ [-ta→] ⟨ES',(h', xs')⟩›
from bisim1 have s: "xs = loc" "xcp = None"
and exec1: "τExec_mover_a P t E h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
by(auto dest: bisim1Val2D1)
hence "τExec_movesr_a P t (E # es) h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
by -(rule τExec_mover_τExec_movesr)
moreover from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,es,h' ⊢ (ES', xs') [↔] (stk'', loc'', pc'', xcp'')"
and exec': "?execs ta es es ES' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
have τ: "τmoves1 P h (Val v # es) = τmoves1 P h es" by(auto simp add: τmove1.simps τmoves1.simps)
have "?execs ta (E # es) (Val v # es) (Val v # ES') h [v] xs (length (compE2 E)) None h' (length (compE2 E) + pc'') (stk'' @ [v]) loc'' xcp''"
proof(cases "τmoves1 P h (Val v # es)")
case True with τ exec' show ?thesis
using append_τExec_movesr[of "[v]" "[E]" _ P t es h "[]" xs 0 None stk'' loc'' pc'' xcp'']
append_τExec_movest[of "[v]" "[E]" _ P t es h "[]" xs 0 None stk'' loc'' pc'' xcp''] by auto
next
case False with τ exec' obtain pc' stk' loc' xcp'
where e: "τExec_movesr_a P t es h ([], xs, 0, None) (stk', loc', pc', xcp')"
and e': "exec_moves_a P t es h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmoves2 (compP2 P) h stk' es pc' xcp'"
and call: "calls1 es = None ∨ no_calls2 es 0 ∨ pc' = 0 ∧ stk' = [] ∧ loc' = xs ∧ xcp' = None" by auto
from append_τExec_movesr[OF _ e, where vs="[v]" and es' = "[E]"]
have "τExec_movesr_a P t (E # es) h ([v], xs, length (compE2 E), None) (stk' @ [v], loc', length (compE2 E) + pc', xcp')" by simp
moreover from append_exec_moves[OF _ e', of "[v]" "[E]"]
have "exec_moves_a P t (E # es) h (stk' @ [v], loc', length (compE2 E) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 E) + pc'', xcp'')"
by simp
moreover from τ' e'
have "τmoves2 (compP2 P) h (stk' @ [v]) (E # es) (length (compE2 E) + pc') xcp' ⟹ False"
by(auto simp add: τmoves2_iff τinstr_stk_drop_exec_moves)
moreover have "calls1 (Val v # es) = calls1 es" by simp
moreover have "no_calls2 es 0 ⟹ no_calls2 (E # es) (length (compE2 E))"
by(auto simp add: no_calls2_def)
ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
qed
moreover from bisim'
have "P,E # es,h' ⊢ (Val v # ES', xs') [↔] (stk'' @ [v], loc'', length (compE2 E) + pc'', xcp'')"
by(rule bisim1_bisims1.bisims1List2)
moreover from bisim1 have "pc ≠ length (compE2 E) ⟶ no_calls2 (E # es) pc"
by(auto simp add: no_calls2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
ultimately show ?thesis using τ exec1 s
apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
apply(blast intro: τExec_movesr_trans|fastforce elim!: τExec_movesr_trans simp del: split_paired_Ex call1.simps calls1.simps)+
done
qed
next
case (bisims1List2 ES n es xs stk loc pc xcp e v)
note IH2 = bisims1List2.IH(2)
note bisim1 = ‹⋀xs. P,e,h ⊢ (e, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹P,ES,h ⊢ (es, xs) [↔] (stk, loc, pc, xcp)›
note bsok = ‹bsoks (e # ES) n›
from ‹True,P,t ⊢1 ⟨Val v # es,(h, xs)⟩ [-ta→] ⟨es',(h', xs')⟩› show ?case
proof cases
case (List1Red2 ES')
note [simp] = ‹es' = Val v # ES'›
and red = ‹True,P,t ⊢1 ⟨es,(h, xs)⟩ [-ta→] ⟨ES',(h', xs')⟩›
from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
where bisim': "P,ES,h' ⊢ (ES', xs') [↔] (stk'', loc'', pc'', xcp'')"
and exec': "?execs ta ES es ES' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
have τ: "τmoves1 P h (Val v # es) = τmoves1 P h es" by(auto simp add: τmove1.simps τmoves1.simps)
have "?execs ta (e # ES) (Val v # es) (Val v # ES') h (stk @ [v]) loc (length (compE2 e) + pc) xcp h' (length (compE2 e) + pc'') (stk'' @ [v]) loc'' xcp''"
proof(cases "τmoves1 P h (Val v # es)")
case True with τ exec' show ?thesis
using append_τExec_movesr[of "[v]" "[e]" _ P t ES h stk]
append_τExec_movest[of "[v]" "[e]" _ P t ES h stk] by auto
next
case False with τ exec' obtain pc' stk' loc' xcp'
where e: "τExec_movesr_a P t ES h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
and e': "exec_moves_a P t ES h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
and τ': "¬ τmoves2 (compP2 P) h stk' ES pc' xcp'"
and call: "calls1 es = None ∨ no_calls2 ES pc ∨ pc' = pc ∧ stk' = stk ∧ loc' = loc ∧ xcp' = xcp" by auto
from append_τExec_movesr[OF _ e, where vs="[v]" and es' = "[e]"]
have "τExec_movesr_a P t (e # ES) h (stk @ [v], loc, length (compE2 e) + pc, xcp) (stk' @ [v], loc', length (compE2 e) + pc', xcp')" by simp
moreover from append_exec_moves[OF _ e', of "[v]" "[e]"]
have "exec_moves_a P t (e # ES) h (stk' @ [v], loc', length (compE2 e) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 e) + pc'', xcp'')" by simp
moreover from τ' e'
have "τmoves2 (compP2 P) h (stk' @ [v]) (e # ES) (length (compE2 e) + pc') xcp' ⟹ False"
by(auto simp add: τmoves2_iff τinstr_stk_drop_exec_moves)
moreover have "calls1 (Val v # es) = calls1 es" by simp
moreover have "no_calls2 ES pc ⟹ no_calls2 (e # ES) (length (compE2 e) + pc)"
by(auto simp add: no_calls2_def)
ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps)
qed
moreover from bisim'
have "P,e # ES,h' ⊢ (Val v # ES', xs') [↔] (stk'' @ [v], loc'', length (compE2 e) + pc'', xcp'')"
by(rule bisim1_bisims1.bisims1List2)
ultimately show ?thesis using τ by auto blast+
qed auto
qed
end
context J1_JVM_conf_read begin
lemma exec_1_simulates_Red1_τ:
assumes wf: "wf_J1_prog P"
and Red1: "True,P,t ⊢1 ⟨(e, xs)/exs, h⟩ -ta→ ⟨(e', xs')/exs', h⟩"
and bisim: "bisim1_list1 t h (e, xs) exs xcp frs"
and τ: "τMove1 P h ((e, xs), exs)"
shows "∃xcp' frs'. (if sim12_size e' < sim12_size e then τExec_1_dr else τExec_1_dt) (compP2 P) t (xcp, h, frs) (xcp', h, frs') ∧ bisim1_list1 t h (e',xs') exs' xcp' frs'"
proof -
from wf have wt: "wf_jvm_prog⇘compTP P⇙ (compP2 P)" by(rule wt_compTP_compP2)
from Red1 show ?thesis
proof(cases)
case (red1Red TA)
note [simp] = ‹ta = extTA2J1 P TA› ‹exs' = exs›
and red = ‹True,P,t ⊢1 ⟨e,(h, xs)⟩ -TA→ ⟨e',(h, xs')⟩›
from τ red have τ': "τmove1 P h e" by(auto elim: red1_cases)
from bisim show ?thesis
proof(cases)
case (bl1_Normal stk loc C M pc FRS Ts T body D)
hence [simp]: "frs = (stk, loc, C, M, pc) # FRS"
and conf: "compTP P ⊢ t: (xcp, h, frs) √"
and sees: "P ⊢ C sees M: Ts→T = ⌊body⌋ in D"
and bisim: "P,blocks1 0 (Class D#Ts) body,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)"
and bisims: "list_all2 (bisim1_fr P h) exs FRS"
and lenxs: "max_vars e ≤ length xs"
by auto
from sees wf have "bsok (blocks1 0 (Class D # Ts) body) 0"
by(auto dest!: sees_wf_mdecl WT1_expr_locks simp add: wf_J1_mdecl_def wf_mdecl_def bsok_def)
from exec_instr_simulates_red1[OF wf bisim red this] τ' obtain pc' stk' loc' xcp'
where exec: "(if sim12_size e' < sim12_size e then τExec_mover_a else τExec_movet_a) P t body h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
and b': "P,blocks1 0 (Class D#Ts) body,h ⊢ (e', xs') ↔ (stk', loc', pc', xcp')"
by(auto split: if_split_asm simp del: blocks1.simps)
from exec sees have "(if sim12_size e' < sim12_size e then τExec_1r else τExec_1t) (compP2 P) t (xcp, h, frs) (xcp', h, (stk', loc', C, M, pc') # FRS)"
by(auto intro: τExec_mover_τExec_1r τExec_movet_τExec_1t)
from wt this conf have execd: "(if sim12_size e' < sim12_size e then τExec_1_dr else τExec_1_dt) (compP2 P) t (xcp, h, frs) (xcp', h, (stk', loc', C, M, pc') # FRS)"
by(auto intro: τExec_1r_τExec_1_dr τExec_1t_τExec_1_dt)
moreover from wt execd conf
have "compTP P ⊢ t: (xcp', h, (stk', loc', C, M, pc') # FRS) √"
by(auto intro: τExec_1_dr_preserves_correct_state τExec_1_dt_preserves_correct_state split: if_split_asm)
hence "bisim1_list1 t h (e', xs') exs xcp' ((stk', loc', C, M, pc') # FRS)"
using sees b'
proof
from red have "max_vars e' ≤ max_vars e" by(rule red1_max_vars)
with red1_preserves_len[OF red] lenxs
show "max_vars e' ≤ length xs'" by simp
qed fact
hence "bisim1_list1 t h (e',xs') exs' xcp' ((stk', loc', C, M, pc') # FRS)" by simp
ultimately show ?thesis by blast
qed(insert red, auto elim: red1_cases)
next
case (red1Call a' M' vs' U' Ts' T' body' D')
hence [simp]: "ta = ε"
and exs' [simp]: "exs' = (e, xs) # exs"
and e': "e' = blocks1 0 (Class D'#Ts') body'"
and xs': "xs' = Addr a' # vs' @ replicate (max_vars body') undefined_value"
and ha': "typeof_addr h a' = ⌊U'⌋"
and call: "call1 e = ⌊(a', M', vs')⌋" by auto
note sees' = ‹P ⊢ class_type_of U' sees M': Ts'→T' = ⌊body'⌋ in D'›
note lenvs'Ts' = ‹length vs' = length Ts'›
from ha' sees_method_decl_above[OF sees']
have conf: "P,h ⊢ Addr a' :≤ ty_of_htype U'" by(auto simp add: conf_def)
note wt = wt_compTP_compP2[OF wf]
from bisim show ?thesis
proof(cases)
case (bl1_Normal stk loc C M pc FRS Ts T body D)
hence [simp]: "frs = (stk, loc, C, M, pc) # FRS"
and conf: "compTP P ⊢ t: (xcp, h, frs) √"
and sees: "P ⊢ C sees M: Ts→T = ⌊body⌋ in D"
and bisim: "P,blocks1 0 (Class D#Ts) body,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)"
and bisims: "list_all2 (bisim1_fr P h) exs FRS"
and lenxs: "max_vars e ≤ length xs" by auto
from call bisim have [simp]: "xcp = None" by(cases xcp, auto dest: bisim1_call_xcpNone)
from bisim have b: "P,blocks1 0 (Class D#Ts) body,h ⊢ (e, xs) ↔ (stk, loc, pc, None)" by simp
from bisim have lenloc: "length xs = length loc" by(rule bisim1_length_xs)
from sees have sees'': "compP2 P ⊢ C sees M:Ts→T = ⌊(max_stack body, max_vars body, compE2 body @ [Return], compxE2 body 0 0)⌋ in D"
unfolding compP2_def compMb2_def Let_def by(auto dest: sees_method_compP)
from sees wf have "¬ contains_insync (blocks1 0 (Class D # Ts) body)"
by(auto dest!: sees_wf_mdecl WT1_expr_locks simp add: wf_J1_mdecl_def wf_mdecl_def contains_insync_conv)
with bisim1_call_τExec_move[OF b call, of 0 t] lenxs obtain pc' loc' stk'
where exec: "τExec_mover_a P t body h (stk, loc, pc, None) (rev vs' @ Addr a' # stk', loc', pc', None)"
and pc': "pc' < length (compE2 body)" and ins: "compE2 body ! pc' = Invoke M' (length vs')"
and bisim': "P,blocks1 0 (Class D#Ts) body,h ⊢ (e, xs) ↔ (rev vs' @ Addr a' # stk', loc', pc', None)"
by(auto simp add: blocks1_max_vars simp del: blocks1.simps)
let ?f = "(rev vs' @ Addr a' # stk', loc', C, M, pc')"
from exec sees
have exec1: "τExec_1r (compP2 P) t (None, h, (stk, loc, C, M, pc) # FRS) (None, h, ?f # FRS)"
by(rule τExec_mover_τExec_1r)
with wt have "τExec_1_dr (compP2 P) t (None, h, (stk, loc, C, M, pc) # FRS) (None, h, ?f # FRS)" using conf
by(simp)(rule τExec_1r_τExec_1_dr)
also with wt have conf': "compTP P ⊢ t: (None, h, ?f # FRS) √" using conf
by simp (rule τExec_1_dr_preserves_correct_state)
let ?f' = "([], Addr a' # vs' @ (replicate (max_vars body') undefined_value), D', M', 0)"
from pc' ins sees sees' ha'
have "(ε, None, h, ?f' # ?f # FRS) ∈ exec_instr (instrs_of (compP2 P) C M ! pc') (compP2 P) t h (rev vs' @ Addr a' # stk') loc' C M pc' FRS"
by(auto simp add: compP2_def compMb2_def nth_append split_beta)
hence "exec_1 (compP2 P) t (None, h, ?f # FRS) ε (None, h, ?f' # ?f # FRS)"
using exec sees by(simp add: exec_1_iff)
with conf' have execd: "compP2 P,t ⊢ Normal (None, h, ?f # FRS) -ε-jvmd→ Normal (None, h, ?f' # ?f # FRS)"
by(simp add: welltyped_commute[OF wt])
hence check: "check (compP2 P) (None, h, ?f # FRS)" by(rule jvmd_NormalE)
have "τmove2 (compP2 P) h (rev vs' @ Addr a' # stk') body pc' None" using pc' ins ha' sees'
by(auto simp add: τmove2_iff compP2_def dest: sees_method_fun)
with sees pc' ins have "τMove2 (compP2 P) (None, h, (rev vs' @ Addr a' # stk', loc', C, M, pc') # FRS)"
unfolding τMove2_compP2[OF sees] by(auto simp add: compP2_def compMb2_def)
with ‹exec_1 (compP2 P) t (None, h, ?f # FRS) ε (None, h, ?f' # ?f # FRS)› check
have "τExec_1_dt (compP2 P) t (None, h, ?f # FRS) (None, h, ?f' # ?f # FRS)" by fastforce
also from execd sees'' sees' ins ha' pc' have "compP2 P,h ⊢ vs' [:≤] Ts'"
by(auto simp add: check_def compP2_def split: if_split_asm elim!: jvmd_NormalE)
hence lenvs: "length vs' = length Ts'" by(rule list_all2_lengthD)
from wt execd conf' have "compTP P ⊢ t:(None, h, ?f' # ?f # FRS) √"
by(rule BV_correct_d_1)
hence "bisim1_list1 t h (blocks1 0 (Class D'#Ts') body', xs') ((e, xs) # exs) None (?f' # ?f # FRS)"
proof
from sees' show "P ⊢ D' sees M': Ts'→T' = ⌊body'⌋ in D'" by(rule sees_method_idemp)
show "P,blocks1 0 (Class D'#Ts') body',h ⊢ (blocks1 0 (Class D'#Ts') body', xs') ↔
([], Addr a' # vs' @ replicate (max_vars body') undefined_value, 0, None)"
unfolding xs' by(rule bisim1_refl)
show "max_vars (blocks1 0 (Class D' # Ts') body') ≤ length xs'"
unfolding xs' using lenvs by(simp add: blocks1_max_vars)
from lenxs have "(max_vars e) ≤ length xs" by simp
with sees bisim' call have "bisim1_fr P h (e, xs) (rev vs' @ Addr a' # stk', loc', C, M, pc')"
by(rule bisim1_fr.intros)
thus "list_all2 (bisim1_fr P h) ((e, xs) # exs)
((rev vs' @ Addr a' # stk', loc', C, M, pc') # FRS)"
using bisims by simp
qed
moreover have "ta_bisim wbisim1 ta ε" by simp
ultimately show ?thesis
unfolding ‹frs = (stk, loc, C, M, pc) # FRS› ‹xcp = None› e' exs'
by auto(blast intro: tranclp_into_rtranclp)
next
case bl1_finalVal
with call show ?thesis by simp
next
case bl1_finalThrow
with call show ?thesis by simp
qed
next
case (red1Return E)
note [simp] = ‹exs = (E, xs') # exs'› ‹ta = ε› ‹e' = inline_call e E›
note wt = wt_compTP_compP2[OF wf]
from bisim have bisim: "bisim1_list1 t h (e, xs) ((E, xs') # exs') xcp frs" by simp
thus ?thesis
proof cases
case (bl1_Normal stk loc C M pc FRS Ts T body D)
hence [simp]: "frs = (stk, loc, C, M, pc) # FRS"
and conf: "compTP P ⊢ t: (xcp, h, frs) √"
and sees: "P ⊢ C sees M: Ts→T = ⌊body⌋ in D"
and bisim: "P,blocks1 0 (Class D#Ts) body,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)"
and bisims: "list_all2 (bisim1_fr P h) ((E, xs') # exs') FRS"
and lenxs: "max_vars e ≤ length xs" by auto
from bisims obtain f FRS' where [simp]: "FRS = f # FRS'" by(fastforce simp add: list_all2_Cons1)
from bisims have "bisim1_fr P h (E, xs') f" by simp
then obtain C0 M0 Ts0 T0 body0 D0 stk0 loc0 pc0 a' M' vs'
where [simp]: "f = (stk0, loc0, C0, M0, pc0)"
and sees0: "P ⊢ C0 sees M0:Ts0→T0=⌊body0⌋ in D0"
and bisim0: "P,blocks1 0 (Class D0#Ts0) body0,h ⊢ (E, xs') ↔ (stk0, loc0, pc0, None)"
and lenxs0: "max_vars E ≤ length xs'"
and call0: "call1 E = ⌊(a', M', vs')⌋"
by cases auto
let ?ee = "inline_call e E"
from bisim0 call0 have pc0: "pc0 < length (compE2 (blocks1 0 (Class D0#Ts0) body0))"
by(rule bisim1_call_pcD)
hence pc0: "pc0 < length (compE2 body0)" by simp
with sees_method_compP[OF sees0, where f="λC M Ts T. compMb2"]
sees_method_compP[OF sees, where f="λC M Ts T. compMb2"] conf
obtain ST LT where Φ: "compTP P C0 M0 ! pc0 = ⌊(ST, LT)⌋"
and conff: "conf_f (compP (λC M Ts T. compMb2) P) h (ST, LT) (compE2 body0 @ [Return]) (stk0, loc0, C0, M0, pc0)"
and ins: "(compE2 body0 @ [Return]) ! pc0 = Invoke M (length Ts)"
by(simp add: correct_state_def)(fastforce simp add: compP2_def compMb2_def dest: sees_method_fun)
from bisim1_callD[OF bisim0 call0, of M "length Ts"] ins pc0
have [simp]: "M' = M" by simp
from ‹final e› show ?thesis
proof(cases)
fix v
assume [simp]: "e = Val v"
with bisim have [simp]: "xcp = None" by(auto dest: bisim_Val_loc_eq_xcp_None)
from bisim1Val2D1[OF bisim[unfolded ‹xcp = None› ‹e = Val v›]]
have "τExec_mover_a P t body h (stk, loc, pc, None) ([v], loc, length (compE2 body), None)"
and [simp]: "xs = loc" by(auto simp del: blocks1.simps)
with sees have "τExec_1r (compP2 P) t (None, h, (stk, loc, C, M, pc) # FRS) (None, h, ([v], loc, C, M, length (compE2 body)) # FRS)"
by-(rule τExec_mover_τExec_1r)
with conf wt have "τExec_1_dr (compP2 P) t (None, h, (stk, loc, C, M, pc) # FRS) (None, h, ([v], loc, C, M, length (compE2 body)) # FRS)"
by(simp)(rule τExec_1r_τExec_1_dr)
moreover with conf wt have conf': "compTP P ⊢ t:(None, h, ([v], loc, C, M, length (compE2 body)) # FRS) √"
by(simp)(rule τExec_1_dr_preserves_correct_state)
from sees sees0
have exec: "exec_1 (compP2 P) t (None, h, ([v], loc, C, M, length (compE2 body)) # FRS) ε (None, h, (v # drop (Suc (length Ts)) stk0, loc0, C0, M0, Suc pc0) # FRS')"
by(simp add: exec_1_iff compP2_def compMb2_def)
moreover with conf' wt have "compP2 P,t ⊢ Normal (None, h, ([v], loc, C, M, length (compE2 body)) # FRS) -ε-jvmd→ Normal (None, h, (v # drop (Suc (length Ts)) stk0, loc0, C0, M0, Suc pc0) # FRS')"
by(simp add: welltyped_commute)
hence "check (compP2 P) (None, h, ([v], loc, C, M, length (compE2 body)) # FRS)"
by(rule jvmd_NormalE)
moreover have "τMove2 (compP2 P) (None, h, ([v], loc, C, M, length (compE2 body)) # FRS)"
unfolding τMove2_compP2[OF sees] by(auto)
ultimately have "τExec_1_dt (compP2 P) t (None, h, (stk, loc, C, M, pc) # FRS) (None, h, (v # drop (Suc (length Ts)) stk0, loc0, C0, M0, Suc pc0) # FRS')"
by -(erule rtranclp_into_tranclp1,rule τexec_1_dI)
moreover from wt conf' exec
have "compTP P ⊢ t:(None, h, (v # drop (Suc (length Ts)) stk0, loc0, C0, M0, Suc pc0) # FRS') √"
by(rule BV_correct_1)
hence "bisim1_list1 t h (?ee, xs') exs' None ((v # drop (Suc (length Ts)) stk0, loc0, C0, M0, Suc pc0) # FRS')"
using sees0
proof
from bisim1_inline_call_Val[OF bisim0 call0, of "length Ts" v] ins pc0
show "P,blocks1 0 (Class D0#Ts0) body0,h ⊢ (?ee, xs') ↔ (v # drop (Suc (length Ts)) stk0, loc0, Suc pc0, None)"
by simp
from lenxs0 max_vars_inline_call[of e "E"]
show "max_vars (inline_call e E) ≤ length xs'" by simp
from bisims show "list_all2 (bisim1_fr P h) exs' FRS'" by simp
qed
ultimately show ?thesis
by -(rule exI conjI|assumption|simp)+
next
fix ad
assume [simp]: "e = Throw ad"
have "∃stk' pc'. τExec_mover_a P t body h (stk, loc, pc, xcp) (stk', loc, pc', ⌊ad⌋) ∧
P,blocks1 0 (Class D#Ts) body,h ⊢ (Throw ad, loc) ↔ (stk', loc, pc', ⌊ad⌋)"
proof(cases xcp)
case [simp]: None
from bisim1_Throw_τExec_mover[OF bisim[unfolded None ‹e = Throw ad›]] obtain pc'
where exec: "τExec_mover_a P t body h (stk, loc, pc, None) ([Addr ad], loc, pc', ⌊ad⌋)"
and bisim': "P,blocks1 0 (Class D#Ts) body,h ⊢ (Throw ad, xs) ↔ ([Addr ad], loc, pc', ⌊ad⌋)"
and [simp]: "xs = loc" by(auto simp del: blocks1.simps)
thus ?thesis by fastforce
next
case (Some a')
with bisim have "a' = ad" "xs = loc" by(auto dest: bisim1_ThrowD)
thus ?thesis using bisim Some by(auto)
qed
then obtain stk' pc' where exec: "τExec_mover_a P t body h (stk, loc, pc, xcp) (stk', loc, pc', ⌊ad⌋)"
and bisim': "P,blocks1 0 (Class D#Ts) body,h ⊢ (Throw ad, loc) ↔ (stk', loc, pc', ⌊ad⌋)" by blast
with sees have "τExec_1r (compP2 P) t (xcp, h, (stk, loc, C, M, pc) # FRS) (⌊ad⌋, h, (stk', loc, C, M, pc') # FRS)"
by-(rule τExec_mover_τExec_1r)
with conf wt have "τExec_1_dr (compP2 P) t (xcp, h, (stk, loc, C, M, pc) # FRS) (⌊ad⌋, h, (stk', loc, C, M, pc') # FRS)"
by(simp)(rule τExec_1r_τExec_1_dr)
moreover with conf wt have conf': "compTP P ⊢ t: (⌊ad⌋, h, (stk', loc, C, M, pc') # FRS) √"
by(simp)(rule τExec_1_dr_preserves_correct_state)
from bisim1_xcp_Some_not_caught[OF bisim', of "λC M Ts T. compMb2" 0 0] sees
have match: "match_ex_table (compP2 P) (cname_of h ad) pc' (ex_table_of (compP2 P) C M) = None"
by(simp add: compP2_def compMb2_def)
hence exec: "exec_1 (compP2 P) t (⌊ad⌋, h, (stk', loc, C, M, pc') # FRS) ε (⌊ad⌋, h, FRS)" by(simp add: exec_1_iff)
moreover
with conf' wt have "compP2 P,t ⊢ Normal (⌊ad⌋, h, (stk', loc, C, M, pc') # FRS) -ε-jvmd→ Normal (⌊ad⌋, h, FRS)"
by(simp add: welltyped_commute)
hence "check (compP2 P) (⌊ad⌋, h, (stk', loc, C, M, pc') # FRS)" by(rule jvmd_NormalE)
moreover from bisim' have "τMove2 (compP2 P) (⌊ad⌋, h, (stk', loc, C, M, pc') # FRS)"
unfolding τMove2_compP2[OF sees] by(auto dest: bisim1_pc_length_compE2)
ultimately have "τExec_1_dt (compP2 P) t (xcp, h, (stk, loc, C, M, pc) # FRS) (⌊ad⌋, h, FRS)"
by -(erule rtranclp_into_tranclp1,rule τexec_1_dI)
moreover from wt conf' exec
have "compTP P ⊢ t: (⌊ad⌋, h, (stk0, loc0, C0, M0, pc0) # FRS') √"
by(simp)(rule BV_correct_1)
hence "bisim1_list1 t h (?ee, xs') exs' ⌊ad⌋ ((stk0, loc0, C0, M0, pc0) # FRS')"
using sees0
proof
from bisim1_inline_call_Throw[OF bisim0 call0] ins pc0
show "P,blocks1 0 (Class D0#Ts0) body0,h ⊢ (?ee, xs') ↔ (stk0, loc0, pc0, ⌊ad⌋)" by simp
from lenxs0 max_vars_inline_call[of e E]
show "max_vars ?ee ≤ length xs'" by simp
from bisims Cons show "list_all2 (bisim1_fr P h) exs' FRS'" by simp
qed
moreover from call0 have "sim12_size (inline_call (Throw ad) E) > 0" by(cases E) simp_all
ultimately show ?thesis
by -(rule exI conjI|assumption|simp)+
qed
qed
qed
qed
lemma exec_1_simulates_Red1_not_τ:
assumes wf: "wf_J1_prog P"
and Red1: "True,P,t ⊢1 ⟨(e, xs)/exs, h⟩ -ta→ ⟨(e', xs')/exs', h'⟩"
and bisim: "bisim1_list1 t h (e, xs) exs xcp frs"
and τ: "¬ τMove1 P h ((e, xs), exs)"
shows "∃xcp' frs'. τExec_1_dr (compP2 P) t (xcp, h, frs) (xcp', h, frs') ∧
(∃ta' xcp'' frs''. exec_1_d (compP2 P) t (Normal (xcp', h, frs')) ta' (Normal (xcp'', h', frs'')) ∧
¬ τMove2 (compP2 P) (xcp', h, frs') ∧ ta_bisim wbisim1 ta ta' ∧
bisim1_list1 t h' (e',xs') exs' xcp'' frs'') ∧
(call1 e = None ∨
(case frs of Nil ⇒ False | (stk, loc, C, M, pc) # FRS ⇒ ∀M' n. instrs_of (compP2 P) C M ! pc ≠ Invoke M' n) ∨
xcp'= xcp ∧ frs' = frs)"
using Red1
proof(cases)
case (red1Red TA)
hence [simp]: "ta = extTA2J1 P TA" "exs' = exs"
and red: "True,P,t ⊢1 ⟨e,(h, xs)⟩ -TA→ ⟨e',(h', xs')⟩" by simp_all
from red have hext: "hext h h'" by(auto dest: red1_hext_incr)
from τ have τ': "¬ τmove1 P h e" by(auto intro: τmove1Block)
note wt = wt_compTP_compP2[OF wf]
from bisim show ?thesis
proof(cases)
case (bl1_Normal stk loc C M pc FRS Ts T body D)
hence [simp]: "frs = (stk, loc, C, M, pc) # FRS"
and conf: "compTP P ⊢ t: (xcp, h, frs) √"
and sees: "P ⊢ C sees M: Ts→T = ⌊body⌋ in D"
and bisim: "P,blocks1 0 (Class D#Ts) body,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp)"
and bisims: "list_all2 (bisim1_fr P h) exs FRS"
and lenxs: "max_vars e ≤ length xs" by auto
from sees wf have "bsok (blocks1 0 (Class D # Ts) body) 0"
by(auto dest!: sees_wf_mdecl WT1_expr_locks simp add: wf_J1_mdecl_def wf_mdecl_def bsok_def)
from exec_instr_simulates_red1[OF wf bisim red this] τ'
obtain pc' stk' loc' xcp' pc'' stk'' loc'' xcp''
where exec1: "τExec_mover_a P t body h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
and exec2: "exec_move_a P t body h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) TA) h' (stk'', loc'', pc'', xcp'')"
and τ2: "¬ τmove2 (compP2 P) h stk' body pc' xcp'"
and b': "P,blocks1 0 (Class D#Ts) body, h' ⊢ (e', xs') ↔ (stk'', loc'', pc'', xcp'')"
and call: "call1 e = None ∨ no_call2 (blocks1 0 (Class D # Ts) body) pc ∨ pc' = pc ∧ stk' = stk ∧ loc' = loc ∧ xcp' = xcp"
by(fastforce simp add: exec_move_def simp del: blocks1.simps)
from exec2 have pc'body: "pc' < length (compE2 body)" by(auto)
from exec1 sees have exec1': "τExec_1r (compP2 P) t (xcp, h, frs) (xcp', h, (stk', loc', C, M, pc') # FRS)"
by(auto intro: τExec_mover_τExec_1r)
with wt have execd: "τExec_1_dr (compP2 P) t (xcp, h, frs) (xcp', h, (stk', loc', C, M, pc') # FRS)"
using conf by(rule τExec_1r_τExec_1_dr)
moreover { fix a
assume [simp]: "xcp' = ⌊a⌋"
from exec2 sees_method_compP[OF sees, of "λC M Ts T. compMb2"] pc'body
have "match_ex_table (compP2 P) (cname_of h a) pc' (ex_table_of (compP2 P) C M) ≠ None"
by(auto simp add: exec_move_def compP2_def compMb2_def elim!: exec_meth.cases) }
note xt = this
with τ2 sees pc'body have τ2': "¬ τMove2 (compP2 P) (xcp', h, (stk', loc', C, M, pc') # FRS)"
unfolding τMove2_compP2[OF sees] by(auto simp add: compP2_def compMb2_def τmove2_iff)
moreover from exec2 sees
have exec2': "exec_1 (compP2 P) t (xcp', h, (stk', loc', C, M, pc') # FRS) (extTA2JVM (compP2 P) TA) (xcp'', h', (stk'', loc'', C, M, pc'') # FRS)"
by(rule exec_move_exec_1)
from wt execd conf have conf': "compTP P ⊢ t: (xcp', h, (stk', loc', C, M, pc') # FRS) √"
by(rule τExec_1_dr_preserves_correct_state)
with exec2' wt
have "exec_1_d (compP2 P) t (Normal (xcp', h, (stk', loc', C, M, pc') # FRS)) (extTA2JVM (compP2 P) TA) (Normal (xcp'', h', (stk'', loc'', C, M, pc'') # FRS))"
by(simp add: welltyped_commute)
moreover
from τ2 sees pc'body xt have τ2': "¬ τMove2 (compP2 P) (xcp', h, (stk', loc', C, M, pc') # FRS)"
unfolding τMove2_compP2[OF sees] by(auto simp add: compP2_def compMb2_def τmove2_iff)
moreover from wt conf' exec2'
have conf'': "compTP P ⊢ t: (xcp'', h', (stk'', loc'', C, M, pc'') # FRS) √" by(rule BV_correct_1)
hence "bisim1_list1 t h' (e', xs') exs xcp'' ((stk'', loc'', C, M, pc'') # FRS)" using sees b'
proof
from red1_preserves_len[OF red] red1_max_vars[OF red] lenxs
show "max_vars e' ≤ length xs'" by simp
from bisims show "list_all2 (bisim1_fr P h') exs FRS"
by(rule List.list_all2_mono)(rule bisim1_fr_hext_mono[OF _ hext])
qed
moreover from conf'' have "hconf h'" "preallocated h'" by(auto simp add: correct_state_def)
with wf red
have "ta_bisim wbisim1 ta (extTA2JVM (compP2 P) TA)"
by(auto intro: ta_bisim_red_extTA2J1_extTA2JVM)
moreover from call sees_method_compP[OF sees, of "λC M Ts T. compMb2"]
have "call1 e = None ∨ (case frs of [] ⇒ False | (stk, loc, C, M, pc) # FRS ⇒ ∀M' n. instrs_of (compP2 P) C M ! pc ≠ Invoke M' n) ∨ xcp' = xcp ∧ (stk', loc', C, M, pc') # FRS = frs"
by(auto simp add: no_call2_def compP2_def compMb2_def)
ultimately show ?thesis by -(rule exI conjI|assumption|simp)+
next
case bl1_finalVal
with red show ?thesis by auto
next
case bl1_finalThrow
with red show ?thesis by(auto elim: red1_cases)
qed
next
case red1Call
with τ have False
by(auto simp add: synthesized_call_def dest!: τmove1_not_call1[where P=P and h=h] dest: sees_method_fun)
thus ?thesis ..
next
case red1Return
with τ have False by auto
thus ?thesis ..
qed
end
end