Theory Correctness2
section ‹ Correctness of Stage 2 ›
theory Correctness2
imports "HOL-Library.Sublist" Compiler2 J1WellForm "../J/EConform"
begin
hide_const (open) Throw
subsection‹ Instruction sequences ›
text‹ How to select individual instructions and subsequences of
instructions from a program given the class, method and program
counter. ›
definition before :: "jvm_prog ⇒ cname ⇒ mname ⇒ nat ⇒ instr list ⇒ bool"
(‹(_,_,_,_/ ⊳ _)› [51,0,0,0,51] 50) where
"P,C,M,pc ⊳ is ⟷ prefix is (drop pc (instrs_of P C M))"
definition at :: "jvm_prog ⇒ cname ⇒ mname ⇒ nat ⇒ instr ⇒ bool"
(‹(_,_,_,_/ ▹ _)› [51,0,0,0,51] 50) where
"P,C,M,pc ▹ i ⟷ (∃is. drop pc (instrs_of P C M) = i#is)"
lemma [simp]: "P,C,M,pc ⊳ []"
by(simp add:before_def)
lemma [simp]: "P,C,M,pc ⊳ (i#is) = (P,C,M,pc ▹ i ∧ P,C,M,pc + 1 ⊳ is)"
by(fastforce simp add:before_def at_def prefix_def drop_Suc drop_tl)
declare drop_drop[simp del]
lemma [simp]: "P,C,M,pc ⊳ (is⇩1 @ is⇩2) = (P,C,M,pc ⊳ is⇩1 ∧ P,C,M,pc + size is⇩1 ⊳ is⇩2)"
by(subst add.commute)
(fastforce simp add:before_def prefix_def drop_drop[symmetric])
declare drop_drop[simp]
lemma [simp]: "P,C,M,pc ▹ i ⟹ instrs_of P C M ! pc = i"
by(clarsimp simp add:at_def strict_prefix_def nth_via_drop)
lemma beforeM:
"P ⊢ C sees M,b: Ts→T = body in D ⟹
compP⇩2 P,D,M,0 ⊳ compE⇩2 body @ [Return]"
by(drule sees_method_idemp) (simp add:before_def compMb⇩2_def)
text‹ This lemma executes a single instruction by rewriting: ›
lemma [simp]:
"P,C,M,pc ▹ instr ⟹
(P ⊢ (None, h, (vs,ls,C,M,pc,ics) # frs, sh) -jvm→ σ') =
((None, h, (vs,ls,C,M,pc,ics) # frs, sh) = σ' ∨
(∃σ. exec(P,(None, h, (vs,ls,C,M,pc,ics) # frs, sh)) = Some σ ∧ P ⊢ σ -jvm→ σ'))"
by(simp only: exec_all_def)
(blast intro: converse_rtranclE converse_rtrancl_into_rtrancl)
subsection‹ Exception tables ›
definition pcs :: "ex_table ⇒ nat set"
where
"pcs xt ≡ ⋃(f,t,C,h,d) ∈ set xt. {f ..< t}"
lemma pcs_subset:
shows "(⋀pc d. pcs(compxE⇩2 e pc d) ⊆ {pc..<pc+size(compE⇩2 e)})"
and "(⋀pc d. pcs(compxEs⇩2 es pc d) ⊆ {pc..<pc+size(compEs⇩2 es)})"
proof(induct e and es rule: compxE⇩2.induct compxEs⇩2.induct)
case Cast then show ?case by (fastforce simp:pcs_def)
next
case BinOp then show ?case by (fastforce simp:pcs_def split:bop.splits)
next
case LAss then show ?case by (fastforce simp: pcs_def)
next
case FAcc then show ?case by (fastforce simp: pcs_def)
next
case FAss then show ?case by (fastforce simp: pcs_def)
next
case SFAss then show ?case by (fastforce simp: pcs_def)
next
case Call then show ?case by (fastforce simp: pcs_def)
next
case SCall then show ?case by (fastforce simp: pcs_def)
next
case Seq then show ?case by (fastforce simp: pcs_def)
next
case Cond then show ?case by (fastforce simp: pcs_def)
next
case While then show ?case by (fastforce simp: pcs_def)
next
case throw then show ?case by (fastforce simp: pcs_def)
next
case TryCatch then show ?case by (fastforce simp: pcs_def)
next
case Cons_exp then show ?case by (fastforce simp: pcs_def)
qed (simp_all add:pcs_def)
lemma [simp]: "pcs [] = {}"
by(simp add:pcs_def)
lemma [simp]: "pcs (x#xt) = {fst x ..< fst(snd x)} ∪ pcs xt"
by(auto simp add: pcs_def)
lemma [simp]: "pcs(xt⇩1 @ xt⇩2) = pcs xt⇩1 ∪ pcs xt⇩2"
by(simp add:pcs_def)
lemma [simp]: "pc < pc⇩0 ∨ pc⇩0+size(compE⇩2 e) ≤ pc ⟹ pc ∉ pcs(compxE⇩2 e pc⇩0 d)"
using pcs_subset by fastforce
lemma [simp]: "pc < pc⇩0 ∨ pc⇩0+size(compEs⇩2 es) ≤ pc ⟹ pc ∉ pcs(compxEs⇩2 es pc⇩0 d)"
using pcs_subset by fastforce
lemma [simp]: "pc⇩1 + size(compE⇩2 e⇩1) ≤ pc⇩2 ⟹ pcs(compxE⇩2 e⇩1 pc⇩1 d⇩1) ∩ pcs(compxE⇩2 e⇩2 pc⇩2 d⇩2) = {}"
using pcs_subset by fastforce
lemma [simp]: "pc⇩1 + size(compE⇩2 e) ≤ pc⇩2 ⟹ pcs(compxE⇩2 e pc⇩1 d⇩1) ∩ pcs(compxEs⇩2 es pc⇩2 d⇩2) = {}"
using pcs_subset by fastforce
lemma [simp]:
"pc ∉ pcs xt⇩0 ⟹ match_ex_table P C pc (xt⇩0 @ xt⇩1) = match_ex_table P C pc xt⇩1"
by (induct xt⇩0) (auto simp: matches_ex_entry_def)
lemma [simp]: "⟦ x ∈ set xt; pc ∉ pcs xt ⟧ ⟹ ¬ matches_ex_entry P D pc x"
by(auto simp:matches_ex_entry_def pcs_def)
lemma [simp]:
assumes xe: "xe ∈ set(compxE⇩2 e pc d)" and outside: "pc' < pc ∨ pc+size(compE⇩2 e) ≤ pc'"
shows "¬ matches_ex_entry P C pc' xe"
proof
assume "matches_ex_entry P C pc' xe"
with xe have "pc' ∈ pcs(compxE⇩2 e pc d)"
by(force simp add:matches_ex_entry_def pcs_def)
with outside show False by simp
qed
lemma [simp]:
assumes xe: "xe ∈ set(compxEs⇩2 es pc d)" and outside: "pc' < pc ∨ pc+size(compEs⇩2 es) ≤ pc'"
shows "¬ matches_ex_entry P C pc' xe"
proof
assume "matches_ex_entry P C pc' xe"
with xe have "pc' ∈ pcs(compxEs⇩2 es pc d)"
by(force simp add:matches_ex_entry_def pcs_def)
with outside show False by simp
qed
lemma match_ex_table_app[simp]:
"∀xte ∈ set xt⇩1. ¬ matches_ex_entry P D pc xte ⟹
match_ex_table P D pc (xt⇩1 @ xt) = match_ex_table P D pc xt"
by(induct xt⇩1) simp_all
lemma [simp]:
"∀x ∈ set xtab. ¬ matches_ex_entry P C pc x ⟹
match_ex_table P C pc xtab = None"
using match_ex_table_app[where ?xt = "[]"] by fastforce
lemma match_ex_entry:
"matches_ex_entry P C pc (start, end, catch_type, handler) =
(start ≤ pc ∧ pc < end ∧ P ⊢ C ≼⇧* catch_type)"
by(simp add:matches_ex_entry_def)
definition caught :: "jvm_prog ⇒ pc ⇒ heap ⇒ addr ⇒ ex_table ⇒ bool" where
"caught P pc h a xt ⟷
(∃entry ∈ set xt. matches_ex_entry P (cname_of h a) pc entry)"
definition beforex :: "jvm_prog ⇒ cname ⇒ mname ⇒ ex_table ⇒ nat set ⇒ nat ⇒ bool"
(‹(2_,/_,/_ ⊳/ _ /'/ _,/_)› [51,0,0,0,0,51] 50) where
"P,C,M ⊳ xt / I,d ⟷
(∃xt⇩0 xt⇩1. ex_table_of P C M = xt⇩0 @ xt @ xt⇩1 ∧ pcs xt⇩0 ∩ I = {} ∧ pcs xt ⊆ I ∧
(∀pc ∈ I. ∀C pc' d'. match_ex_table P C pc xt⇩1 = ⌊(pc',d')⌋ ⟶ d' ≤ d))"
definition dummyx :: "jvm_prog ⇒ cname ⇒ mname ⇒ ex_table ⇒ nat set ⇒ nat ⇒ bool" (‹(2_,_,_ ▹/ _ '/_,_)› [51,0,0,0,0,51] 50) where
"P,C,M ▹ xt/I,d ⟷ P,C,M ⊳ xt/I,d"
abbreviation
"beforex⇩0 P C M d I xt xt⇩0 xt⇩1
≡ ex_table_of P C M = xt⇩0 @ xt @ xt⇩1 ∧ pcs xt⇩0 ∩ I = {}
∧ pcs xt ⊆ I ∧ (∀pc ∈ I. ∀C pc' d'. match_ex_table P C pc xt⇩1 = ⌊(pc',d')⌋ ⟶ d' ≤ d)"
lemma beforex_beforex⇩0_eq:
"P,C,M ⊳ xt / I,d ≡ ∃xt⇩0 xt⇩1. beforex⇩0 P C M d I xt xt⇩0 xt⇩1"
using beforex_def by auto
lemma beforexD1: "P,C,M ⊳ xt / I,d ⟹ pcs xt ⊆ I"
by(auto simp add:beforex_def)
lemma beforex_mono: "⟦ P,C,M ⊳ xt/I,d'; d' ≤ d ⟧ ⟹ P,C,M ⊳ xt/I,d"
by(fastforce simp:beforex_def)
lemma [simp]: "P,C,M ⊳ xt/I,d ⟹ P,C,M ⊳ xt/I,Suc d"
by(fastforce intro:beforex_mono)
lemma beforex_append[simp]:
"pcs xt⇩1 ∩ pcs xt⇩2 = {} ⟹
P,C,M ⊳ xt⇩1 @ xt⇩2/I,d =
(P,C,M ⊳ xt⇩1/I-pcs xt⇩2,d ∧ P,C,M ⊳ xt⇩2/I-pcs xt⇩1,d ∧ P,C,M ▹ xt⇩1@xt⇩2/I,d)"
(is "?Q ⟹ ?P = (?P1 ∧ ?P2 ∧ ?P3)" is "?Q ⟹ ?P = ?P123")
proof -
assume pcs: ?Q
show ?thesis proof(rule iffI)
assume "?P123" then show ?P by(simp add:dummyx_def)
next
assume hyp: ?P
let ?xt = "xt⇩1 @ xt⇩2"
let ?beforex = "beforex⇩0 P C M d"
obtain xt⇩0 xt⇩1' where beforex: "?beforex I ?xt xt⇩0 xt⇩1'"
using hyp by(clarsimp simp: beforex_def)
have "∃xt⇩0 xt⇩1'. ?beforex (I - pcs xt⇩2) xt⇩1 xt⇩0 xt⇩1'"
using pcs beforex by(rule_tac x=xt⇩0 in exI) auto
moreover have "∃xt⇩0 xt⇩1'. ?beforex (I - pcs xt⇩1) xt⇩2 xt⇩0 xt⇩1'"
using pcs beforex by(rule_tac x="xt⇩0@xt⇩1" in exI) auto
moreover have ?P3 using hyp by(simp add: dummyx_def)
ultimately show ?P123 by (simp add: beforex_def)
qed
qed
lemma beforex_appendD1:
assumes bx: "P,C,M ⊳ xt⇩1 @ xt⇩2 @ [(f,t,D,h,d)] / I,d"
and pcs: "pcs xt⇩1 ⊆ J" and JI: "J ⊆ I" and Jpcs: "J ∩ pcs xt⇩2 = {}"
shows "P,C,M ⊳ xt⇩1 / J,d"
proof -
let ?beforex = "beforex⇩0 P C M d"
obtain xt⇩0 xt⇩1' where bx': "?beforex I (xt⇩1 @ xt⇩2 @ [(f,t,D,h,d)]) xt⇩0 xt⇩1'"
using bx by(clarsimp simp:beforex_def)
let ?xt0 = xt⇩0 and ?xt1 = "xt⇩2 @ (f, t, D, h, d) # xt⇩1'"
have "pcs xt⇩0 ∩ J = {}" using bx' JI by blast
moreover {
fix pc C pc' d' assume pcJ: "pc∈J"
then have "pc ∉ pcs xt⇩2" using bx' Jpcs by blast
then have "match_ex_table P C pc (xt⇩2 @ (f, t, D, h, d) # xt⇩1')
= ⌊(pc', d')⌋ ⟶ d' ≤ d"
using bx' JI pcJ by (auto split:if_split_asm)
}
ultimately have "?beforex J xt⇩1 ?xt0 ?xt1" using bx' pcs by simp
then show ?thesis using beforex_def by blast
qed
lemma beforex_appendD2:
assumes bx: "P,C,M ⊳ xt⇩1 @ xt⇩2 @ [(f,t,D,h,d)] / I,d"
and pcs: "pcs xt⇩2 ⊆ J" and JI: "J ⊆ I" and Jpcs: "J ∩ pcs xt⇩1 = {}"
shows "P,C,M ⊳ xt⇩2 / J,d"
proof -
let ?beforex = "beforex⇩0 P C M d"
obtain xt⇩0 xt⇩1' where bx': "?beforex I (xt⇩1 @ xt⇩2 @ [(f,t,D,h,d)]) xt⇩0 xt⇩1'"
using bx by(clarsimp simp:beforex_def)
then have "∃xt⇩1''. beforex⇩0 P C M d J xt⇩2 (xt⇩0 @ xt⇩1) xt⇩1''"
using assms by fastforce
then show ?thesis using beforex_def by blast
qed
lemma beforexM:
"P ⊢ C sees M,b: Ts→T = body in D ⟹ compP⇩2 P,D,M ⊳ compxE⇩2 body 0 0/{..<size(compE⇩2 body)},0"
proof -
assume cM: "P ⊢ C sees M,b: Ts→T = body in D"
let ?xt0 = "[]"
have "∃xt1. beforex⇩0 (compP⇩2 P) D M 0 ({..<size(compE⇩2 body)}) (compxE⇩2 body 0 0) ?xt0 xt1"
using sees_method_compP[where f = compMb⇩2, OF sees_method_idemp[OF cM]]
pcs_subset by(fastforce simp add: compP⇩2_def compMb⇩2_def)
then show ?thesis using beforex_def by blast
qed
lemma match_ex_table_SomeD2:
assumes met: "match_ex_table P D pc (ex_table_of P C M) = ⌊(pc',d')⌋"
and bx: "P,C,M ⊳ xt/I,d"
and nmet: "∀x ∈ set xt. ¬ matches_ex_entry P D pc x" and pcI: "pc ∈ I"
shows "d' ≤ d"
proof -
obtain xt⇩0 xt⇩1 where bx': "beforex⇩0 P C M d I xt xt⇩0 xt⇩1"
using bx by(clarsimp simp:beforex_def)
then have "pc ∉ pcs xt⇩0" using pcI by blast
then show ?thesis using bx' met nmet pcI by simp
qed
lemma match_ex_table_SomeD1:
"⟦ match_ex_table P D pc (ex_table_of P C M) = ⌊(pc',d')⌋;
P,C,M ⊳ xt / I,d; pc ∈ I; pc ∉ pcs xt ⟧ ⟹ d' ≤ d"
by(auto elim: match_ex_table_SomeD2)
subsection‹ The correctness proof ›
declare nat_add_distrib[simp] caught_def[simp]
declare fun_upd_apply[simp del]
definition
handle :: "jvm_prog ⇒ cname ⇒ mname ⇒ addr ⇒ heap ⇒ val list ⇒ val list ⇒ nat ⇒ init_call_status ⇒ frame list ⇒ sheap
⇒ jvm_state" where
"handle P C M a h vs ls pc ics frs sh = find_handler P a h ((vs,ls,C,M,pc,ics) # frs) sh"
lemma aux_isin[simp]: "⟦ B ⊆ A; a ∈ B ⟧ ⟹ a ∈ A"
by blast
lemma handle_frs_tl_neq:
"ics_of f ≠ No_ics
⟹ (xp, h, f#frs, sh) ≠ handle P C M xa h' vs l pc ics frs sh'"
by(simp add: handle_def find_handler_frs_tl_neq del: find_handler.simps)
subsubsection "Correctness proof inductive hypothesis"
fun calling_to_called :: "frame ⇒ frame" where
"calling_to_called (stk,loc,D,M,pc,ics) = (stk,loc,D,M,pc,case ics of Calling C Cs ⇒ Called (C#Cs))"
fun calling_to_scalled :: "frame ⇒ frame" where
"calling_to_scalled (stk,loc,D,M,pc,ics) = (stk,loc,D,M,pc,case ics of Calling C Cs ⇒ Called Cs)"
fun calling_to_calling :: "frame ⇒ cname ⇒ frame" where
"calling_to_calling (stk,loc,D,M,pc,ics) C' = (stk,loc,D,M,pc,case ics of Calling C Cs ⇒ Calling C' (C#Cs))"
fun calling_to_throwing :: "frame ⇒ addr ⇒ frame" where
"calling_to_throwing (stk,loc,D,M,pc,ics) a = (stk,loc,D,M,pc,case ics of Calling C Cs ⇒ Throwing (C#Cs) a)"
fun calling_to_sthrowing :: "frame ⇒ addr ⇒ frame" where
"calling_to_sthrowing (stk,loc,D,M,pc,ics) a = (stk,loc,D,M,pc,case ics of Calling C Cs ⇒ Throwing Cs a)"
fun Jcc_cond :: "J⇩1_prog ⇒ ty list ⇒ cname ⇒ mname ⇒ val list ⇒ pc ⇒ init_call_status
⇒ nat set ⇒ heap ⇒ sheap ⇒ expr⇩1 ⇒ bool" where
"Jcc_cond P E C M vs pc ics I h sh (INIT C⇩0 (Cs,b) ← e')
= ((∃T. P,E,h,sh ⊢⇩1 INIT C⇩0 (Cs,b) ← e' : T) ∧ unit = e' ∧ ics = No_ics)" |
"Jcc_cond P E C M vs pc ics I h sh (RI(C',e⇩0);Cs ← e')
= (((e⇩0 = C'∙⇩sclinit([]) ∧ (∃T. P,E,h,sh ⊢⇩1 RI(C',e⇩0);Cs ← e':T))
∨ ((∃a. e⇩0 = Throw a) ∧ (∀C ∈ set(C'#Cs). is_class P C)))
∧ unit = e' ∧ ics = No_ics)" |
"Jcc_cond P E C M vs pc ics I h sh (C'∙⇩sM'(es))
= (let e = (C'∙⇩sM'(es))
in if M' = clinit ∧ es = [] then (∃T. P,E,h,sh ⊢⇩1 e:T) ∧ (∃Cs. ics = Called Cs)
else (compP⇩2 P,C,M,pc ⊳ compE⇩2 e ∧ compP⇩2 P,C,M ⊳ compxE⇩2 e pc (size vs)/I,size vs
∧ {pc..<pc+size(compE⇩2 e)} ⊆ I ∧ ¬sub_RI e ∧ ics = No_ics)
)" |
"Jcc_cond P E C M vs pc ics I h sh e
= (compP⇩2 P,C,M,pc ⊳ compE⇩2 e ∧ compP⇩2 P,C,M ⊳ compxE⇩2 e pc (size vs)/I,size vs
∧ {pc..<pc+size(compE⇩2 e)} ⊆ I ∧ ¬sub_RI e ∧ ics = No_ics)"
fun Jcc_frames :: "jvm_prog ⇒ cname ⇒ mname ⇒ val list ⇒ val list ⇒ pc ⇒ init_call_status
⇒ frame list ⇒ expr⇩1 ⇒ frame list" where
"Jcc_frames P C M vs ls pc ics frs (INIT C⇩0 (C'#Cs,b) ← e')
= (case b of False ⇒ (vs,ls,C,M,pc,Calling C' Cs) # frs
| True ⇒ (vs,ls,C,M,pc,Called (C'#Cs)) # frs
)" |
"Jcc_frames P C M vs ls pc ics frs (INIT C⇩0 (Nil,b) ← e')
= (vs,ls,C,M,pc,Called [])#frs" |
"Jcc_frames P C M vs ls pc ics frs (RI(C',e⇩0);Cs ← e')
= (case e⇩0 of Throw a ⇒ (vs,ls,C,M,pc,Throwing (C'#Cs) a) # frs
| _ ⇒ (vs,ls,C,M,pc,Called (C'#Cs)) # frs )" |
"Jcc_frames P C M vs ls pc ics frs (C'∙⇩sM'(es))
= (if M' = clinit ∧ es = []
then create_init_frame P C'#(vs,ls,C,M,pc,ics)#frs
else (vs,ls,C,M,pc,ics)#frs
)" |
"Jcc_frames P C M vs ls pc ics frs e
= (vs,ls,C,M,pc,ics)#frs"
fun Jcc_rhs :: "J⇩1_prog ⇒ ty list ⇒ cname ⇒ mname ⇒ val list ⇒ val list ⇒ pc ⇒ init_call_status
⇒ frame list ⇒ heap ⇒ val list ⇒ sheap ⇒ val ⇒ expr⇩1 ⇒ jvm_state" where
"Jcc_rhs P E C M vs ls pc ics frs h' ls' sh' v (INIT C⇩0 (Cs,b) ← e')
= (None,h',(vs,ls,C,M,pc,Called [])#frs,sh')" |
"Jcc_rhs P E C M vs ls pc ics frs h' ls' sh' v (RI(C',e⇩0);Cs ← e')
= (None,h',(vs,ls,C,M,pc,Called [])#frs,sh')" |
"Jcc_rhs P E C M vs ls pc ics frs h' ls' sh' v (C'∙⇩sM'(es))
= (let e = (C'∙⇩sM'(es))
in if M' = clinit ∧ es = []
then (None,h',(vs,ls,C,M,pc,ics)#frs,sh'(C'↦(fst(the(sh' C')),Done)))
else (None,h',(v#vs,ls',C,M,pc+size(compE⇩2 e),ics)#frs,sh')
)" |
"Jcc_rhs P E C M vs ls pc ics frs h' ls' sh' v e
= (None,h',(v#vs,ls',C,M,pc+size(compE⇩2 e),ics)#frs,sh')"
fun Jcc_err :: "jvm_prog ⇒ cname ⇒ mname ⇒ heap ⇒ val list ⇒ val list ⇒ pc ⇒ init_call_status
⇒ frame list ⇒ sheap ⇒ nat set ⇒ heap ⇒ val list ⇒ sheap ⇒ addr ⇒ expr⇩1
⇒ bool" where
"Jcc_err P C M h vs ls pc ics frs sh I h' ls' sh' xa (INIT C⇩0 (Cs,b) ← e')
= (∃vs'. P ⊢ (None,h,Jcc_frames P C M vs ls pc ics frs (INIT C⇩0 (Cs,b) ← e'),sh)
-jvm→ handle P C M xa h' (vs'@vs) ls pc ics frs sh')" |
"Jcc_err P C M h vs ls pc ics frs sh I h' ls' sh' xa (RI(C',e⇩0);Cs ← e')
= (∃vs'. P ⊢ (None,h,Jcc_frames P C M vs ls pc ics frs (RI(C',e⇩0);Cs ← e'),sh)
-jvm→ handle P C M xa h' (vs'@vs) ls pc ics frs sh')" |
"Jcc_err P C M h vs ls pc ics frs sh I h' ls' sh' xa (C'∙⇩sM'(es))
= (let e = (C'∙⇩sM'(es))
in if M' = clinit ∧ es = []
then case ics of
Called Cs ⇒ P ⊢ (None,h,Jcc_frames P C M vs ls pc ics frs e,sh)
-jvm→ (None,h',(vs,ls,C,M,pc,Throwing Cs xa)#frs,(sh'(C' ↦ (fst(the(sh' C')),Error))))
else (∃pc⇩1. pc ≤ pc⇩1 ∧ pc⇩1 < pc + size(compE⇩2 e) ∧
¬ caught P pc⇩1 h' xa (compxE⇩2 e pc (size vs)) ∧
(∃vs'. P ⊢ (None,h,Jcc_frames P C M vs ls pc ics frs e,sh)
-jvm→ handle P C M xa h' (vs'@vs) ls' pc⇩1 ics frs sh'))
)" |
"Jcc_err P C M h vs ls pc ics frs sh I h' ls' sh' xa e
= (∃pc⇩1. pc ≤ pc⇩1 ∧ pc⇩1 < pc + size(compE⇩2 e) ∧
¬ caught P pc⇩1 h' xa (compxE⇩2 e pc (size vs)) ∧
(∃vs'. P ⊢ (None,h,Jcc_frames P C M vs ls pc ics frs e,sh)
-jvm→ handle P C M xa h' (vs'@vs) ls' pc⇩1 ics frs sh'))"
fun Jcc_pieces :: "J⇩1_prog ⇒ ty list ⇒ cname ⇒ mname ⇒ heap ⇒ val list ⇒ val list ⇒ pc ⇒ init_call_status
⇒ frame list ⇒ sheap ⇒ nat set ⇒ heap ⇒ val list ⇒ sheap ⇒ val ⇒ addr ⇒ expr⇩1
⇒ bool × frame list × jvm_state × bool" where
"Jcc_pieces P E C M h vs ls pc ics frs sh I h' ls' sh' v xa e
= (Jcc_cond P E C M vs pc ics I h sh e, Jcc_frames (compP⇩2 P) C M vs ls pc ics frs e,
Jcc_rhs P E C M vs ls pc ics frs h' ls' sh' v e,
Jcc_err (compP⇩2 P) C M h vs ls pc ics frs sh I h' ls' sh' xa e)"
lemma nsub_RI_Jcc_pieces:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and nsub: "¬sub_RI e"
shows "Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa e
= (let cond = P,C,M,pc ⊳ compE⇩2 e ∧ P,C,M ⊳ compxE⇩2 e pc (size vs)/I,size vs
∧ {pc..<pc+size(compE⇩2 e)} ⊆ I ∧ ics = No_ics;
frs' = (vs,ls,C,M,pc,ics)#frs;
rhs = (None,h',(v#vs,ls',C,M,pc+size(compE⇩2 e),ics)#frs,sh');
err = (∃pc⇩1. pc ≤ pc⇩1 ∧ pc⇩1 < pc + size(compE⇩2 e) ∧
¬ caught P pc⇩1 h' xa (compxE⇩2 e pc (size vs)) ∧
(∃vs'. P ⊢ (None,h,frs',sh) -jvm→ handle P C M xa h' (vs'@vs) ls' pc⇩1 ics frs sh'))
in (cond, frs',rhs, err)
)"
proof -
have NC: "∀C'. e ≠ C'∙⇩sclinit([])" using assms(2) proof(cases e) qed(simp_all)
then show ?thesis using assms
proof(cases e)
case (SCall C M es)
then have "M ≠ clinit" using nsub by simp
then show ?thesis using SCall nsub proof(cases es) qed(simp_all)
qed(simp_all)
qed
lemma Jcc_pieces_Cast:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (Cast C' e)
= (True, frs⇩0, (xp',h',(v#vs',ls',C⇩0,M',pc',ics')#frs',sh'), err)"
shows "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v' xa e
= (True, frs⇩0, (xp',h',(v'#vs',ls',C⇩0,M',pc' - 1,ics')#frs',sh'),
(∃pc⇩1. pc ≤ pc⇩1 ∧ pc⇩1 < pc + size(compE⇩2 e) ∧
¬ caught P pc⇩1 h⇩1 xa (compxE⇩2 e pc (size vs)) ∧
(∃vs'. P ⊢ (None,h⇩0,frs⇩0,sh⇩0) -jvm→ handle P C M xa h⇩1 (vs'@vs) ls⇩1 pc⇩1 ics frs sh⇩1)))"
proof -
have pc: "{pc..<pc + length (compE⇩2 e)} ⊆ I" using assms by clarsimp
show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] pc by clarsimp
qed
lemma Jcc_pieces_BinOp1:
assumes
"Jcc_pieces P E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e «bop» e')
= (True, frs⇩0, (xp',h',(v#vs',ls',C⇩0,M',pc',ics')#frs',sh'), err)"
shows "∃err. Jcc_pieces P E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0
(I - pcs (compxE⇩2 e' (pc + length (compE⇩2 e)) (Suc (length vs')))) h⇩1 ls⇩1 sh⇩1 v' xa e
= (True, frs⇩0, (xp',h⇩1,(v'#vs',ls⇩1,C⇩0,M',pc' - size (compE⇩2 e') - 1,ics')#frs',sh⇩1), err)"
proof -
have bef: "compP compMb⇩2 P,C⇩0,M' ⊳ compxE⇩2 e pc (length vs)
/ I - pcs (compxE⇩2 e' (pc + length (compE⇩2 e)) (Suc (length vs'))),length vs"
using assms by clarsimp
have vs: "vs = vs'" using assms by simp
show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] bef vs by clarsimp
qed
lemma Jcc_pieces_BinOp2:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e «bop» e')
= (True, frs⇩0, (xp',h',(v#vs',ls',C⇩0,M',pc',ics')#frs',sh'), err)"
shows "∃err. Jcc_pieces P⇩1 E C M h⇩1 (v⇩1#vs) ls⇩1 (pc + size (compE⇩2 e)) ics frs sh⇩1
(I - pcs (compxE⇩2 e pc (length vs'))) h⇩2 ls⇩2 sh⇩2 v' xa e'
= (True, (v⇩1#vs,ls⇩1,C,M,pc + size (compE⇩2 e),ics)#frs,
(xp',h',(v'#v⇩1#vs',ls',C⇩0,M',pc' - 1,ics')#frs',sh'),
(∃pc⇩1. pc + size (compE⇩2 e) ≤ pc⇩1 ∧ pc⇩1 < pc + size (compE⇩2 e) + length (compE⇩2 e') ∧
¬ caught P pc⇩1 h⇩2 xa (compxE⇩2 e' (pc + size (compE⇩2 e)) (Suc (length vs))) ∧
(∃vs'. P ⊢ (None,h⇩1,(v⇩1#vs,ls⇩1,C,M,pc + size (compE⇩2 e),ics)#frs,sh⇩1)
-jvm→ handle P C M xa h⇩2 (vs'@v⇩1#vs) ls⇩2 pc⇩1 ics frs sh⇩2)))"
proof -
have bef: "compP compMb⇩2 P⇩1,C⇩0,M' ⊳ compxE⇩2 e pc (length vs)
/ I - pcs (compxE⇩2 e' (pc + length (compE⇩2 e)) (Suc (length vs'))),length vs"
using assms by clarsimp
have vs: "vs = vs'" using assms by simp
show ?thesis using assms nsub_RI_Jcc_pieces[where e=e'] bef vs by clarsimp
qed
lemma Jcc_pieces_FAcc:
assumes
"Jcc_pieces P E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (e∙F{D})
= (True, frs⇩0, (xp',h',(v#vs',ls',C⇩0,M',pc',ics')#frs',sh'), err)"
shows "∃err. Jcc_pieces P E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v' xa e
= (True, frs⇩0, (xp',h',(v'#vs',ls',C⇩0,M',pc' - 1,ics')#frs',sh'), err)"
proof -
have pc: "{pc..<pc + length (compE⇩2 e)} ⊆ I" using assms by clarsimp
then show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] by clarsimp
qed
lemma Jcc_pieces_LAss:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (i:=e)
= (True, frs⇩0, (xp',h',(v#vs',ls',C⇩0,M',pc',ics')#frs',sh'), err)"
shows "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v' xa e
= (True, frs⇩0, (xp',h',(v'#vs',ls',C⇩0,M',pc' - 2,ics')#frs',sh'),
(∃pc⇩1. pc ≤ pc⇩1 ∧ pc⇩1 < pc + size(compE⇩2 e) ∧
¬ caught P pc⇩1 h⇩1 xa (compxE⇩2 e pc (size vs)) ∧
(∃vs'. P ⊢ (None,h⇩0,frs⇩0,sh⇩0) -jvm→ handle P C M xa h⇩1 (vs'@vs) ls⇩1 pc⇩1 ics frs sh⇩1)))"
proof -
have pc: "{pc..<pc + length (compE⇩2 e)} ⊆ I" using assms by clarsimp
show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] pc by clarsimp
qed
lemma Jcc_pieces_FAss1:
assumes
"Jcc_pieces P E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e∙F{D}:=e')
= (True, frs⇩0, (xp',h',(v#vs',ls',C⇩0,M',pc',ics')#frs',sh'), err)"
shows "∃err. Jcc_pieces P E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0
(I - pcs (compxE⇩2 e' (pc + length (compE⇩2 e)) (Suc (length vs')))) h⇩1 ls⇩1 sh⇩1 v' xa e
= (True, frs⇩0, (xp',h⇩1,(v'#vs',ls⇩1,C⇩0,M',pc' - size (compE⇩2 e') - 2,ics')#frs',sh⇩1), err)"
proof -
show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] by clarsimp
qed
lemma Jcc_pieces_FAss2:
assumes
"Jcc_pieces P E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e∙F{D}:=e')
= (True, frs⇩0, (xp',h',(v#vs',ls',C⇩0,M',pc',ics')#frs',sh'), err)"
shows "Jcc_pieces P E C M h⇩1 (v⇩1#vs) ls⇩1 (pc + size (compE⇩2 e)) ics frs sh⇩1
(I - pcs (compxE⇩2 e pc (length vs'))) h⇩2 ls⇩2 sh⇩2 v' xa e'
= (True, (v⇩1#vs,ls⇩1,C,M,pc + size (compE⇩2 e),ics)#frs,
(xp',h',(v'#v⇩1#vs',ls',C⇩0,M',pc' - 2,ics')#frs',sh'),
(∃pc⇩1. (pc + size (compE⇩2 e)) ≤ pc⇩1 ∧ pc⇩1 < pc + size (compE⇩2 e) + size(compE⇩2 e') ∧
¬ caught (compP⇩2 P) pc⇩1 h⇩2 xa (compxE⇩2 e' (pc + size (compE⇩2 e)) (size (v⇩1#vs))) ∧
(∃vs'. (compP⇩2 P) ⊢ (None,h⇩1,(v⇩1#vs,ls⇩1,C,M,pc + size (compE⇩2 e),ics)#frs,sh⇩1)
-jvm→ handle (compP⇩2 P) C M xa h⇩2 (vs'@v⇩1#vs) ls⇩2 pc⇩1 ics frs sh⇩2)))"
proof -
show ?thesis using assms nsub_RI_Jcc_pieces[where e=e'] by clarsimp
qed
lemma Jcc_pieces_SFAss:
assumes
"Jcc_pieces P E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h' ls' sh' v xa (C'∙⇩sF{D}:=e)
= (True, frs⇩0, (xp',h',(v#vs',ls',C⇩0,M',pc',ics')#frs',sh'), err)"
shows "∃err. Jcc_pieces P E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v' xa e
= (True, frs⇩0, (xp',h⇩1,(v'#vs',ls⇩1,C⇩0,M',pc' - 2,ics')#frs',sh⇩1), err)"
proof -
have pc: "{pc..<pc + length (compE⇩2 e)} ⊆ I" using assms by clarsimp
show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] pc by clarsimp
qed
lemma Jcc_pieces_Call1:
assumes
"Jcc_pieces P E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩3 ls⇩3 sh⇩3 v xa (e∙M⇩0(es))
= (True, frs⇩0, (xp',h',(v#vs',ls',C',M',pc',ics')#frs',sh'), err)"
shows "∃err. Jcc_pieces P E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0
(I - pcs (compxEs⇩2 es (pc + length (compE⇩2 e)) (Suc (length vs')))) h⇩1 ls⇩1 sh⇩1 v' xa e
= (True, frs⇩0,
(xp',h⇩1,(v'#vs',ls⇩1,C',M',pc' - size (compEs⇩2 es) - 1,ics')#frs',sh⇩1), err)"
proof -
show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] by clarsimp
qed
lemma Jcc_pieces_clinit:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and cond: "Jcc_cond P⇩1 E C M vs pc ics I h sh (C1∙⇩sclinit([]))"
shows "Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (C1∙⇩sclinit([]))
= (True, create_init_frame P C1 # (vs,ls,C,M,pc,ics)#frs,
(None, h', (vs,ls,C,M,pc,ics)#frs, sh'(C1↦(fst(the(sh' C1)),Done))),
P ⊢ (None,h,create_init_frame P C1 # (vs,ls,C,M,pc,ics)#frs,sh) -jvm→
(case ics of Called Cs ⇒ (None,h',(vs,ls,C,M,pc,Throwing Cs xa)#frs,(sh'(C1 ↦ (fst(the(sh' C1)),Error))))))"
using assms by(auto split: init_call_status.splits list.splits bool.splits)
lemma Jcc_pieces_SCall_clinit_body:
assumes [simp]: "P ≡ compP⇩2 P⇩1" and wf: "wf_J⇩1_prog P⇩1"
and "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩3 ls⇩2 sh⇩3 v xa (C1∙⇩sclinit([]))
= (True, frs', rhs', err')"
and method: "P⇩1 ⊢ C1 sees clinit,Static: []→Void = body in D"
shows "Jcc_pieces P⇩1 [] D clinit h⇩2 [] (replicate (max_vars body) undefined) 0
No_ics (tl frs') sh⇩2 {..<length (compE⇩2 body)} h⇩3 ls⇩3 sh⇩3 v xa body
= (True, frs',
(None,h⇩3,([v],ls⇩3,D,clinit,size(compE⇩2 body), No_ics)#tl frs',sh⇩3),
∃pc⇩1. 0 ≤ pc⇩1 ∧ pc⇩1 < size(compE⇩2 body) ∧
¬ caught P pc⇩1 h⇩3 xa (compxE⇩2 body 0 0) ∧
(∃vs'. P ⊢ (None,h⇩2,frs',sh⇩2) -jvm→ handle P D clinit xa h⇩3 vs' ls⇩3 pc⇩1
No_ics (tl frs') sh⇩3))"
proof -
have M_in_D: "P⇩1 ⊢ D sees clinit,Static: []→Void = body in D"
using method by(rule sees_method_idemp)
hence M_code: "compP⇩2 P⇩1,D,clinit,0 ⊳ compE⇩2 body @ [Return]"
and M_xtab: "compP⇩2 P⇩1,D,clinit ⊳ compxE⇩2 body 0 0/{..<size(compE⇩2 body)},0"
by(rule beforeM, rule beforexM)
have nsub: "¬sub_RI body" by(rule sees_wf⇩1_nsub_RI[OF wf method])
then show ?thesis using assms nsub_RI_Jcc_pieces M_code M_xtab by clarsimp
qed
lemma Jcc_pieces_Cons:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "P,C,M,pc ⊳ compEs⇩2 (e#es)" and "P,C,M ⊳ compxEs⇩2 (e#es) pc (size vs)/I,size vs"
and "{pc..<pc+size(compEs⇩2 (e#es))} ⊆ I"
and "ics = No_ics"
and "¬sub_RIs (e#es)"
shows "Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh
(I - pcs (compxEs⇩2 es (pc + length (compE⇩2 e)) (Suc (length vs)))) h' ls' sh' v xa e
= (True, (vs, ls, C, M, pc, ics) # frs,
(None, h', (v#vs, ls', C, M, pc + length (compE⇩2 e), ics) # frs, sh'),
∃pc⇩1≥pc. pc⇩1 < pc + length (compE⇩2 e) ∧ ¬ caught P pc⇩1 h' xa (compxE⇩2 e pc (length vs))
∧ (∃vs'. P ⊢ (None, h, (vs, ls, C, M, pc, ics) # frs, sh)
-jvm→ handle P C M xa h' (vs'@vs) ls' pc⇩1 ics frs sh'))"
proof -
show ?thesis using assms nsub_RI_Jcc_pieces[where e=e] by auto
qed
lemma Jcc_pieces_InitNone:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa (INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
shows
"Jcc_pieces P⇩1 E C M h vs l pc ics frs (sh(C⇩0 ↦ (sblank P C⇩0, Prepared)))
I h' l' sh' v xa (INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'),
∃vs'. P ⊢ (None,h,frs',(sh(C⇩0 ↦ (sblank P⇩1 C⇩0, Prepared))))
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh')"
proof -
have "Jcc_cond P⇩1 E C M vs pc ics I h sh (INIT C' (C⇩0 # Cs,False) ← e)" using assms by simp
then obtain T where "P⇩1,E,h,sh ⊢⇩1 INIT C' (C⇩0 # Cs,False) ← unit : T" by fastforce
then have "P⇩1,E,h,sh(C⇩0 ↦ (sblank P⇩1 C⇩0, Prepared)) ⊢⇩1 INIT C' (C⇩0 # Cs,False) ← unit : T"
by(auto simp: fun_upd_apply)
then have "Ex (WTrt2⇩1 P⇩1 E h (sh(C⇩0 ↦ (sblank P⇩1 C⇩0, Prepared))) (INIT C' (C⇩0 # Cs,False) ← unit))"
by(simp only: exI)
then show ?thesis using assms by clarsimp
qed
lemma Jcc_pieces_InitDP:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa (INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
shows
"Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa (INIT C' (Cs,True) ← e)
= (True, (calling_to_scalled (hd frs'))#(tl frs'),
(None, h', (vs, l, C, M, pc, Called []) # frs, sh'),
∃vs'. P ⊢ (None,h,calling_to_scalled (hd frs')#(tl frs'),sh)
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh')"
proof -
have "Jcc_cond P⇩1 E C M vs pc ics I h sh (INIT C' (C⇩0 # Cs,False) ← e)" using assms by simp
then obtain T where "P⇩1,E,h,sh ⊢⇩1 INIT C' (C⇩0 # Cs,False) ← unit : T" by fastforce
then have "P⇩1,E,h,sh ⊢⇩1 INIT C' (Cs,True) ← unit : T"
by (auto; metis list.sel(2) list.set_sel(2))
then have wtrt: "Ex (WTrt2⇩1 P⇩1 E h sh (INIT C' (Cs,True) ← unit))" by(simp only: exI)
show ?thesis using assms wtrt
proof(cases Cs)
case (Cons C1 Cs1)
then show ?thesis using assms wtrt
by(case_tac "method P C1 clinit") clarsimp
qed(clarsimp)
qed
lemma Jcc_pieces_InitError:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa (INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
and err: "sh C⇩0 = Some(sfs,Error)"
shows
"Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa (RI (C⇩0, THROW NoClassDefFoundError);Cs ← e)
= (True, (calling_to_throwing (hd frs') (addr_of_sys_xcpt NoClassDefFoundError))#(tl frs'),
(None, h', (vs, l, C, M, pc, Called []) # frs, sh'),
∃vs'. P ⊢ (None,h, (calling_to_throwing (hd frs') (addr_of_sys_xcpt NoClassDefFoundError))#(tl frs'),sh)
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh')"
proof -
show ?thesis using assms
proof(cases Cs)
case (Cons C1 Cs1)
then show ?thesis using assms
by(case_tac "method P C1 clinit", case_tac "method P C⇩0 clinit") clarsimp
qed(clarsimp)
qed
lemma Jcc_pieces_InitObj:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' (sh(C⇩0 ↦ (sfs,Processing))) v xa (INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
shows
"Jcc_pieces P⇩1 E C M h vs l pc ics frs (sh(C⇩0 ↦ (sfs,Processing))) I h' l' sh'' v xa (INIT C' (C⇩0 # Cs,True) ← e)
= (True, calling_to_called (hd frs')#(tl frs'),
(None, h', (vs, l, C, M, pc, Called []) # frs, sh''),
∃vs'. P ⊢ (None,h,calling_to_called (hd frs')#(tl frs'),sh')
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh'')"
proof -
have "Jcc_cond P⇩1 E C M vs pc ics I h sh (INIT C' (C⇩0 # Cs,False) ← e)" using assms by simp
then obtain T where "P⇩1,E,h,sh ⊢⇩1 INIT C' (C⇩0 # Cs,False) ← unit : T" by fastforce
then have "P⇩1,E,h,sh(C⇩0 ↦ (sfs,Processing)) ⊢⇩1 INIT C' (C⇩0 # Cs,True) ← unit : T"
using assms by clarsimp (auto simp: fun_upd_apply)
then have wtrt: "Ex (WTrt2⇩1 P⇩1 E h (sh(C⇩0 ↦ (sfs,Processing))) (INIT C' (C⇩0 # Cs,True) ← unit))"
by(simp only: exI)
show ?thesis using assms wtrt by clarsimp
qed
lemma Jcc_pieces_InitNonObj:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "is_class P⇩1 D" and "D ∉ set (C⇩0#Cs)" and "∀C ∈ set (C⇩0#Cs). P⇩1 ⊢ C ≼⇧* D"
and pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' (sh(C⇩0 ↦ (sfs,Processing))) v xa (INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
shows
"Jcc_pieces P⇩1 E C M h vs l pc ics frs (sh(C⇩0 ↦ (sfs,Processing))) I h' l' sh'' v xa (INIT C' (D # C⇩0 # Cs,False) ← e)
= (True, calling_to_calling (hd frs') D#(tl frs'),
(None, h', (vs, l, C, M, pc, Called []) # frs, sh''),
∃vs'. P ⊢ (None,h,calling_to_calling (hd frs') D#(tl frs'),sh')
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh'')"
proof -
have "Jcc_cond P⇩1 E C M vs pc ics I h sh (INIT C' (C⇩0 # Cs,False) ← e)" using assms by simp
then obtain T where "P⇩1,E,h,sh ⊢⇩1 INIT C' (C⇩0 # Cs,False) ← unit : T" by fastforce
then have "P⇩1,E,h,sh(C⇩0 ↦ (sfs,Processing)) ⊢⇩1 INIT C' (D # C⇩0 # Cs,False) ← unit : T"
using assms by clarsimp (auto simp: fun_upd_apply)
then have wtrt: "Ex (WTrt2⇩1 P⇩1 E h (sh(C⇩0 ↦ (sfs,Processing))) (INIT C' (D # C⇩0 # Cs,False) ← unit))"
by(simp only: exI)
show ?thesis using assms wtrt by clarsimp
qed
lemma Jcc_pieces_InitRInit:
assumes [simp]: "P ≡ compP⇩2 P⇩1" and wf: "wf_J⇩1_prog P⇩1"
and "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa (INIT C' (C⇩0 # Cs,True) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
shows
"Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa (RI (C⇩0,C⇩0∙⇩sclinit([])) ; Cs ← e)
= (True, frs',
(None, h', (vs, l, C, M, pc, Called []) # frs, sh'),
∃vs'. P ⊢ (None,h,frs',sh)
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh')"
proof -
have cond: "Jcc_cond P⇩1 E C M vs pc ics I h sh (INIT C' (C⇩0 # Cs,True) ← e)" using assms by simp
then have clinit: "∃T. P⇩1,E,h,sh ⊢⇩1 C⇩0∙⇩sclinit([]) : T" using wf
by clarsimp (auto simp: is_class_def intro: wf⇩1_types_clinit)
then obtain T where cT: "P⇩1,E,h,sh ⊢⇩1 C⇩0∙⇩sclinit([]) : T" by blast
obtain T where "P⇩1,E,h,sh ⊢⇩1 INIT C' (C⇩0 # Cs,True) ← unit : T" using cond by fastforce
then have "P⇩1,E,h,sh ⊢⇩1 RI (C⇩0,C⇩0∙⇩sclinit([])) ; Cs ← unit : T"
using assms by (auto intro: cT)
then have wtrt: "Ex (WTrt2⇩1 P⇩1 E h sh (RI (C⇩0,C⇩0∙⇩sclinit([])) ; Cs ← unit))"
by(simp only: exI)
then show ?thesis using assms by simp
qed
lemma Jcc_pieces_RInit_clinit:
assumes [simp]: "P ≡ compP⇩2 P⇩1" and wf: "wf_J⇩1_prog P⇩1"
and "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h⇩1 l⇩1 sh⇩1 v xa (RI (C⇩0,C⇩0∙⇩sclinit([]));Cs ← e)
= (True, frs',
(None, h⇩1, (vs, l, C, M, pc, Called []) # frs, sh⇩1), err)"
shows
"Jcc_pieces P⇩1 E C M h vs l pc (Called Cs) (tl frs') sh I h' l' sh' v xa (C⇩0∙⇩sclinit([]))
= (True, create_init_frame P C⇩0#(vs,l,C,M,pc,Called Cs)#tl frs',
(None, h', (vs,l,C,M,pc,Called Cs)#tl frs', sh'(C⇩0↦(fst(the(sh' C⇩0)),Done))),
P ⊢ (None,h,create_init_frame P C⇩0#(vs,l,C,M,pc,Called Cs)#tl frs',sh)
-jvm→ (None,h',(vs, l, C, M, pc, Throwing Cs xa) # tl frs',sh'(C⇩0 ↦ (fst(the(sh' C⇩0)),Error))))"
proof -
have cond: "Jcc_cond P⇩1 E C M vs pc ics I h sh (RI (C⇩0,C⇩0∙⇩sclinit([]));Cs ← e)" using assms by simp
then have wtrt: "∃T. P⇩1,E,h,sh ⊢⇩1 C⇩0∙⇩sclinit([]) : T" using wf
by clarsimp (auto simp: is_class_def intro: wf⇩1_types_clinit)
then show ?thesis using assms by clarsimp
qed
lemma Jcc_pieces_RInit_Init:
assumes [simp]: "P ≡ compP⇩2 P⇩1" and wf: "wf_J⇩1_prog P⇩1"
and proc: "∀C' ∈ set Cs. ∃sfs. sh'' C' = ⌊(sfs,Processing)⌋"
and "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h⇩1 l⇩1 sh⇩1 v xa (RI (C⇩0,C⇩0∙⇩sclinit([]));Cs ← e)
= (True, frs',
(None, h⇩1, (vs, l, C, M, pc, Called []) # frs, sh⇩1), err)"
shows
"Jcc_pieces P⇩1 E C M h' vs l pc ics frs sh'' I h⇩1 l⇩1 sh⇩1 v xa (INIT (last (C⇩0#Cs)) (Cs,True) ← e)
= (True, (vs, l, C, M, pc, Called Cs) # frs,
(None, h⇩1, (vs, l, C, M, pc, Called []) # frs, sh⇩1),
∃vs'. P ⊢ (None,h',(vs, l, C, M, pc, Called Cs) # frs,sh'')
-jvm→ handle P C M xa h⇩1 (vs'@vs) l pc ics frs sh⇩1)"
proof -
have "Jcc_cond P⇩1 E C M vs pc ics I h sh (RI (C⇩0,C⇩0∙⇩sclinit([]));Cs ← e)" using assms by simp
then have "Ex (WTrt2⇩1 P⇩1 E h sh (RI (C⇩0,C⇩0∙⇩sclinit([])) ; Cs ← unit))" by simp
then obtain T where riwt: "P⇩1,E,h,sh ⊢⇩1 RI (C⇩0,C⇩0∙⇩sclinit([]));Cs ← unit : T" by meson
then have "P⇩1,E,h',sh'' ⊢⇩1 INIT (last (C⇩0#Cs)) (Cs,True) ← unit : T" using proc
proof(cases Cs) qed(auto)
then have wtrt: "Ex (WTrt2⇩1 P⇩1 E h' sh'' (INIT (last (C⇩0#Cs)) (Cs,True) ← unit))" by(simp only: exI)
show ?thesis using assms wtrt
proof(cases Cs)
case (Cons C1 Cs1)
then show ?thesis using assms wtrt
by(case_tac "method P C1 clinit") clarsimp
qed(clarsimp)
qed
lemma Jcc_pieces_RInit_RInit:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h⇩1 l⇩1 sh⇩1 v xa (RI (C⇩0,e);D#Cs ← e')
= (True, frs', rhs, err)"
and hd: "hd frs' = (vs1,l1,C1,M1,pc1,ics1)"
shows
"Jcc_pieces P⇩1 E C M h' vs l pc ics frs sh'' I h⇩1 l⇩1 sh⇩1 v xa (RI (D,Throw xa) ; Cs ← e')
= (True, (vs1, l1, C1, M1, pc1, Throwing (D#Cs) xa) # tl frs',
(None, h⇩1, (vs, l, C, M, pc, Called []) # frs, sh⇩1),
∃vs'. P ⊢ (None,h',(vs1, l1, C1, M1, pc1, Throwing (D#Cs) xa) # tl frs',sh'')
-jvm→ handle P C M xa h⇩1 (vs'@vs) l pc ics frs sh⇩1)"
using assms by(case_tac "method P D clinit", cases "e = C⇩0∙⇩sclinit([])") clarsimp+
subsubsection "JVM stepping lemmas"
lemma jvm_Invoke:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "P,C,M,pc ▹ Invoke M' (length Ts)"
and ha: "h⇩2 a = ⌊(Ca, fs)⌋" and method: "P⇩1 ⊢ Ca sees M', NonStatic : Ts→T = body in D"
and len: "length pvs = length Ts" and "ls⇩2' = Addr a # pvs @ replicate (max_vars body) undefined"
shows "P ⊢ (None, h⇩2, (rev pvs @ Addr a # vs, ls⇩2, C, M, pc, No_ics) # frs, sh⇩2) -jvm→
(None, h⇩2, ([], ls⇩2', D, M', 0, No_ics) # (rev pvs @ Addr a # vs, ls⇩2, C, M, pc, No_ics) # frs, sh⇩2)"
proof -
have cname: "cname_of h⇩2 (the_Addr ((rev pvs @ Addr a # vs) ! length Ts)) = Ca"
using ha method len by(auto simp: nth_append)
have r: "(rev pvs @ Addr a # vs) ! (length Ts) = Addr a" using len by(auto simp: nth_append)
have exm: "∃Ts T m D b. P ⊢ Ca sees M',b:Ts → T = m in D"
using sees_method_compP[OF method] by fastforce
show ?thesis using assms cname r exm by simp
qed
lemma jvm_Invokestatic:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "P,C,M,pc ▹ Invokestatic C' M' (length Ts)"
and sh: "sh⇩2 D = Some(sfs,Done)"
and method: "P⇩1 ⊢ C' sees M', Static : Ts→T = body in D"
and len: "length pvs = length Ts" and "ls⇩2' = pvs @ replicate (max_vars body) undefined"
shows "P ⊢ (None, h⇩2, (rev pvs @ vs, ls⇩2, C, M, pc, No_ics) # frs, sh⇩2) -jvm→
(None, h⇩2, ([], ls⇩2', D, M', 0, No_ics) # (rev pvs @ vs, ls⇩2, C, M, pc, No_ics) # frs, sh⇩2)"
proof -
have exm: "∃Ts T m D b. P ⊢ C' sees M',b:Ts → T = m in D"
using sees_method_compP[OF method] by fastforce
show ?thesis using assms exm by simp
qed
lemma jvm_Invokestatic_Called:
assumes [simp]: "P ≡ compP⇩2 P⇩1"
and "P,C,M,pc ▹ Invokestatic C' M' (length Ts)"
and sh: "sh⇩2 D = Some(sfs,i)"
and method: "P⇩1 ⊢ C' sees M', Static : Ts→T = body in D"
and len: "length pvs = length Ts" and "ls⇩2' = pvs @ replicate (max_vars body) undefined"
shows "P ⊢ (None, h⇩2, (rev pvs @ vs, ls⇩2, C, M, pc, Called []) # frs, sh⇩2) -jvm→
(None, h⇩2, ([], ls⇩2', D, M', 0, No_ics) # (rev pvs @ vs, ls⇩2, C, M, pc, No_ics) # frs, sh⇩2)"
proof -
have exm: "∃Ts T m D b. P ⊢ C' sees M',b:Ts → T = m in D"
using sees_method_compP[OF method] by fastforce
show ?thesis using assms exm by simp
qed
lemma jvm_Return_Init:
"P,D,clinit,0 ⊳ compE⇩2 body @ [Return]
⟹ P ⊢ (None, h, (vs, ls, D, clinit, size(compE⇩2 body), No_ics) # frs, sh)
-jvm→ (None, h, frs, sh(D↦(fst(the(sh D)),Done)))"
(is "?P ⟹ P ⊢ ?s1 -jvm→ ?s2")
proof -
assume ?P
then have "exec (P, ?s1) = ⌊?s2⌋" by(cases frs) auto
then have "(?s1, ?s2) ∈ (exec_1 P)⇧*"
by(rule exec_1I[THEN r_into_rtrancl])
then show ?thesis by(simp add: exec_all_def1)
qed
lemma jvm_InitNone:
"⟦ ics_of f = Calling C Cs;
sh C = None ⟧
⟹ P ⊢ (None,h,f#frs,sh) -jvm→ (None,h,f#frs,sh(C ↦ (sblank P C, Prepared)))"
(is "⟦ ?P; ?Q ⟧ ⟹ P ⊢ ?s1 -jvm→ ?s2")
proof -
assume assms: ?P ?Q
then obtain stk1 loc1 C1 M1 pc1 ics1 where "f = (stk1,loc1,C1,M1,pc1,ics1)"
by(cases f) simp
then have "exec (P, ?s1) = ⌊?s2⌋" using assms
by(case_tac ics1) simp_all
then have "(?s1, ?s2) ∈ (exec_1 P)⇧*"
by(rule exec_1I[THEN r_into_rtrancl])
then show ?thesis by(simp add: exec_all_def1)
qed
lemma jvm_InitDP:
"⟦ ics_of f = Calling C Cs;
sh C = ⌊(sfs,i)⌋; i = Done ∨ i = Processing ⟧
⟹ P ⊢ (None,h,f#frs,sh) -jvm→ (None,h,(calling_to_scalled f)#frs,sh)"
(is "⟦ ?P; ?Q; ?R ⟧ ⟹ P ⊢ ?s1 -jvm→ ?s2")
proof -
assume assms: ?P ?Q ?R
then obtain stk1 loc1 C1 M1 pc1 ics1 where "f = (stk1,loc1,C1,M1,pc1,ics1)"
by(cases f) simp
then have "exec (P, ?s1) = ⌊?s2⌋" using assms
by(case_tac i) simp_all
then have "(?s1, ?s2) ∈ (exec_1 P)⇧*"
by(rule exec_1I[THEN r_into_rtrancl])
then show ?thesis by(simp add: exec_all_def1)
qed
lemma jvm_InitError:
"sh C = ⌊(sfs,Error)⌋
⟹ P ⊢ (None,h,(vs,ls,C⇩0,M,pc,Calling C Cs)#frs,sh)
-jvm→ (None,h,(vs,ls,C⇩0,M,pc,Throwing Cs (addr_of_sys_xcpt NoClassDefFoundError))#frs,sh)"
by(clarsimp simp: exec_all_def1 intro!: r_into_rtrancl exec_1I)
lemma exec_ErrorThrowing:
"sh C = ⌊(sfs,Error)⌋
⟹ exec (P, (None,h,calling_to_throwing (stk,loc,D,M,pc,Calling C Cs) a#frs,sh))
= Some (None,h,calling_to_sthrowing (stk,loc,D,M,pc,Calling C Cs) a #frs,sh)"
by(clarsimp simp: exec_all_def1 fun_upd_idem_iff intro!: r_into_rtrancl exec_1I)
lemma jvm_InitObj:
"⟦ sh C = Some(sfs,Prepared);
C = Object;
sh' = sh(C ↦ (sfs,Processing)) ⟧
⟹ P ⊢ (None, h, (vs,ls,C⇩0,M,pc,Calling C Cs)#frs, sh) -jvm→
(None, h, (vs,ls,C⇩0,M,pc,Called (C#Cs))#frs,sh')"
(is "⟦ ?P; ?Q; ?R ⟧ ⟹ P ⊢ ?s1 -jvm→ ?s2")
proof -
assume assms: ?P ?Q ?R
then have "exec (P, ?s1) = ⌊?s2⌋"
by(case_tac "method P C clinit") simp
then have "(?s1, ?s2) ∈ (exec_1 P)⇧*"
by(rule exec_1I[THEN r_into_rtrancl])
then show ?thesis by(simp add: exec_all_def1)
qed
lemma jvm_InitNonObj:
"⟦ sh C = Some(sfs,Prepared);
C ≠ Object;
class P C = Some (D,r);
sh' = sh(C ↦ (sfs,Processing)) ⟧
⟹ P ⊢ (None, h, (vs,ls,C⇩0,M,pc,Calling C Cs)#frs, sh) -jvm→
(None, h, (vs,ls,C⇩0,M,pc,Calling D (C#Cs))#frs, sh')"
(is "⟦ ?P; ?Q; ?R; ?S ⟧ ⟹ P ⊢ ?s1 -jvm→ ?s2")
proof -
assume assms: ?P ?Q ?R ?S
then have "exec (P, ?s1) = ⌊?s2⌋"
by(case_tac "method P C clinit") simp
then have "(?s1, ?s2) ∈ (exec_1 P)⇧*"
by(rule exec_1I[THEN r_into_rtrancl])
then show ?thesis by(simp add: exec_all_def1)
qed
lemma jvm_RInit_throw:
"P ⊢ (None,h,(vs,l,C,M,pc,Throwing [] xa) # frs,sh)
-jvm→ handle P C M xa h vs l pc No_ics frs sh"
(is "P ⊢ ?s1 -jvm→ ?s2")
proof -
have "exec (P, ?s1) = ⌊?s2⌋"
by(simp add: handle_def split: bool.splits)
then have "(?s1, ?s2) ∈ (exec_1 P)⇧*"
by(rule exec_1I[THEN r_into_rtrancl])
then show ?thesis by(simp add: exec_all_def1)
qed
lemma jvm_RInit_throw':
"P ⊢ (None,h,(vs,l,C,M,pc,Throwing [C'] xa) # frs,sh)
-jvm→ handle P C M xa h vs l pc No_ics frs (sh(C':=Some(fst(the(sh C')), Error)))"
(is "P ⊢ ?s1 -jvm→ ?s2")
proof -
let ?sy = "(None,h,(vs,l,C,M,pc,Throwing [] xa) # frs,sh(C':=Some(fst(the(sh C')), Error)))"
have "exec (P, ?s1) = ⌊?sy⌋" by simp
then have "(?s1, ?sy) ∈ (exec_1 P)⇧*"
by(rule exec_1I[THEN r_into_rtrancl])
also have "(?sy, ?s2) ∈ (exec_1 P)⇧*"
using jvm_RInit_throw by(simp add: exec_all_def1)
ultimately show ?thesis by(simp add: exec_all_def1)
qed
lemma jvm_Called:
"P ⊢ (None, h, (vs, l, C, M, pc, Called (C⇩0 # Cs)) # frs, sh) -jvm→
(None, h, create_init_frame P C⇩0 # (vs, l, C, M, pc, Called Cs) # frs, sh)"
by(simp add: exec_all_def1 r_into_rtrancl exec_1I)
lemma jvm_Throwing:
"P ⊢ (None, h, (vs, l, C, M, pc, Throwing (C⇩0#Cs) xa') # frs, sh) -jvm→
(None, h, (vs, l, C, M, pc, Throwing Cs xa') # frs, sh(C⇩0 ↦ (fst (the (sh C⇩0)), Error)))"
by(simp add: exec_all_def1 r_into_rtrancl exec_1I)
subsubsection "Other lemmas for correctness proof"
lemma assumes wf:"wf_prog wf_md P"
and ex: "class P C = Some a"
shows create_init_frame_wf_eq: "create_init_frame (compP⇩2 P) C = (stk,loc,D,M,pc,ics) ⟹ D=C"
using wf_sees_clinit[OF wf ex] by(cases "method P C clinit", auto)
lemma beforex_try:
assumes pcI: "{pc..<pc+size(compE⇩2(try e⇩1 catch(Ci i) e⇩2))} ⊆ I"
and bx: "P,C,M ⊳ compxE⇩2 (try e⇩1 catch(Ci i) e⇩2) pc (size vs) / I,size vs"
shows "P,C,M ⊳ compxE⇩2 e⇩1 pc (size vs) / {pc..<pc + length (compE⇩2 e⇩1)},size vs"
proof -
obtain xt⇩0 xt⇩1 where
"beforex⇩0 P C M (size vs) I (compxE⇩2 (try e⇩1 catch(Ci i) e⇩2) pc (size vs)) xt⇩0 xt⇩1"
using bx by(clarsimp simp:beforex_def)
then have "∃xt1. beforex⇩0 P C M (size vs) {pc..<pc + length (compE⇩2 e⇩1)}
(compxE⇩2 e⇩1 pc (size vs)) xt⇩0 xt1"
using pcI pcs_subset(1) atLeastLessThan_iff by simp blast
then show ?thesis using beforex_def by blast
qed
lemma
shows eval⇩1_init_return: "P ⊢⇩1 ⟨e,s⟩ ⇒ ⟨e',s'⟩
⟹ iconf (shp⇩1 s) e
⟹ (∃Cs b. e = INIT C' (Cs,b) ← unit) ∨ (∃C e⇩0 Cs e⇩i. e = RI(C,e⇩0);Cs@[C'] ← unit)
∨ (∃e⇩0. e = RI(C',e⇩0);Nil ← unit)
⟹ (val_of e' = Some v ⟶ (∃sfs i. shp⇩1 s' C' = ⌊(sfs,i)⌋ ∧ (i = Done ∨ i = Processing)))
∧ (throw_of e' = Some a ⟶ (∃sfs i. shp⇩1 s' C' = ⌊(sfs,Error)⌋))"
and "P ⊢⇩1 ⟨es,s⟩ [⇒] ⟨es',s'⟩ ⟹ True"
proof(induct rule: eval⇩1_evals⇩1.inducts)
case (InitFinal⇩1 e s e' s' C b) then show ?case
by(auto simp: initPD_def dest: eval⇩1_final_same)
next
case (InitDone⇩1 sh C sfs C' Cs e h l e' s')
then have "final e'" using eval⇩1_final by simp
then show ?case
proof(rule finalE)
fix v assume e': "e' = Val v" then show ?thesis using InitDone⇩1 initPD_def
proof(cases Cs) qed(auto)
next
fix a assume e': "e' = throw a" then show ?thesis using InitDone⇩1 initPD_def
proof(cases Cs) qed(auto)
qed
next
case (InitProcessing⇩1 sh C sfs C' Cs e h l e' s')
then have "final e'" using eval⇩1_final by simp
then show ?case
proof(rule finalE)
fix v assume e': "e' = Val v" then show ?thesis using InitProcessing⇩1 initPD_def
proof(cases Cs) qed(auto)
next
fix a assume e': "e' = throw a" then show ?thesis using InitProcessing⇩1 initPD_def
proof(cases Cs) qed(auto)
qed
next
case (InitError⇩1 sh C sfs Cs e h l e' s' C') show ?case
proof(cases Cs)
case Nil then show ?thesis using InitError⇩1 by simp
next
case (Cons C2 list)
then have "final e'" using InitError⇩1 eval⇩1_final by simp
then show ?thesis
proof(rule finalE)
fix v assume e': "e' = Val v" show ?thesis
using InitError⇩1.hyps(2) e' rinit⇩1_throwE by blast
next
fix a assume e': "e' = throw a"
then show ?thesis using Cons InitError⇩1 cons_to_append[of list] by clarsimp
qed
qed
next
case (InitRInit⇩1 C Cs h l sh e' s' C') show ?case
proof(cases Cs)
case Nil then show ?thesis using InitRInit⇩1 by simp
next
case (Cons C' list) then show ?thesis
using InitRInit⇩1 Cons cons_to_append[of list] by clarsimp
qed
next
case (RInit⇩1 e s v h' l' sh' C sfs i sh'' C' Cs e' e⇩1 s⇩1)
then have final: "final e⇩1" using eval⇩1_final by simp
then show ?case
proof(cases Cs)
case Nil show ?thesis using final
proof(rule finalE)
fix v assume e': "e⇩1 = Val v" show ?thesis
using RInit⇩1 Nil by(clarsimp, meson fun_upd_same initPD_def)
next
fix a assume e': "e⇩1 = throw a" show ?thesis
using RInit⇩1 Nil by(clarsimp, meson fun_upd_same initPD_def)
qed
next
case (Cons a list) show ?thesis using final
proof(rule finalE)
fix v assume e': "e⇩1 = Val v" then show ?thesis
using RInit⇩1 Cons by(clarsimp, metis last.simps last_appendR list.distinct(1))
next
fix a assume e': "e⇩1 = throw a" then show ?thesis
using RInit⇩1 Cons by(clarsimp, metis last.simps last_appendR list.distinct(1))
qed
qed
next
case (RInitInitFail⇩1 e s a h' l' sh' C sfs i sh'' D Cs e' e⇩1 s⇩1)
then have final: "final e⇩1" using eval⇩1_final by simp
then show ?case
proof(rule finalE)
fix v assume e': "e⇩1 = Val v" then show ?thesis
using RInitInitFail⇩1 by(clarsimp, meson exp.distinct(101) rinit⇩1_throwE)
next
fix a' assume e': "e⇩1 = Throw a'"
then have "iconf (sh'(C ↦ (sfs, Error))) a"
using RInitInitFail⇩1.hyps(1) eval⇩1_final by fastforce
then show ?thesis using RInitInitFail⇩1 e'
by(clarsimp, meson Cons_eq_append_conv list.inject)
qed
qed(auto simp: fun_upd_same)
lemma init⇩1_Val_PD: "P ⊢⇩1 ⟨INIT C' (Cs,b) ← unit,s⟩ ⇒ ⟨Val v,s'⟩
⟹ iconf (shp⇩1 s) (INIT C' (Cs,b) ← unit)
⟹ ∃sfs i. shp⇩1 s' C' = ⌊(sfs,i)⌋ ∧ (i = Done ∨ i = Processing)"
by(drule_tac v = v in eval⇩1_init_return, simp+)
lemma init⇩1_throw_PD: "P ⊢⇩1 ⟨INIT C' (Cs,b) ← unit,s⟩ ⇒ ⟨throw a,s'⟩
⟹ iconf (shp⇩1 s) (INIT C' (Cs,b) ← unit)
⟹ ∃sfs i. shp⇩1 s' C' = ⌊(sfs,Error)⌋"
by(drule_tac a = a in eval⇩1_init_return, simp+)
lemma rinit⇩1_Val_PD:
assumes eval: "P ⊢⇩1 ⟨RI(C,e⇩0);Cs ← unit,s⟩ ⇒ ⟨Val v,s'⟩"
and iconf: "iconf (shp⇩1 s) (RI(C,e⇩0);Cs ← unit)" and last: "last(C#Cs) = C'"
shows "∃sfs i. shp⇩1 s' C' = ⌊(sfs,i)⌋ ∧ (i = Done ∨ i = Processing)"
proof(cases Cs)
case Nil
then show ?thesis using eval⇩1_init_return[OF eval iconf] last by simp
next
case (Cons a list)
then have nNil: "Cs ≠ []" by simp
then have "∃Cs'. Cs = Cs' @ [C']" using last append_butlast_last_id[OF nNil]
by(rule_tac x="butlast Cs" in exI) simp
then show ?thesis using eval⇩1_init_return[OF eval iconf] by simp
qed
lemma rinit⇩1_throw_PD:
assumes eval: "P ⊢⇩1 ⟨RI(C,e⇩0);Cs ← unit,s⟩ ⇒ ⟨throw a,s'⟩"
and iconf: "iconf (shp⇩1 s) (RI(C,e⇩0);Cs ← unit)" and last: "last(C#Cs) = C'"
shows "∃sfs. shp⇩1 s' C' = ⌊(sfs,Error)⌋"
proof(cases Cs)
case Nil
then show ?thesis using eval⇩1_init_return[OF eval iconf] last by simp
next
case (Cons a list)
then have nNil: "Cs ≠ []" by simp
then have "∃Cs'. Cs = Cs' @ [C']" using last append_butlast_last_id[OF nNil]
by(rule_tac x="butlast Cs" in exI) simp
then show ?thesis using eval⇩1_init_return[OF eval iconf] by simp
qed
subsubsection "The proof"
lemma fixes P⇩1 defines [simp]: "P ≡ compP⇩2 P⇩1"
assumes wf: "wf_J⇩1_prog P⇩1"
shows Jcc: "P⇩1 ⊢⇩1 ⟨e,(h⇩0,ls⇩0,sh⇩0)⟩ ⇒ ⟨ef,(h⇩1,ls⇩1,sh⇩1)⟩ ⟹
(⋀E C M pc ics v xa vs frs I.
⟦ Jcc_cond P⇩1 E C M vs pc ics I h⇩0 sh⇩0 e ⟧ ⟹
(ef = Val v ⟶
P ⊢ (None,h⇩0,Jcc_frames P C M vs ls⇩0 pc ics frs e,sh⇩0)
-jvm→ Jcc_rhs P⇩1 E C M vs ls⇩0 pc ics frs h⇩1 ls⇩1 sh⇩1 v e)
∧
(ef = Throw xa ⟶ Jcc_err P C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 xa e)
)"
(is "_ ⟹ (⋀E C M pc ics v xa vs frs I.
PROP ?P e h⇩0 ls⇩0 sh⇩0 ef h⇩1 ls⇩1 sh⇩1 E C M pc ics v xa vs frs I)")
and "P⇩1 ⊢⇩1 ⟨es,(h⇩0,ls⇩0,sh⇩0)⟩ [⇒] ⟨fs,(h⇩1,ls⇩1,sh⇩1)⟩ ⟹
(⋀C M pc ics ws xa es' vs frs I.
⟦ P,C,M,pc ⊳ compEs⇩2 es; P,C,M ⊳ compxEs⇩2 es pc (size vs)/I,size vs;
{pc..<pc+size(compEs⇩2 es)} ⊆ I; ics = No_ics;
¬sub_RIs es ⟧ ⟹
(fs = map Val ws ⟶
P ⊢ (None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0) -jvm→
(None,h⇩1,(rev ws @ vs,ls⇩1,C,M,pc+size(compEs⇩2 es),ics)#frs,sh⇩1))
∧
(fs = map Val ws @ Throw xa # es' ⟶
(∃pc⇩1. pc ≤ pc⇩1 ∧ pc⇩1 < pc + size(compEs⇩2 es) ∧
¬ caught P pc⇩1 h⇩1 xa (compxEs⇩2 es pc (size vs)) ∧
(∃vs'. P ⊢ (None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0)
-jvm→ handle P C M xa h⇩1 (vs'@vs) ls⇩1 pc⇩1 ics frs sh⇩1))))"
(is "_ ⟹ (⋀C M pc ics ws xa es' vs frs I.
PROP ?Ps es h⇩0 ls⇩0 sh⇩0 fs h⇩1 ls⇩1 sh⇩1 C M pc ics ws xa es' vs frs I)")
proof (induct rule:eval⇩1_evals⇩1_inducts)
case New⇩1 thus ?case by auto
next
case (NewFail⇩1 sh C' sfs h ls)
let ?xa = "addr_of_sys_xcpt OutOfMemory"
have "P ⊢ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm→ handle P C M ?xa h vs ls pc ics frs sh"
using NewFail⇩1 by(clarsimp simp: handle_def)
then show ?case by(auto intro!: exI[where x="[]"])
next
case (NewInit⇩1 sh C' h ls v' h' ls' sh' a FDTs h'')
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (new C')
= (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE⇩2 (new C')),ics)#frs,sh'), err)"
using NewInit⇩1.prems(1) by clarsimp
have "Ex (WTrt2⇩1 P⇩1 E h sh (INIT C' ([C'],False) ← unit))"
using has_fields_is_class[OF NewInit⇩1.hyps(5)] by auto
then obtain err' where pcs':
"Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v' xa (INIT C' ([C'],False) ← unit)
= (True, (vs,ls,C,M,pc,Calling C' []) # frs, (None,h',(vs,ls,C,M,pc,Called [])#frs,sh'), err')"
using NewInit⇩1.prems(1) by auto
have IH: "PROP ?P (INIT C' ([C'],False) ← unit) h ls sh (Val v')
h' ls' sh' E C M pc ics v' xa vs frs I" by fact
have ls: "ls = ls'" by(rule init⇩1_same_loc[OF NewInit⇩1.hyps(2)])
obtain sfs i where sh': "sh' C' = Some(sfs,i)"
using init⇩1_Val_PD[OF NewInit⇩1.hyps(2)] by clarsimp
have "P ⊢ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm→ (None,h,(vs,ls,C,M,pc,Calling C' [])#frs,sh)"
proof(cases "sh C'")
case None then show ?thesis using NewInit⇩1.prems by(cases ics) auto
next
case (Some a)
then obtain sfs i where "a = (sfs,i)" by(cases a)
then show ?thesis using NewInit⇩1.hyps(1) NewInit⇩1.prems Some
by(cases ics; case_tac i) auto
qed
also have "P ⊢ … -jvm→ (None, h', (vs, ls, C, M, pc, Called []) # frs, sh')"
using IH pcs' by auto
also have "P ⊢ … -jvm→ (None, h'', (Addr a#vs, ls, C, M, Suc pc, ics) # frs, sh')"
using NewInit⇩1.hyps(1,2,4-6) NewInit⇩1.prems sh' by(cases ics) auto
finally show ?case using pcs ls by clarsimp
next
case (NewInitOOM⇩1 sh C' h ls v' h' ls' sh')
let ?xa = "addr_of_sys_xcpt OutOfMemory"
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (new C')
= (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE⇩2 (new C')),ics)#frs,sh'), err)"
using NewInitOOM⇩1.prems(1) by clarsimp
have "Ex (WTrt2⇩1 P⇩1 E h sh (INIT C' ([C'],False) ← unit))" using NewInitOOM⇩1.hyps(5) by auto
then obtain err' where pcs':
"Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v' xa (INIT C' ([C'],False) ← unit)
= (True, (vs,ls,C,M,pc,Calling C' []) # frs, (None,h',(vs,ls,C,M,pc,Called [])#frs,sh'), err')"
using NewInitOOM⇩1.prems(1) by auto
have IH: "PROP ?P (INIT C' ([C'],False) ← unit) h ls sh (Val v')
h' ls' sh' E C M pc ics v' xa vs frs I" by fact
have ls: "ls = ls'" by(rule init⇩1_same_loc[OF NewInitOOM⇩1.hyps(2)])
have "iconf (shp⇩1 (h, ls, sh)) (INIT C' ([C'],False) ← unit)" by simp
then obtain sfs i where sh': "sh' C' = Some(sfs,i)"
using init⇩1_Val_PD[OF NewInitOOM⇩1.hyps(2)] by clarsimp
have "P ⊢ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm→ (None,h,(vs,ls,C,M,pc,Calling C' [])#frs,sh)"
proof(cases "sh C'")
case None then show ?thesis using NewInitOOM⇩1.prems by(cases ics) auto
next
case (Some a)
then obtain sfs i where "a = (sfs,i)" by(cases a)
then show ?thesis using NewInitOOM⇩1.hyps(1) NewInitOOM⇩1.prems Some
by(cases ics; case_tac i) auto
qed
also have "P ⊢ … -jvm→ (None, h', (vs, ls, C, M, pc, Called []) # frs, sh')"
using IH pcs' by auto
also have "P ⊢ … -jvm→ handle P C M ?xa h' vs ls pc ics frs sh'"
using NewInitOOM⇩1.hyps(1,2,4,5) NewInitOOM⇩1.prems sh' by(auto simp: handle_def)
finally show ?case using pcs ls by(simp, metis (no_types) append_Nil le_refl lessI)
next
case (NewInitThrow⇩1 sh C' h ls a h' ls' sh')
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (new C')
= (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE⇩2 (new C')),ics)#frs,sh'), err)"
using NewInitThrow⇩1.prems(1) by clarsimp
obtain a' where throw: "throw a = Throw a'" using eval⇩1_final[OF NewInitThrow⇩1.hyps(2)] by clarsimp
have "Ex (WTrt2⇩1 P⇩1 E h sh (INIT C' ([C'],False) ← unit))" using NewInitThrow⇩1.hyps(4) by auto
then obtain vs' where pcs':
"Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v a' (INIT C' ([C'],False) ← unit)
= (True, (vs,ls,C,M,pc,Calling C' []) # frs, (None,h',(vs,ls,C,M,pc,Called [])#frs,sh'),
P ⊢ (None,h,(vs,ls,C,M,pc,Calling C' []) # frs,sh)
-jvm→ handle P C M a' h' (vs'@vs) ls pc ics frs sh')"
using NewInitThrow⇩1.prems(1) by simp blast
have IH: "PROP ?P (INIT C' ([C'],False) ← unit) h ls sh (throw a)
h' ls' sh' E C M pc ics v a' vs frs I" by fact
have ls: "ls = ls'" by(rule init⇩1_same_loc[OF NewInitThrow⇩1.hyps(2)])
then have "P ⊢ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm→ (None,h,(vs,ls,C,M,pc,Calling C' []) # frs,sh)"
proof(cases "sh C'")
case None then show ?thesis using NewInitThrow⇩1.prems by(cases ics) auto
next
case (Some a)
then obtain sfs i where "a = (sfs,i)" by(cases a)
then show ?thesis using NewInitThrow⇩1.hyps(1) NewInitThrow⇩1.prems Some
by(cases ics; case_tac i) auto
qed
also have "P ⊢ … -jvm→ handle P C M a' h' (vs'@vs) ls pc ics frs sh'" using IH pcs' throw by auto
finally show ?case using throw ls by auto
next
case (Cast⇩1 e h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 D fs C')
let ?pc = "pc + length(compE⇩2 e)"
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (Cast C' e)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (Cast C' e)),ics)#frs,sh⇩1), err)"
using Cast⇩1.prems(1) by auto
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) xa vs frs I" by fact
then have "P ⊢ (None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0) -jvm→
(None,h⇩1,(Addr a#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using Jcc_pieces_Cast[OF assms(1) pcs, of "Addr a"] Cast⇩1.prems pcs by auto
also have "P ⊢ … -jvm→ (None,h⇩1,(Addr a#vs,ls⇩1,C,M,?pc+1,ics)#frs,sh⇩1)"
using Cast⇩1 by (auto simp add:cast_ok_def)
finally show ?case by auto
next
case (CastNull⇩1 e h⇩0 ls⇩0 sh⇩0 h⇩1 ls⇩1 sh⇩1 C')
let ?pc = "pc + length(compE⇩2 e)"
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (Cast C' e)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (Cast C' e)),ics)#frs,sh⇩1), err)"
using CastNull⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 null h⇩1 ls⇩1 sh⇩1 E C M pc ics Null xa vs frs I" by fact
then have "P ⊢ (None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0) -jvm→
(None,h⇩1,(Null#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using Jcc_pieces_Cast[OF assms(1) pcs, of Null] CastNull⇩1.prems pcs by auto
also have "P ⊢ … -jvm→ (None,h⇩1,(Null#vs,ls⇩1,C,M,?pc+1,ics)#frs,sh⇩1)"
using CastNull⇩1 by (auto simp add:cast_ok_def)
finally show ?case by auto
next
case (CastFail⇩1 e h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 D fs C')
let ?pc = "pc + length(compE⇩2 e)"
let ?xa = "addr_of_sys_xcpt ClassCast"
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (Cast C' e)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (Cast C' e)),ics)#frs,sh⇩1), err)"
using CastFail⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) xa vs frs I" by fact
then have "P ⊢ (None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0) -jvm→
(None,h⇩1,(Addr a#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using Jcc_pieces_Cast[OF assms(1) pcs, of "Addr a"] CastFail⇩1.prems pcs by auto
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩1 (Addr a#vs) ls⇩1 ?pc ics frs sh⇩1"
using CastFail⇩1 by (auto simp add:handle_def cast_ok_def)
finally have exec: "P ⊢ (None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0) -jvm→ …".
show ?case (is "?N ∧ (?eq ⟶ ?err)")
proof
show ?N by simp
next
{ assume ?eq
then have ?err using exec by (auto intro!: exI[where x="?pc"] exI[where x="[Addr a]"])
}
thus "?eq ⟶ ?err" by simp
qed
next
case (CastThrow⇩1 e h⇩0 ls⇩0 sh⇩0 e' h⇩1 ls⇩1 sh⇩1 C')
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (Cast C' e)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (Cast C' e)),ics)#frs,sh⇩1), err)"
using CastThrow⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (throw e') h⇩1 ls⇩1 sh⇩1 E C M pc ics v xa vs frs I" by fact
show ?case using IH Jcc_pieces_Cast[OF assms(1) pcs, of v] CastThrow⇩1.prems pcs less_SucI
by(simp, blast)
next
case Val⇩1 thus ?case by auto
next
case Var⇩1 thus ?case by auto
next
case (BinOp⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 v⇩1 h⇩1 ls⇩1 sh⇩1 e⇩2 v⇩2 h⇩2 ls⇩2 sh⇩2 bop w)
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e⇩1 «bop» e⇩2)
= (True, frs', (None,h⇩2,(v#vs,ls⇩2,C,M,pc+size(compE⇩2 (e⇩1 «bop» e⇩2)),ics)#frs,sh⇩2), err)"
using BinOp⇩1.prems(1) by clarsimp
let ?pc⇩1 = "pc + length(compE⇩2 e⇩1)"
let ?pc⇩2 = "?pc⇩1 + length(compE⇩2 e⇩2)"
have IH⇩1: "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 (Val v⇩1) h⇩1 ls⇩1 sh⇩1 E C M pc ics v⇩1 xa vs frs
(I - pcs (compxE⇩2 e⇩2 (pc + length (compE⇩2 e⇩1)) (Suc (length vs))))" by fact
have IH⇩2: "PROP ?P e⇩2 h⇩1 ls⇩1 sh⇩1 (Val v⇩2) h⇩2 ls⇩2 sh⇩2 E C M ?pc⇩1 ics v⇩2 xa (v⇩1#vs) frs
(I - pcs(compxE⇩2 e⇩1 pc (size vs)))" by fact
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(v⇩1#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
using IH⇩1 Jcc_pieces_BinOp1[OF pcs, of h⇩1 ls⇩1 sh⇩1 v⇩1] by simp
also have "P ⊢ … -jvm→ (None,h⇩2,(v⇩2#v⇩1#vs,ls⇩2,C,M,?pc⇩2,ics)#frs,sh⇩2)"
using IH⇩2 Jcc_pieces_BinOp2[OF assms(1) pcs, of h⇩1 v⇩1 ls⇩1 sh⇩1 v⇩2] by (simp add: add.assoc)
also have "P ⊢ … -jvm→ (None,h⇩2,(w#vs,ls⇩2,C,M,?pc⇩2+1,ics)#frs,sh⇩2)"
using BinOp⇩1 by(cases bop) auto
finally show ?case using pcs by (auto split: bop.splits simp:add.assoc)
next
case (BinOpThrow⇩1⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 e h⇩1 ls⇩1 sh⇩1 bop e⇩2)
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (e⇩1 «bop» e⇩2)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (e⇩1 «bop» e⇩2)),ics)#frs,sh⇩1), err)"
using BinOpThrow⇩1⇩1.prems(1) by clarsimp
have IH⇩1: "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 (throw e) h⇩1 ls⇩1 sh⇩1 E C M pc ics v xa vs frs
(I - pcs (compxE⇩2 e⇩2 (pc + length (compE⇩2 e⇩1)) (Suc (length vs))))" by fact
show ?case using IH⇩1 Jcc_pieces_BinOp1[OF pcs, of h⇩1 ls⇩1 sh⇩1 v] BinOpThrow⇩1⇩1.prems nsub_RI_Jcc_pieces
by auto
next
case (BinOpThrow⇩2⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 v⇩1 h⇩1 ls⇩1 sh⇩1 e⇩2 e h⇩2 ls⇩2 sh⇩2 bop)
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e⇩1 «bop» e⇩2)
= (True, frs', (None,h⇩2,(v#vs,ls⇩2,C,M,pc+size(compE⇩2 (e⇩1 «bop» e⇩2)),ics)#frs,sh⇩2), err)"
using BinOpThrow⇩2⇩1.prems(1) by clarsimp
let ?pc = "pc + length(compE⇩2 e⇩1)"
have IH⇩1: "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 (Val v⇩1) h⇩1 ls⇩1 sh⇩1 E C M pc ics v⇩1 xa vs frs
(I - pcs (compxE⇩2 e⇩2 (pc + length (compE⇩2 e⇩1)) (Suc (length vs))))" by fact
have IH⇩2: "PROP ?P e⇩2 h⇩1 ls⇩1 sh⇩1 (throw e) h⇩2 ls⇩2 sh⇩2 E C M ?pc ics v xa (v⇩1#vs) frs
(I - pcs(compxE⇩2 e⇩1 pc (size vs)))" by fact
let ?σ⇩1 = "(None,h⇩1,(v⇩1#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
have 1: "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ ?σ⇩1"
using IH⇩1 Jcc_pieces_BinOp1[OF pcs, of h⇩1 ls⇩1 sh⇩1 v⇩1] by simp
have "(throw e = Val v ⟶ P ⊢ (None, h⇩0, Jcc_frames P C M vs ls⇩0 pc ics frs (e⇩1 «bop» e⇩2), sh⇩0) -jvm→
Jcc_rhs P⇩1 E C M vs ls⇩0 pc ics frs h⇩2 ls⇩2 sh⇩2 v (e⇩1 «bop» e⇩2))
∧ (throw e = Throw xa ⟶ (∃pc⇩1. pc ≤ pc⇩1 ∧ pc⇩1 < pc + size(compE⇩2 (e⇩1 «bop» e⇩2)) ∧
¬ caught P pc⇩1 h⇩2 xa (compxE⇩2 (e⇩1 «bop» e⇩2) pc (size vs)) ∧
(∃vs'. P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ handle P C M xa h⇩2 (vs'@vs) ls⇩2 pc⇩1 ics frs sh⇩2)))"
(is "?N ∧ (?eq ⟶ (∃pc⇩2. ?H pc⇩2))")
proof
show ?N by simp
next
{ assume ?eq
then obtain pc⇩2 vs' where
pc⇩2: "?pc ≤ pc⇩2 ∧ pc⇩2 < ?pc + size(compE⇩2 e⇩2) ∧
¬ caught P pc⇩2 h⇩2 xa (compxE⇩2 e⇩2 ?pc (size vs + 1))" and
2: "P ⊢ ?σ⇩1 -jvm→ handle P C M xa h⇩2 (vs'@v⇩1#vs) ls⇩2 pc⇩2 ics frs sh⇩2"
using IH⇩2 Jcc_pieces_BinOp2[OF assms(1) pcs, of h⇩1 v⇩1 ls⇩1 sh⇩1 v] BinOpThrow⇩2⇩1.prems by clarsimp
then have "?H pc⇩2" using jvm_trans[OF 1 2] by(auto intro!: exI[where x="vs'@[v⇩1]"])
hence "∃pc⇩2. ?H pc⇩2" by iprover
}
thus "?eq ⟶ (∃pc⇩2. ?H pc⇩2)" by iprover
qed
then show ?case using pcs by simp blast
next
case (FAcc⇩1 e h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 C' fs F T D w)
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (e∙F{D})
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (e∙F{D})),ics)#frs,sh⇩1), err)"
using FAcc⇩1.prems(1) by clarsimp
have "P⇩1 ⊢ D sees F,NonStatic:T in D" by(rule has_field_sees[OF has_field_idemp[OF FAcc⇩1.hyps(4)]])
then have field: "field P D F = (D,NonStatic,T)" by simp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) xa vs frs I" by fact
let ?pc = "pc + length(compE⇩2 e)"
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(Addr a#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using IH Jcc_pieces_FAcc[OF pcs, of "Addr a"] pcs by simp
also have "P ⊢ … -jvm→ (None,h⇩1,(w#vs,ls⇩1,C,M,?pc+1,ics)#frs,sh⇩1)"
using FAcc⇩1 field by auto
finally have "P ⊢ (None, h⇩0, frs', sh⇩0) -jvm→ (None,h⇩1,(w#vs,ls⇩1,C,M,?pc+1,ics)#frs,sh⇩1)"
by auto
then show ?case using pcs by auto
next
case (FAccNull⇩1 e h⇩0 ls⇩0 sh⇩0 h⇩1 ls⇩1 sh⇩1 F D)
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (e∙F{D})
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (e∙F{D})),ics)#frs,sh⇩1), err)"
using FAccNull⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 null h⇩1 ls⇩1 sh⇩1 E C M pc ics Null xa vs frs I" by fact
let ?pc = "pc + length(compE⇩2 e)"
let ?xa = "addr_of_sys_xcpt NullPointer"
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(Null#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using IH Jcc_pieces_FAcc[OF pcs, of Null] by simp
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩1 (Null#vs) ls⇩1 ?pc ics frs sh⇩1"
using FAccNull⇩1.prems
by(fastforce simp:split_beta handle_def simp del: split_paired_Ex)
finally show ?case using pcs by (auto intro!: exI[where x = ?pc] exI[where x="[Null]"])
next
case (FAccThrow⇩1 e h⇩0 ls⇩0 sh⇩0 e' h⇩1 ls⇩1 sh⇩1 F D)
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (e∙F{D})
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (e∙F{D})),ics)#frs,sh⇩1), err)"
using FAccThrow⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (throw e') h⇩1 ls⇩1 sh⇩1 E C M pc ics v xa vs frs I" by fact
show ?case using IH Jcc_pieces_FAcc[OF pcs, of v] FAccThrow⇩1.prems nsub_RI_Jcc_pieces
less_Suc_eq by auto
next
case (FAccNone⇩1 e h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 C fs F D)
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (e∙F{D})
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (e∙F{D})),ics)#frs,sh⇩1), err)"
using FAccNone⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) xa vs frs I" by fact
let ?pc = "pc + length(compE⇩2 e)"
let ?xa = "addr_of_sys_xcpt NoSuchFieldError"
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(Addr a#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using IH Jcc_pieces_FAcc[OF pcs, of "Addr a"] by simp
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩1 (Addr a#vs) ls⇩1 ?pc ics frs sh⇩1"
using FAccNone⇩1
by(cases ics; clarsimp simp:split_beta handle_def simp del: split_paired_Ex)
finally show ?case using pcs by (auto intro!: exI[where x = ?pc] exI[where x="[Addr a]"])
next
case (FAccStatic⇩1 e h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 C' fs F T D)
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (e∙F{D})
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (e∙F{D})),ics)#frs,sh⇩1), err)"
using FAccStatic⇩1.prems(1) by clarsimp
have "P⇩1 ⊢ D sees F,Static:T in D" by(rule has_field_sees[OF has_field_idemp[OF FAccStatic⇩1.hyps(4)]])
then have field: "field P D F = (D,Static,T)" by simp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) xa vs frs I" by fact
let ?pc = "pc + length(compE⇩2 e)"
let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError"
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(Addr a#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using IH Jcc_pieces_FAcc[OF pcs, of "Addr a"] by simp
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩1 (Addr a#vs) ls⇩1 ?pc ics frs sh⇩1"
using FAccStatic⇩1 field by(fastforce simp:split_beta handle_def simp del: split_paired_Ex)
finally show ?case using pcs by (auto intro!: exI[where x = ?pc] exI[where x="[Addr a]"])
next
case (SFAcc⇩1 C' F t D sh sfs v' h ls)
have has: "P⇩1 ⊢ D has F,Static:t in D" by(rule has_field_idemp[OF SFAcc⇩1.hyps(1)])
have "P⇩1 ⊢ D sees F,Static:t in D" by(rule has_field_sees[OF has])
then have field: "field P D F = (D,Static,t)" by simp
then have "P ⊢ (None,h,Jcc_frames P C M vs ls pc ics frs (C'∙⇩sF{D}),sh) -jvm→
(None,h,(v'#vs,ls,C,M,Suc pc,ics)#frs,sh)"
using SFAcc⇩1 has by(cases ics) auto
then show ?case by clarsimp
next
case (SFAccInit⇩1 C' F t D sh h ls v' h' ls' sh' sfs i v'')
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (C'∙⇩sF{D})
= (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE⇩2 (C'∙⇩sF{D})),ics)#frs,sh'), err)"
using SFAccInit⇩1.prems(1) by clarsimp
have "Ex (WTrt2⇩1 P⇩1 E h sh (INIT D ([D],False) ← unit))"
using has_field_is_class'[OF SFAccInit⇩1.hyps(1)] by auto
then obtain err' where pcs':
"Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v' xa (INIT D ([D],False) ← unit)
= (True, (vs,ls,C,M,pc,Calling D []) # frs, (None,h',(vs,ls,C,M,pc,Called [])#frs,sh'), err')"
using SFAccInit⇩1.prems(1) by auto
have IH: "PROP ?P (INIT D ([D],False) ← unit) h ls sh (Val v')
h' ls' sh' E C M pc ics v' xa vs frs I" by fact
have ls: "ls = ls'" by(rule init⇩1_same_loc[OF SFAccInit⇩1.hyps(3)])
have has: "P⇩1 ⊢ D has F,Static:t in D" by(rule has_field_idemp[OF SFAccInit⇩1.hyps(1)])
have "P⇩1 ⊢ D sees F,Static:t in D" by(rule has_field_sees[OF has])
then have field: "field P D F = (D,Static,t)" by simp
have "P ⊢ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm→ (None,h,(vs,ls,C,M,pc,Calling D [])#frs,sh)"
proof(cases "sh D")
case None then show ?thesis using SFAccInit⇩1.hyps(1,2,5,6) SFAccInit⇩1.prems field
by(cases ics) auto
next
case (Some a)
then obtain sfs i where "a = (sfs,i)" by(cases a)
then show ?thesis using SFAccInit⇩1.hyps(1,2,5,6) SFAccInit⇩1.prems field Some
by(cases ics; case_tac i) auto
qed
also have "P ⊢ ... -jvm→ (None, h', (vs, ls, C, M, pc, Called []) # frs, sh')"
using IH pcs' by auto
also have "P ⊢ ... -jvm→ (None, h', (v''#vs, ls, C, M, Suc pc, ics) # frs, sh')"
using SFAccInit⇩1.hyps(1,2,5,6) SFAccInit⇩1.prems has field by(cases ics) auto
finally show ?case using pcs ls by clarsimp
next
case (SFAccInitThrow⇩1 C' F t D sh h ls a h' ls' sh')
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (C'∙⇩sF{D})
= (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE⇩2 (C'∙⇩sF{D})),ics)#frs,sh'), err)"
using SFAccInitThrow⇩1.prems(1) by clarsimp
obtain a' where throw: "throw a = Throw a'" using eval⇩1_final[OF SFAccInitThrow⇩1.hyps(3)] by clarsimp
have "Ex (WTrt2⇩1 P⇩1 E h sh (INIT D ([D],False) ← unit))"
using has_field_is_class'[OF SFAccInitThrow⇩1.hyps(1)] by auto
then obtain vs' where pcs':
"Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v a' (INIT D ([D],False) ← unit)
= (True, (vs,ls,C,M,pc,Calling D []) # frs, (None,h',(vs,ls,C,M,pc,Called [])#frs,sh'),
P ⊢ (None,h,(vs,ls,C,M,pc,Calling D []) # frs,sh)
-jvm→ handle P C M a' h' (vs'@vs) ls pc ics frs sh')"
using SFAccInitThrow⇩1.prems(1) by simp blast
have IH: "PROP ?P (INIT D ([D],False) ← unit) h ls sh (throw a)
h' ls' sh' E C M pc ics v a' vs frs I" by fact
have ls: "ls = ls'" by(rule init⇩1_same_loc[OF SFAccInitThrow⇩1.hyps(3)])
have has: "P⇩1 ⊢ D has F,Static:t in D" by(rule has_field_idemp[OF SFAccInitThrow⇩1.hyps(1)])
have "P⇩1 ⊢ D sees F,Static:t in D" by(rule has_field_sees[OF has])
then have field: "field P D F = (D,Static,t)" by simp
then have "P ⊢ (None,h,(vs,ls,C,M,pc,ics)#frs,sh) -jvm→ (None,h,(vs,ls,C,M,pc,Calling D []) # frs,sh)"
proof(cases "sh D")
case None then show ?thesis using SFAccInitThrow⇩1.hyps(1,2) SFAccInitThrow⇩1.prems field
by(cases ics) auto
next
case (Some a)
then obtain sfs i where "a = (sfs,i)" by(cases a)
then show ?thesis using SFAccInitThrow⇩1.hyps(1,2) SFAccInitThrow⇩1.prems field Some
by(cases ics; case_tac i) auto
qed
also have "P ⊢ … -jvm→ handle P C M a' h' (vs'@vs) ls pc ics frs sh'"
using IH pcs' throw by auto
finally show ?case using throw ls by auto
next
case (SFAccNone⇩1 C' F D h⇩1 ls⇩1 sh⇩1)
then obtain frs' err where pcs:
"Jcc_pieces P⇩1 E C M h⇩1 vs ls⇩1 pc ics frs sh⇩1 I h⇩1 ls⇩1 sh⇩1 v xa (C'∙⇩sF{D})
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (C'∙⇩sF{D})),ics)#frs,sh⇩1), err)"
by clarsimp
let ?xa = "addr_of_sys_xcpt NoSuchFieldError"
have "P ⊢ (None,h⇩1,frs',sh⇩1) -jvm→ handle P C M ?xa h⇩1 vs ls⇩1 pc ics frs sh⇩1"
using SFAccNone⇩1 pcs
by(cases ics; clarsimp simp:split_beta handle_def simp del: split_paired_Ex)
then show ?case using pcs by(auto intro!: exI[where x = pc] exI[where x="[]"])
next
case (SFAccNonStatic⇩1 C' F t D h⇩1 ls⇩1 sh⇩1)
let ?frs' = "(vs, ls⇩1, C, M, pc, ics) # frs"
let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError"
have "P⇩1 ⊢ D sees F,NonStatic:t in D"
by(rule has_field_sees[OF has_field_idemp[OF SFAccNonStatic⇩1.hyps(1)]])
then have field: "field P D F = (D,NonStatic,t)" by simp
have "P ⊢ (None,h⇩1,?frs',sh⇩1) -jvm→ handle P C M ?xa h⇩1 vs ls⇩1 pc ics frs sh⇩1"
using SFAccNonStatic⇩1
proof(cases ics)
case No_ics
then show ?thesis using SFAccNonStatic⇩1 field
by (auto simp:split_beta handle_def simp del: split_paired_Ex)
qed(simp_all)
then show ?case by (auto intro!: exI[where x = pc] exI[where x="[]"])
next
case (LAss⇩1 e h⇩0 ls⇩0 sh⇩0 w h⇩1 ls⇩1 sh⇩1 i ls⇩2)
let ?pc = "pc + length(compE⇩2 e)"
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (i:=e)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (i:=e)),ics)#frs,sh⇩1), err)"
using LAss⇩1.prems(1) by auto
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (Val w) h⇩1 ls⇩1 sh⇩1 E C M pc ics w xa vs frs I" by fact
then have "P ⊢ (None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0) -jvm→
(None,h⇩1,(w#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using Jcc_pieces_LAss[OF assms(1) pcs, of w] LAss⇩1.prems pcs by auto
also have "P ⊢ … -jvm→ (None,h⇩1,(Unit#vs,ls⇩2,C,M,?pc+2,ics)#frs,sh⇩1)"
using LAss⇩1 by (auto simp add:cast_ok_def)
finally show ?case by auto
next
case (LAssThrow⇩1 e h⇩0 ls⇩0 sh⇩0 w h⇩1 ls⇩1 sh⇩1 i)
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (i:=e)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (i:=e)),ics)#frs,sh⇩1), err)"
using LAssThrow⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (throw w) h⇩1 ls⇩1 sh⇩1 E C M pc ics v xa vs frs I" by fact
show ?case using IH Jcc_pieces_LAss[OF assms(1) pcs, of v] LAssThrow⇩1.prems pcs less_SucI
by(simp, blast)
next
case (FAss⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 e⇩2 w h⇩2 ls⇩2 sh⇩2 C' fs F T D fs' h⇩2')
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e⇩1∙F{D} := e⇩2)
= (True, frs', (None,h⇩2,(v#vs,ls⇩2,C,M,pc+size(compE⇩2 (e⇩1∙F{D} := e⇩2)),ics)#frs,sh⇩2), err)"
using FAss⇩1.prems(1) by clarsimp
have "P⇩1 ⊢ D sees F,NonStatic:T in D" by(rule has_field_sees[OF has_field_idemp[OF FAss⇩1.hyps(6)]])
then have field: "field P D F = (D,NonStatic,T)" by simp
let ?pc⇩1 = "pc + length(compE⇩2 e⇩1)"
let ?pc⇩2 = "?pc⇩1 + length(compE⇩2 e⇩2)"
have IH⇩1: "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) xa vs frs
(I - pcs (compxE⇩2 e⇩2 (pc + length (compE⇩2 e⇩1)) (Suc (length vs))))" by fact
have IH⇩2: "PROP ?P e⇩2 h⇩1 ls⇩1 sh⇩1 (Val w) h⇩2 ls⇩2 sh⇩2 E C M ?pc⇩1 ics w xa (Addr a#vs) frs
(I - pcs(compxE⇩2 e⇩1 pc (size vs)))" by fact
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(Addr a#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
using IH⇩1 Jcc_pieces_FAss1[OF pcs, of h⇩1 ls⇩1 sh⇩1 "Addr a"] by simp
also have "P ⊢ … -jvm→ (None,h⇩2,(w#Addr a#vs,ls⇩2,C,M,?pc⇩2,ics)#frs,sh⇩2)"
using IH⇩2 Jcc_pieces_FAss2[OF pcs, of h⇩1 "Addr a" ls⇩1 sh⇩1 w] by (simp add: add.assoc)
also have "P ⊢ … -jvm→ (None,h⇩2',(Unit#vs,ls⇩2,C,M,?pc⇩2+2,ics)#frs,sh⇩2)"
using FAss⇩1 field by auto
finally show ?case using pcs by (auto simp:add.assoc)
next
case (FAssNull⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 h⇩1 ls⇩1 sh⇩1 e⇩2 w h⇩2 ls⇩2 sh⇩2 F D)
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e⇩1∙F{D} := e⇩2)
= (True, frs', (None,h⇩2,(v#vs,ls⇩2,C,M,pc+size(compE⇩2 (e⇩1∙F{D} := e⇩2)),ics)#frs,sh⇩2), err)"
using FAssNull⇩1.prems(1) by clarsimp
let ?pc⇩1 = "pc + length(compE⇩2 e⇩1)"
let ?pc⇩2 = "?pc⇩1 + length(compE⇩2 e⇩2)"
let ?xa = "addr_of_sys_xcpt NullPointer"
have IH⇩1: "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 null h⇩1 ls⇩1 sh⇩1 E C M pc ics Null xa vs frs
(I - pcs (compxE⇩2 e⇩2 (pc + length (compE⇩2 e⇩1)) (Suc (length vs))))" by fact
have IH⇩2: "PROP ?P e⇩2 h⇩1 ls⇩1 sh⇩1 (Val w) h⇩2 ls⇩2 sh⇩2 E C M ?pc⇩1 ics w xa (Null#vs) frs
(I - pcs(compxE⇩2 e⇩1 pc (size vs)))" by fact
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(Null#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
using IH⇩1 Jcc_pieces_FAss1[OF pcs, of h⇩1 ls⇩1 sh⇩1 Null] by simp
also have "P ⊢ … -jvm→ (None,h⇩2,(w#Null#vs,ls⇩2,C,M,?pc⇩2,ics)#frs,sh⇩2)"
using IH⇩2 Jcc_pieces_FAss2[OF pcs, of h⇩1 Null ls⇩1 sh⇩1 w] by (simp add: add.assoc)
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩2 (w#Null#vs) ls⇩2 ?pc⇩2 ics frs sh⇩2"
using FAssNull⇩1 by(fastforce simp:split_beta handle_def simp del: split_paired_Ex)
finally show ?case using pcs by (auto intro!: exI[where x = ?pc⇩2] exI[where x="w#[Null]"])
next
case (FAssThrow⇩2⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 w h⇩1 ls⇩1 sh⇩1 e⇩2 e' h⇩2 ls⇩2 sh⇩2 F D)
let ?frs' = "(vs, ls⇩0, C, M, pc, ics) # frs"
obtain err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e⇩1∙F{D} := e⇩2)
= (True, ?frs', (None,h⇩2,(v#vs,ls⇩2,C,M,pc+size(compE⇩2 (e⇩1∙F{D} := e⇩2)),ics)#frs,sh⇩2), err)"
using FAssThrow⇩2⇩1.prems(1) by clarsimp
let ?pc⇩1 = "pc + length(compE⇩2 e⇩1)"
let ?σ⇩1 = "(None,h⇩1,(w#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
have IH⇩1: "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 (Val w) h⇩1 ls⇩1 sh⇩1 E C M pc ics w xa vs frs
(I - pcs (compxE⇩2 e⇩2 (pc + length (compE⇩2 e⇩1)) (Suc (length vs))))" by fact
have IH⇩2: "PROP ?P e⇩2 h⇩1 ls⇩1 sh⇩1 (throw e') h⇩2 ls⇩2 sh⇩2 E C M ?pc⇩1 ics v xa (w#vs) frs
(I - pcs(compxE⇩2 e⇩1 pc (size vs)))" by fact
have 1: "P ⊢ (None,h⇩0,?frs',sh⇩0) -jvm→ ?σ⇩1"
using IH⇩1 Jcc_pieces_FAss1[OF pcs, of h⇩1 ls⇩1 sh⇩1 w] by simp
show ?case (is "?N ∧ (?eq ⟶ ?err)")
proof
show ?N by simp
next
{ assume ?eq
moreover
have "PROP ?P e⇩2 h⇩1 ls⇩1 sh⇩1 (throw e') h⇩2 ls⇩2 sh⇩2 E C M ?pc⇩1 ics v xa (w#vs) frs
(I - pcs (compxE⇩2 e⇩1 pc (length vs)))" by fact
ultimately obtain pc⇩2 vs' where
pc⇩2: "?pc⇩1 ≤ pc⇩2 ∧ pc⇩2 < ?pc⇩1 + size(compE⇩2 e⇩2) ∧
¬ caught P pc⇩2 h⇩2 xa (compxE⇩2 e⇩2 ?pc⇩1 (size vs + 1))" and
2: "P ⊢ ?σ⇩1 -jvm→ handle P C M xa h⇩2 (vs'@w#vs) ls⇩2 pc⇩2 ics frs sh⇩2"
using FAssThrow⇩2⇩1.prems Jcc_pieces_FAss2[OF pcs, of h⇩1 w ls⇩1 sh⇩1] by auto
have ?err using Jcc_pieces_FAss2[OF pcs, of h⇩1 w ls⇩1 sh⇩1] pc⇩2 jvm_trans[OF 1 2]
by(auto intro!: exI[where x=pc⇩2] exI[where x="vs'@[w]"])
}
thus "?eq ⟶ ?err" by simp
qed
next
case (FAssThrow⇩1⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 e' h⇩1 ls⇩1 sh⇩1 F D e⇩2)
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (e⇩1∙F{D} := e⇩2)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (e⇩1∙F{D} := e⇩2)),ics)#frs,sh⇩1), err)"
using FAssThrow⇩1⇩1.prems(1) by clarsimp
have IH⇩1: "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 (throw e') h⇩1 ls⇩1 sh⇩1 E C M pc ics v xa vs frs
(I - pcs (compxE⇩2 e⇩2 (pc + length (compE⇩2 e⇩1)) (Suc (length vs))))" by fact
show ?case using IH⇩1 Jcc_pieces_FAss1[OF pcs, of h⇩1 ls⇩1 sh⇩1 v] FAssThrow⇩1⇩1.prems nsub_RI_Jcc_pieces
by auto
next
case (FAssNone⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 e⇩2 w h⇩2 ls⇩2 sh⇩2 C' fs F D)
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e⇩1∙F{D} := e⇩2)
= (True, frs', (None,h⇩2,(v#vs,ls⇩2,C,M,pc+size(compE⇩2 (e⇩1∙F{D} := e⇩2)),ics)#frs,sh⇩2), err)"
using FAssNone⇩1.prems(1) by clarsimp
let ?pc⇩1 = "pc + length(compE⇩2 e⇩1)"
let ?pc⇩2 = "?pc⇩1 + length(compE⇩2 e⇩2)"
let ?xa = "addr_of_sys_xcpt NoSuchFieldError"
have IH⇩1: "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) xa vs frs
(I - pcs (compxE⇩2 e⇩2 (pc + length (compE⇩2 e⇩1)) (Suc (length vs))))" by fact
have IH⇩2: "PROP ?P e⇩2 h⇩1 ls⇩1 sh⇩1 (Val w) h⇩2 ls⇩2 sh⇩2 E C M ?pc⇩1 ics w xa (Addr a#vs) frs
(I - pcs(compxE⇩2 e⇩1 pc (size vs)))" by fact
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(Addr a#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
using IH⇩1 Jcc_pieces_FAss1[OF pcs, of h⇩1 ls⇩1 sh⇩1 "Addr a"] by simp
also have "P ⊢ … -jvm→ (None,h⇩2,(w#Addr a#vs,ls⇩2,C,M,?pc⇩2,ics)#frs,sh⇩2)"
using IH⇩2 Jcc_pieces_FAss2[OF pcs, of h⇩1 "Addr a" ls⇩1 sh⇩1 w] by (simp add: add.assoc)
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩2 (w#Addr a#vs) ls⇩2 ?pc⇩2 ics frs sh⇩2"
using FAssNone⇩1 by(fastforce simp:split_beta handle_def simp del: split_paired_Ex)
finally show ?case using pcs by (auto intro!: exI[where x = ?pc⇩2] exI[where x="w#[Addr a]"])
next
case (FAssStatic⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 e⇩2 w h⇩2 ls⇩2 sh⇩2 C' fs F T D)
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e⇩1∙F{D} := e⇩2)
= (True, frs', (None,h⇩2,(v#vs,ls⇩2,C,M,pc+size(compE⇩2 (e⇩1∙F{D} := e⇩2)),ics)#frs,sh⇩2), err)"
using FAssStatic⇩1.prems(1) by clarsimp
have "P⇩1 ⊢ D sees F,Static:T in D" by(rule has_field_sees[OF has_field_idemp[OF FAssStatic⇩1.hyps(6)]])
then have field: "field P D F = (D,Static,T)" by simp
let ?pc⇩1 = "pc + length(compE⇩2 e⇩1)"
let ?pc⇩2 = "?pc⇩1 + length(compE⇩2 e⇩2)"
let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError"
have IH⇩1: "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) xa vs frs
(I - pcs (compxE⇩2 e⇩2 (pc + length (compE⇩2 e⇩1)) (Suc (length vs))))" by fact
have IH⇩2: "PROP ?P e⇩2 h⇩1 ls⇩1 sh⇩1 (Val w) h⇩2 ls⇩2 sh⇩2 E C M ?pc⇩1 ics w xa (Addr a#vs) frs
(I - pcs(compxE⇩2 e⇩1 pc (size vs)))" by fact
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(Addr a#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
using IH⇩1 Jcc_pieces_FAss1[OF pcs, of h⇩1 ls⇩1 sh⇩1 "Addr a"] by simp
also have "P ⊢ … -jvm→ (None,h⇩2,(w#Addr a#vs,ls⇩2,C,M,?pc⇩2,ics)#frs,sh⇩2)"
using IH⇩2 Jcc_pieces_FAss2[OF pcs, of h⇩1 "Addr a" ls⇩1 sh⇩1 w] by (simp add: add.assoc)
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩2 (w#Addr a#vs) ls⇩2 ?pc⇩2 ics frs sh⇩2"
using FAssStatic⇩1 field by(fastforce simp:split_beta handle_def simp del: split_paired_Ex)
finally show ?case using pcs by (auto intro!: exI[where x = ?pc⇩2] exI[where x="w#[Addr a]"])
next
case (SFAss⇩1 e⇩2 h⇩0 ls⇩0 sh⇩0 w h⇩1 ls⇩1 sh⇩1 C' F T D sfs sfs' sh⇩1')
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (C'∙⇩sF{D} := e⇩2)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (C'∙⇩sF{D} := e⇩2)),ics)#frs,sh⇩1), err)"
using SFAss⇩1.prems(1) by clarsimp
have "P⇩1 ⊢ D sees F,Static:T in D" by(rule has_field_sees[OF has_field_idemp[OF SFAss⇩1.hyps(3)]])
then have field: "field P D F = (D,Static,T)" by simp
have IH: "PROP ?P e⇩2 h⇩0 ls⇩0 sh⇩0 (Val w) h⇩1 ls⇩1 sh⇩1 E C M pc ics w xa vs frs I" by fact
let ?pc = "pc + length(compE⇩2 e⇩2)"
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(w#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using IH Jcc_pieces_SFAss[OF pcs, where v'=w] pcs by simp
also have "P ⊢ … -jvm→ (None,h⇩1,(vs,ls⇩1,C,M,?pc+1,ics)#frs,sh⇩1')"
using SFAss⇩1.hyps(3-6) SFAss⇩1.prems(1) field by auto
also have "P ⊢ ... -jvm→ (None,h⇩1,(Unit#vs,ls⇩1,C,M,?pc+2,ics)#frs,sh⇩1')"
using SFAss⇩1 by auto
finally show ?case using pcs by auto
next
case (SFAssInit⇩1 e⇩2 h ls sh w h⇩1 ls⇩1 sh⇩1 C' F t D v' h' ls' sh' sfs i sfs' sh'')
let ?pc = "pc + length(compE⇩2 e⇩2)"
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh'' v xa (C'∙⇩sF{D}:=e⇩2)
= (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE⇩2 (C'∙⇩sF{D}:=e⇩2)),ics)#frs,sh''), err)"
using SFAssInit⇩1.prems(1) by clarsimp
have "Ex (WTrt2⇩1 P⇩1 E h⇩1 sh⇩1 (INIT D ([D],False) ← unit))"
using has_field_is_class'[OF SFAssInit⇩1.hyps(3)] by auto
then obtain err' where pcs':
"Jcc_pieces P⇩1 E C M h⇩1 (w#vs) ls⇩1 ?pc ics frs sh⇩1 I h' ls' sh' v' xa (INIT D ([D],False) ← unit)
= (True, (w#vs,ls⇩1,C,M,?pc,Calling D []) # frs,
(None,h',(w#vs,ls⇩1,C,M,?pc,Called [])#frs,sh'), err')"
using SFAssInit⇩1.prems(1) by simp
have ls: "ls⇩1 = ls'" by(rule init⇩1_same_loc[OF SFAssInit⇩1.hyps(5)])
have has: "P⇩1 ⊢ D has F,Static:t in D" by(rule has_field_idemp[OF SFAssInit⇩1.hyps(3)])
have "P⇩1 ⊢ D sees F,Static:t in D" by(rule has_field_sees[OF has])
then have field: "field P D F = (D,Static,t)" by simp
have IH: "PROP ?P e⇩2 h ls sh (Val w) h⇩1 ls⇩1 sh⇩1 E C M pc ics w xa vs frs I" by fact
have IHI: "PROP ?P (INIT D ([D],False) ← unit) h⇩1 ls⇩1 sh⇩1 (Val v')
h' ls' sh' E C M ?pc ics v' xa (w#vs) frs I" by fact
have "P ⊢ (None,h,frs',sh) -jvm→ (None,h⇩1,(w#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using IH Jcc_pieces_SFAss[OF pcs, where v'=w] by simp
also have "P ⊢ … -jvm→ (None,h⇩1,(w#vs,ls⇩1,C,M,?pc,Calling D [])#frs,sh⇩1)"
proof(cases "sh⇩1 D")
case None then show ?thesis using None SFAssInit⇩1.hyps(1,3-5,7-9) SFAssInit⇩1.prems field
by(cases ics, auto)
next
case (Some a)
then obtain sfs i where "a = (sfs,i)" by(cases a)
then show ?thesis using SFAssInit⇩1.hyps(1,3-5,7-9) SFAssInit⇩1.prems field Some
by(cases ics; case_tac i) auto
qed
also have "P ⊢ ... -jvm→ (None, h', (w#vs, ls⇩1, C, M, ?pc, Called []) # frs, sh')"
using IHI pcs' by clarsimp
also have "P ⊢ ... -jvm→ (None, h', (vs, ls⇩1, C, M, ?pc + 1, ics) # frs, sh'')"
using SFAssInit⇩1.hyps(1,3-5,7-9) SFAssInit⇩1.prems has field by(cases ics) auto
also have "P ⊢ ... -jvm→ (None, h', (Unit#vs, ls⇩1, C, M, ?pc + 2, ics) # frs, sh'')"
using SFAssInit⇩1.hyps(1,3-5,7-9) SFAssInit⇩1.prems has field by(cases ics) auto
finally show ?case using pcs ls by simp blast
next
case (SFAssInitThrow⇩1 e⇩2 h ls sh w h⇩1 ls⇩1 sh⇩1 C' F t D a h' ls' sh')
let ?pc = "pc + length(compE⇩2 e⇩2)"
obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (C'∙⇩sF{D}:=e⇩2)
= (True, frs', (None,h',(v#vs,ls',C,M,pc+size(compE⇩2 (C'∙⇩sF{D}:=e⇩2)),ics)#frs,sh'), err)"
using SFAssInitThrow⇩1.prems(1) by clarsimp
obtain a' where throw: "throw a = Throw a'" using eval⇩1_final[OF SFAssInitThrow⇩1.hyps(5)] by clarsimp
have "Ex (WTrt2⇩1 P⇩1 E h⇩1 sh⇩1 (INIT D ([D],False) ← unit))"
using has_field_is_class'[OF SFAssInitThrow⇩1.hyps(3)] by auto
then obtain vs' where pcs':
"Jcc_pieces P⇩1 E C M h⇩1 (w#vs) ls⇩1 ?pc ics frs sh⇩1 I h' ls' sh' v a' (INIT D ([D],False) ← unit)
= (True, (w#vs,ls⇩1,C,M,?pc,Calling D []) # frs, (None,h',(w#vs,ls⇩1,C,M,?pc,Called [])#frs,sh'),
P ⊢ (None,h⇩1,(w#vs,ls⇩1,C,M,?pc,Calling D []) # frs,sh⇩1)
-jvm→ handle P C M a' h' (vs'@w#vs) ls⇩1 ?pc ics frs sh')"
using SFAssInitThrow⇩1.prems(1) by simp blast
have ls: "ls⇩1 = ls'" by(rule init⇩1_same_loc[OF SFAssInitThrow⇩1.hyps(5)])
have has: "P⇩1 ⊢ D has F,Static:t in D" by(rule has_field_idemp[OF SFAssInitThrow⇩1.hyps(3)])
have "P⇩1 ⊢ D sees F,Static:t in D" by(rule has_field_sees[OF has])
then have field: "field P D F = (D,Static,t)" by simp
have IH: "PROP ?P e⇩2 h ls sh (Val w) h⇩1 ls⇩1 sh⇩1 E C M pc ics w xa vs frs I" by fact
have IHI: "PROP ?P (INIT D ([D],False) ← unit) h⇩1 ls⇩1 sh⇩1 (throw a)
h' ls' sh' E C M ?pc ics v a' (w#vs) frs I" by fact
have "P ⊢ (None,h,(vs, ls, C, M, pc, ics) # frs,sh) -jvm→ (None,h⇩1,(w#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using IH Jcc_pieces_SFAss[OF pcs, where v'=w] pcs by simp blast
also have "P ⊢ … -jvm→ (None,h⇩1,(w#vs,ls⇩1,C,M,?pc,Calling D [])#frs,sh⇩1)"
proof(cases "sh⇩1 D")
case None then show ?thesis using SFAssInitThrow⇩1.hyps(1,3,4,5) SFAssInitThrow⇩1.prems field
by(cases ics) auto
next
case (Some a)
then obtain sfs i where "a = (sfs,i)" by(cases a)
then show ?thesis using SFAssInitThrow⇩1.hyps(1,3,4,5) SFAssInitThrow⇩1.prems field Some
by(cases ics; case_tac i) auto
qed
also have "P ⊢ ... -jvm→ handle P C M a' h' (vs'@w#vs) ls⇩1 ?pc ics frs sh'"
using IHI pcs' throw by auto
finally show ?case using throw ls by(auto intro!: exI[where x = ?pc] exI[where x="vs'@[w]"])
next
case (SFAssThrow⇩1 e⇩2 h⇩0 ls⇩0 sh⇩0 e' h⇩1 ls⇩1 sh⇩1 C' F D)
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (C'∙⇩sF{D} := e⇩2)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (C'∙⇩sF{D} := e⇩2)),ics)#frs,sh⇩1), err)"
using SFAssThrow⇩1.prems(1) by clarsimp
have IH: "PROP ?P e⇩2 h⇩0 ls⇩0 sh⇩0 (throw e') h⇩1 ls⇩1 sh⇩1 E C M pc ics v xa vs frs I" by fact
show ?case using IH Jcc_pieces_SFAss[OF pcs, where v'=v] SFAssThrow⇩1.prems nsub_RI_Jcc_pieces
less_Suc_eq by auto
next
case (SFAssNone⇩1 e⇩2 h⇩0 ls⇩0 sh⇩0 w h⇩1 ls⇩1 sh⇩1 C' F D)
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (C'∙⇩sF{D} := e⇩2)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (C'∙⇩sF{D} := e⇩2)),ics)#frs,sh⇩1), err)"
using SFAssNone⇩1.prems(1) by clarsimp
have IH: "PROP ?P e⇩2 h⇩0 ls⇩0 sh⇩0 (Val w) h⇩1 ls⇩1 sh⇩1 E C M pc ics w xa vs frs I" by fact
let ?pc = "pc + length(compE⇩2 e⇩2)"
let ?xa = "addr_of_sys_xcpt NoSuchFieldError"
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(w#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using IH Jcc_pieces_SFAss[OF pcs, where v'=w] pcs by simp
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩1 (w#vs) ls⇩1 ?pc ics frs sh⇩1"
using SFAssNone⇩1 by(cases ics; clarsimp simp add: handle_def)
finally show ?case using pcs by (auto intro!: exI[where x = ?pc] exI[where x="[w]"])
next
case (SFAssNonStatic⇩1 e⇩2 h⇩0 ls⇩0 sh⇩0 w h⇩1 ls⇩1 sh⇩1 C' F T D)
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩1 ls⇩1 sh⇩1 v xa (C'∙⇩sF{D} := e⇩2)
= (True, frs', (None,h⇩1,(v#vs,ls⇩1,C,M,pc+size(compE⇩2 (C'∙⇩sF{D} := e⇩2)),ics)#frs,sh⇩1), err)"
using SFAssNonStatic⇩1.prems(1) by clarsimp
have IH: "PROP ?P e⇩2 h⇩0 ls⇩0 sh⇩0 (Val w) h⇩1 ls⇩1 sh⇩1 E C M pc ics w xa vs frs I" by fact
let ?pc = "pc + length(compE⇩2 e⇩2)"
let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError"
have "P⇩1 ⊢ D sees F,NonStatic:T in D"
by(rule has_field_sees[OF has_field_idemp[OF SFAssNonStatic⇩1.hyps(3)]])
then have field: "field P D F = (D,NonStatic,T)" by simp
have "P ⊢ (None,h⇩0,frs',sh⇩0) -jvm→ (None,h⇩1,(w#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using IH Jcc_pieces_SFAss[OF pcs, where v'=w] pcs by simp
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩1 (w#vs) ls⇩1 ?pc ics frs sh⇩1"
using SFAssNonStatic⇩1
proof(cases ics)
case No_ics
then show ?thesis using SFAssNonStatic⇩1 field
by (auto simp:split_beta handle_def simp del: split_paired_Ex)
qed(simp_all)
finally show ?case using pcs by (auto intro!: exI[where x = ?pc] exI[where x="[w]"])
next
case (Call⇩1 e h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 es pvs h⇩2 ls⇩2 sh⇩2 Ca fs M' Ts T body D ls⇩2' f h⇩3 ls⇩3 sh⇩3)
let ?frs⇩0 = "(vs, ls⇩0, C,M,pc,ics)#frs"
let ?σ⇩0 = "(None,h⇩0,?frs⇩0,sh⇩0)"
let ?pc⇩1 = "pc + length(compE⇩2 e)"
let ?σ⇩1 = "(None,h⇩1,(Addr a#vs, ls⇩1, C,M,?pc⇩1,ics)#frs,sh⇩1)"
let ?pc⇩2 = "?pc⇩1 + length(compEs⇩2 es)"
let ?frs⇩2 = "(rev pvs @ Addr a # vs, ls⇩2, C,M,?pc⇩2,ics)#frs"
let ?σ⇩2 = "(None,h⇩2,?frs⇩2,sh⇩2)"
let ?frs⇩2' = "([], ls⇩2', D,M',0,No_ics) # ?frs⇩2"
let ?σ⇩2' = "(None, h⇩2, ?frs⇩2', sh⇩2)"
have nclinit: "M' ≠ clinit" using wf_sees_clinit1[OF wf] visible_method_exists[OF Call⇩1.hyps(6)]
sees_method_idemp[OF Call⇩1.hyps(6)] by fastforce
have "P⇩1 ⊢⇩1 ⟨es,(h⇩1, ls⇩1, sh⇩1)⟩ [⇒] ⟨map Val pvs,(h⇩2, ls⇩2, sh⇩2)⟩" by fact
hence [simp]: "length es = length pvs" by(auto dest:evals⇩1_preserves_elen)
have invoke: "P,C,M,?pc⇩2 ▹ Invoke M' (length Ts)"
using Call⇩1.hyps(7) Call⇩1.prems(1) by clarsimp
have nsub: "¬ sub_RI body" by(rule sees_wf⇩1_nsub_RI[OF wf Call⇩1.hyps(6)])
obtain err where pcs:
"Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩3 ls⇩2 sh⇩3 v xa (e∙M'(es)) =
(True, ?frs⇩0, (None, h⇩3, (v#vs, ls⇩2, C,M,?pc⇩2+1,ics)#frs,sh⇩3), err)"
using Call⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) xa vs frs
(I - pcs (compxEs⇩2 es (pc + length (compE⇩2 e)) (Suc (length vs))))" by fact
have IH_es: "PROP ?Ps es h⇩1 ls⇩1 sh⇩1 (map Val pvs) h⇩2 ls⇩2 sh⇩2 C M ?pc⇩1 ics pvs xa
(map Val pvs) (Addr a#vs) frs (I - pcs(compxE⇩2 e pc (size vs)))" by fact
have "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1" using Jcc_pieces_Call1[OF pcs] IH by clarsimp
also have "P ⊢ … -jvm→ ?σ⇩2" using IH_es Call⇩1.prems by fastforce
also have "P ⊢ … -jvm→ ?σ⇩2'"
using jvm_Invoke[OF assms(1) invoke _ Call⇩1.hyps(6-8)] Call⇩1.hyps(5) Call⇩1.prems(1) by simp
finally have 1: "P ⊢ ?σ⇩0 -jvm→ ?σ⇩2'".
have "P⇩1 ⊢ Ca sees M',NonStatic: Ts→T = body in D" by fact
then have M'_in_D: "P⇩1 ⊢ D sees M',NonStatic: Ts→T = body in D"
by(rule sees_method_idemp)
have M'_code: "compP⇩2 P⇩1,D,M',0 ⊳ compE⇩2 body @ [Return]" using beforeM M'_in_D by simp
have M'_xtab: "compP⇩2 P⇩1,D,M' ⊳ compxE⇩2 body 0 0/{..<size(compE⇩2 body)},0"
using M'_in_D by(rule beforexM)
have IH_body: "PROP ?P body h⇩2 ls⇩2' sh⇩2 f h⇩3 ls⇩3 sh⇩3 (Class D # Ts) D M' 0 No_ics v xa [] ?frs⇩2
({..<size(compE⇩2 body)})" by fact
have cond: "Jcc_cond P⇩1 (Class D # Ts) D M' [] 0 No_ics {..<length (compE⇩2 body)} h⇩2 sh⇩2 body"
using nsub_RI_Jcc_pieces[OF assms(1) nsub] M'_code M'_xtab by clarsimp
show ?case (is "?Norm ∧ ?Err")
proof
show ?Norm (is "?val ⟶ ?trans")
proof
assume val: ?val
note 1
also have "P ⊢ ?σ⇩2' -jvm→ (None,h⇩3,([v],ls⇩3,D,M',size(compE⇩2 body),No_ics)#?frs⇩2,sh⇩3)"
using val IH_body Call⇩1.prems M'_code cond nsub_RI_Jcc_pieces nsub by auto
also have "P ⊢ … -jvm→ (None, h⇩3, (v#vs, ls⇩2, C,M,?pc⇩2+1,ics)#frs,sh⇩3)"
using Call⇩1.hyps(7) M'_code M'_in_D nclinit by(cases T, auto)
finally show ?trans by(simp add:add.assoc)
qed
next
show ?Err (is "?throw ⟶ ?err")
proof
assume throw: ?throw
with IH_body obtain pc⇩2 vs' where
pc⇩2: "0 ≤ pc⇩2 ∧ pc⇩2 < size(compE⇩2 body) ∧
¬ caught P pc⇩2 h⇩3 xa (compxE⇩2 body 0 0)" and
2: "P ⊢ ?σ⇩2' -jvm→ handle P D M' xa h⇩3 vs' ls⇩3 pc⇩2 No_ics ?frs⇩2 sh⇩3"
using Call⇩1.prems M'_code M'_xtab cond nsub_RI_Jcc_pieces nsub
by (auto simp del:split_paired_Ex)
have "handle P D M' xa h⇩3 vs' ls⇩3 pc⇩2 No_ics ?frs⇩2 sh⇩3 =
handle P C M xa h⇩3 (rev pvs @ Addr a # vs) ls⇩2 ?pc⇩2 ics frs sh⇩3"
using pc⇩2 M'_in_D nclinit by(auto simp add:handle_def)
then show "?err" using pc⇩2 jvm_trans[OF 1 2]
by(auto intro!:exI[where x="?pc⇩2"] exI[where x="rev pvs@[Addr a]"])
qed
qed
next
case (CallParamsThrow⇩1 e h⇩0 ls⇩0 sh⇩0 w h⇩1 ls⇩1 sh⇩1 es es' h⇩2 ls⇩2 sh⇩2 pvs ex es'' M')
let ?frs⇩0 = "(vs, ls⇩0, C,M,pc,ics)#frs"
let ?σ⇩0 = "(None,h⇩0,(vs, ls⇩0, C,M,pc,ics)#frs,sh⇩0)"
let ?pc⇩1 = "pc + length(compE⇩2 e)"
let ?σ⇩1 = "(None,h⇩1,(w # vs, ls⇩1, C,M,?pc⇩1,ics)#frs,sh⇩1)"
let ?pc⇩2 = "?pc⇩1 + length(compEs⇩2 es)"
obtain err where pcs:
"Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e∙M'(es)) =
(True, ?frs⇩0, (None, h⇩2, (v#vs, ls⇩2, C,M,?pc⇩2+1,ics)#frs,sh⇩2), err)"
using CallParamsThrow⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (Val w) h⇩1 ls⇩1 sh⇩1 E C M pc ics w xa vs frs
(I - pcs (compxEs⇩2 es (pc + length (compE⇩2 e)) (Suc (length vs))))" by fact
have 1: "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1" using Jcc_pieces_Call1[OF pcs] IH by clarsimp
have Isubs: "{?pc⇩1..<?pc⇩2} ⊆ I - pcs (compxE⇩2 e pc (length vs))"
using CallParamsThrow⇩1.prems by clarsimp
show ?case (is "?N ∧ (?eq ⟶ ?err)")
proof
show ?N by simp
next
{ assume ?eq
moreover
have "PROP ?Ps es h⇩1 ls⇩1 sh⇩1 es' h⇩2 ls⇩2 sh⇩2 C M ?pc⇩1 ics pvs xa es'' (w#vs) frs
(I - pcs (compxE⇩2 e pc (length vs)))" by fact
ultimately obtain vs' where "∃pc⇩2.
(?pc⇩1 ≤ pc⇩2 ∧ pc⇩2 < ?pc⇩1 + size(compEs⇩2 es) ∧
¬ caught P pc⇩2 h⇩2 xa (compxEs⇩2 es ?pc⇩1 (size vs + 1))) ∧
P ⊢ ?σ⇩1 -jvm→ handle P C M xa h⇩2 (vs'@w#vs) ls⇩2 pc⇩2 ics frs sh⇩2"
(is "∃pc⇩2. ?PC pc⇩2 ∧ ?Exec pc⇩2")
using CallParamsThrow⇩1 Isubs by auto
then obtain pc⇩2 where pc⇩2: "?PC pc⇩2" and 2: "?Exec pc⇩2" by iprover
then have "?err" using pc⇩2 jvm_trans[OF 1 2]
by(auto intro!: exI[where x="pc⇩2"] exI[where x="vs'@[w]"])
}
thus "?eq ⟶ ?err" by simp
qed
next
case (CallNull⇩1 e h⇩0 ls⇩0 sh⇩0 h⇩1 ls⇩1 sh⇩1 es pvs h⇩2 ls⇩2 sh⇩2 M')
have "P⇩1 ⊢⇩1 ⟨es,(h⇩1, ls⇩1, sh⇩1)⟩ [⇒] ⟨map Val pvs,(h⇩2, ls⇩2, sh⇩2)⟩" by fact
hence [simp]: "length es = length pvs" by(auto dest:evals⇩1_preserves_elen)
let ?frs⇩0 = "(vs, ls⇩0, C,M,pc,ics)#frs"
let ?pc⇩1 = "pc + length(compE⇩2 e)"
let ?pc⇩2 = "?pc⇩1 + length(compEs⇩2 es)"
let ?xa = "addr_of_sys_xcpt NullPointer"
obtain err where pcs:
"Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e∙M'(es)) =
(True, ?frs⇩0, (None, h⇩2, (v#vs, ls⇩2, C,M,?pc⇩2+1,ics)#frs,sh⇩2), err)"
using CallNull⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 null h⇩1 ls⇩1 sh⇩1 E C M pc ics Null xa vs frs
(I - pcs (compxEs⇩2 es (pc + length (compE⇩2 e)) (Suc (length vs))))" by fact
have IH_es: "PROP ?Ps es h⇩1 ls⇩1 sh⇩1 (map Val pvs) h⇩2 ls⇩2 sh⇩2 C M ?pc⇩1 ics pvs xa
(map Val pvs) (Null#vs) frs (I - pcs(compxE⇩2 e pc (size vs)))" by fact
have Isubs: "{pc + length (compE⇩2 e)..<pc + length (compE⇩2 e) + length (compEs⇩2 es)}
⊆ I - pcs (compxE⇩2 e pc (length vs))" using CallNull⇩1.prems by clarsimp
have "P ⊢ (None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0) -jvm→
(None,h⇩1,(Null#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
using Jcc_pieces_Call1[OF pcs] IH by clarsimp
also have "P ⊢ … -jvm→ (None,h⇩2,(rev pvs@Null#vs,ls⇩2,C,M,?pc⇩2,ics)#frs,sh⇩2)"
using CallNull⇩1 IH_es Isubs by auto
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩2 (rev pvs@Null#vs) ls⇩2 ?pc⇩2 ics frs sh⇩2"
using CallNull⇩1.prems
by(auto simp:split_beta handle_def nth_append simp del: split_paired_Ex)
finally show ?case by (auto intro!: exI[where x = ?pc⇩2] exI[where x="rev pvs@[Null]"])
next
case (CallObjThrow⇩1 e h ls sh e' h' ls' sh' M' es)
obtain err where pcs:
"Jcc_pieces P⇩1 E C M h vs ls pc ics frs sh I h' ls' sh' v xa (e∙M'(es)) =
(True, (vs, ls, C,M,pc,ics)#frs,
(None, h', (v#vs, ls', C,M,pc+size(compE⇩2 (e∙M'(es))),ics)#frs,sh'), err)"
using CallObjThrow⇩1.prems(1) by clarsimp
obtain a' where throw: "throw e' = Throw a'"
using eval⇩1_final[OF CallObjThrow⇩1.hyps(1)] by clarsimp
have IH: "PROP ?P e h ls sh (throw e') h' ls' sh' E C M pc ics v a' vs frs
(I - pcs (compxEs⇩2 es (pc + length (compE⇩2 e)) (Suc (length vs))))" by fact
show ?case using IH Jcc_pieces_Call1[OF pcs] throw CallObjThrow⇩1.prems nsub_RI_Jcc_pieces
by auto
next
case (CallNone⇩1 e h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 es pvs h⇩2 ls⇩2 sh⇩2 C' fs M')
let ?frs⇩0 = "(vs, ls⇩0, C,M,pc,ics)#frs"
let ?σ⇩0 = "(None,h⇩0,?frs⇩0,sh⇩0)"
let ?pc⇩1 = "pc + length(compE⇩2 e)"
let ?σ⇩1 = "(None,h⇩1,(Addr a#vs, ls⇩1, C,M,?pc⇩1,ics)#frs,sh⇩1)"
let ?pc⇩2 = "?pc⇩1 + length(compEs⇩2 es)"
let ?frs⇩2 = "(rev pvs @ Addr a # vs, ls⇩2, C,M,?pc⇩2,ics)#frs"
let ?σ⇩2 = "(None,h⇩2,?frs⇩2,sh⇩2)"
let ?xa = "addr_of_sys_xcpt NoSuchMethodError"
have "P⇩1 ⊢⇩1 ⟨es,(h⇩1, ls⇩1, sh⇩1)⟩ [⇒] ⟨map Val pvs,(h⇩2, ls⇩2, sh⇩2)⟩" by fact
hence [simp]: "length es = length pvs" by(auto dest:evals⇩1_preserves_elen)
have aux: "(rev pvs @ Addr a # vs) ! length pvs = Addr a"
by (metis length_rev nth_append_length)
have nmeth: "¬(∃b Ts T body D. P ⊢ C' sees M', b : Ts→T = body in D)"
using sees_method_compPD CallNone⇩1.hyps(6) by fastforce
obtain err where pcs:
"Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e∙M'(es)) =
(True, ?frs⇩0, (None, h⇩2, (v#vs, ls⇩2, C,M,?pc⇩2+1,ics)#frs,sh⇩2), err)"
using CallNone⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) xa vs frs
(I - pcs (compxEs⇩2 es (pc + length (compE⇩2 e)) (Suc (length vs))))" by fact
have IH_es: "PROP ?Ps es h⇩1 ls⇩1 sh⇩1 (map Val pvs) h⇩2 ls⇩2 sh⇩2 C M ?pc⇩1 ics pvs xa
(map Val pvs) (Addr a#vs) frs (I - pcs(compxE⇩2 e pc (size vs)))" by fact
have "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1" using Jcc_pieces_Call1[OF pcs] IH by clarsimp
also have "P ⊢ … -jvm→ ?σ⇩2" using IH_es CallNone⇩1.prems by fastforce
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩2 (rev pvs@Addr a#vs) ls⇩2 ?pc⇩2 ics frs sh⇩2"
using CallNone⇩1.hyps(5) CallNone⇩1.prems aux nmeth
by(cases "method P C' M'", cases "find_handler P ?xa h⇩2 frs sh⇩2", auto simp: handle_def)
finally show ?case using pcs by (auto intro!: exI[where x = ?pc⇩2] exI[where x="rev pvs@[Addr a]"])
next
case (CallStatic⇩1 e h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 es pvs h⇩2 ls⇩2 sh⇩2 C' fs M' Ts T body D)
let ?frs⇩0 = "(vs, ls⇩0, C,M,pc,ics)#frs"
let ?σ⇩0 = "(None,h⇩0,?frs⇩0,sh⇩0)"
let ?pc⇩1 = "pc + length(compE⇩2 e)"
let ?σ⇩1 = "(None,h⇩1,(Addr a#vs, ls⇩1, C,M,?pc⇩1,ics)#frs,sh⇩1)"
let ?pc⇩2 = "?pc⇩1 + length(compEs⇩2 es)"
let ?frs⇩2 = "(rev pvs @ Addr a # vs, ls⇩2, C,M,?pc⇩2,ics)#frs"
let ?σ⇩2 = "(None,h⇩2,?frs⇩2,sh⇩2)"
let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError"
have "P⇩1 ⊢⇩1 ⟨es,(h⇩1, ls⇩1, sh⇩1)⟩ [⇒] ⟨map Val pvs,(h⇩2, ls⇩2, sh⇩2)⟩" by fact
hence [simp]: "length es = length pvs" by(auto dest:evals⇩1_preserves_elen)
have aux: "(rev pvs @ Addr a # vs) ! length pvs = Addr a"
by (metis length_rev nth_append_length)
obtain body' where method: "P ⊢ C' sees M', Static : Ts→T = body' in D"
by (metis CallStatic⇩1.hyps(6) P_def compP⇩2_def sees_method_compP)
obtain err where pcs:
"Jcc_pieces P⇩1 E C M h⇩0 vs ls⇩0 pc ics frs sh⇩0 I h⇩2 ls⇩2 sh⇩2 v xa (e∙M'(es)) =
(True, ?frs⇩0, (None, h⇩2, (v#vs, ls⇩2, C,M,?pc⇩2+1,ics)#frs,sh⇩2), err)"
using CallStatic⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) xa vs frs
(I - pcs (compxEs⇩2 es (pc + length (compE⇩2 e)) (Suc (length vs))))" by fact
have IH_es: "PROP ?Ps es h⇩1 ls⇩1 sh⇩1 (map Val pvs) h⇩2 ls⇩2 sh⇩2 C M ?pc⇩1 ics pvs xa
(map Val pvs) (Addr a#vs) frs (I - pcs(compxE⇩2 e pc (size vs)))" by fact
have "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1" using Jcc_pieces_Call1[OF pcs] IH by clarsimp
also have "P ⊢ … -jvm→ ?σ⇩2" using IH_es CallStatic⇩1.prems by fastforce
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩2 (rev pvs@Addr a#vs) ls⇩2 ?pc⇩2 ics frs sh⇩2"
using CallStatic⇩1.hyps(5) CallStatic⇩1.prems aux method
by(cases "method P C' M'", cases "find_handler P ?xa h⇩2 frs sh⇩2")
(auto simp: handle_def; meson frames_of.cases)
finally show ?case using pcs by (auto intro!: exI[where x = ?pc⇩2] exI[where x="rev pvs@[Addr a]"])
next
case (SCallParamsThrow⇩1 es h⇩1 ls⇩1 sh⇩1 es' h⇩2 ls⇩2 sh⇩2 pvs ex es'' C' M')
show ?case
proof(cases "M' = clinit ∧ es = []")
case clinit: True then show ?thesis
using SCallParamsThrow⇩1.hyps(1,3) evals⇩1_cases(1) by fastforce
next
case nclinit: False
let ?σ⇩1 = "(None,h⇩1,(vs, ls⇩1, C,M,pc,ics)#frs,sh⇩1)"
let ?pc⇩2 = "pc + length(compEs⇩2 es)"
have Isubs: "{pc..<pc + length (compEs⇩2 es)} ⊆ I" using SCallParamsThrow⇩1.prems nclinit by clarsimp
show ?thesis (is "?N ∧ (?eq ⟶ ?err)")
proof
show ?N by simp
next
{ assume ?eq
moreover
have "PROP ?Ps es h⇩1 ls⇩1 sh⇩1 es' h⇩2 ls⇩2 sh⇩2 C M pc ics pvs xa es'' vs frs I" by fact
ultimately have "∃pc⇩2.
(pc ≤ pc⇩2 ∧ pc⇩2 < pc + size(compEs⇩2 es) ∧
¬ caught P pc⇩2 h⇩2 xa (compxEs⇩2 es pc (size vs))) ∧
(∃vs'. P ⊢ ?σ⇩1 -jvm→ handle P C M xa h⇩2 (vs'@vs) ls⇩2 pc⇩2 ics frs sh⇩2)"
(is "∃pc⇩2. ?PC pc⇩2 ∧ ?Exec pc⇩2")
using SCallParamsThrow⇩1 Isubs nclinit by auto
then obtain pc⇩2 where pc⇩2: "?PC pc⇩2" and 2: "?Exec pc⇩2" by iprover
then have "?err" using pc⇩2 2 by(auto intro: exI[where x="pc⇩2"])
}
thus "?eq ⟶ ?err" by iprover
qed
qed
next
case (SCallNone⇩1 es h⇩1 ls⇩1 sh⇩1 pvs h⇩2 ls⇩2 sh⇩2 C' M')
show ?case
proof(cases "M' = clinit ∧ es = []")
case clinit: True then show ?thesis using SCallNone⇩1.hyps(3) SCallNone⇩1.prems by auto
next
case nclinit: False
let ?σ⇩1 = "(None,h⇩1,(vs, ls⇩1, C,M,pc,ics)#frs,sh⇩1)"
let ?pc⇩2 = "pc + length(compEs⇩2 es)"
let ?frs⇩2 = "(rev pvs @ vs, ls⇩2, C,M,?pc⇩2,ics)#frs"
let ?σ⇩2 = "(None,h⇩2,?frs⇩2,sh⇩2)"
let ?xa = "addr_of_sys_xcpt NoSuchMethodError"
have "P⇩1 ⊢⇩1 ⟨es,(h⇩1, ls⇩1, sh⇩1)⟩ [⇒] ⟨map Val pvs,(h⇩2, ls⇩2, sh⇩2)⟩" by fact
hence [simp]: "length es = length pvs" by(auto dest:evals⇩1_preserves_elen)
have nmeth: "¬(∃b Ts T body D. P ⊢ C' sees M', b : Ts→T = body in D)"
using sees_method_compPD SCallNone⇩1.hyps(3) by fastforce
have IH_es: "PROP ?Ps es h⇩1 ls⇩1 sh⇩1 (map Val pvs) h⇩2 ls⇩2 sh⇩2 C M pc ics pvs xa
(map Val pvs) vs frs I" by fact
have "P ⊢ ?σ⇩1 -jvm→ ?σ⇩2" using IH_es SCallNone⇩1.prems nclinit by auto fastforce+
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩2 (rev pvs@vs) ls⇩2 ?pc⇩2 ics frs sh⇩2"
using SCallNone⇩1.prems nmeth nclinit
by(cases "method P C' M'", cases "find_handler P ?xa h⇩2 frs sh⇩2", auto simp: handle_def)
finally show ?thesis using nclinit by (auto intro: exI[where x = ?pc⇩2])
qed
next
case (SCallNonStatic⇩1 es h⇩1 ls⇩1 sh⇩1 pvs h⇩2 ls⇩2 sh⇩2 C' M' Ts T body D)
show ?case
proof(cases "M' = clinit ∧ es = []")
case clinit: True then show ?thesis
using SCallNonStatic⇩1.hyps(3) SCallNonStatic⇩1.prems sees_method_fun by fastforce
next
case nclinit: False
let ?σ⇩1 = "(None,h⇩1,(vs, ls⇩1, C,M,pc,ics)#frs,sh⇩1)"
let ?pc⇩2 = "pc + length(compEs⇩2 es)"
let ?frs⇩2 = "(rev pvs @ vs, ls⇩2, C,M,?pc⇩2,ics)#frs"
let ?σ⇩2 = "(None,h⇩2,?frs⇩2,sh⇩2)"
let ?xa = "addr_of_sys_xcpt IncompatibleClassChangeError"
have "P⇩1 ⊢⇩1 ⟨es,(h⇩1, ls⇩1, sh⇩1)⟩ [⇒] ⟨map Val pvs,(h⇩2, ls⇩2, sh⇩2)⟩" by fact
hence [simp]: "length es = length pvs" by(auto dest:evals⇩1_preserves_elen)
obtain body' where method: "P ⊢ C' sees M', NonStatic : Ts→T = body' in D"
by (metis SCallNonStatic⇩1.hyps(3) P_def compP⇩2_def sees_method_compP)
have IH_es: "PROP ?Ps es h⇩1 ls⇩1 sh⇩1 (map Val pvs) h⇩2 ls⇩2 sh⇩2 C M pc ics pvs xa
(map Val pvs) vs frs I" by fact
have "P ⊢ ?σ⇩1 -jvm→ ?σ⇩2" using IH_es SCallNonStatic⇩1.prems nclinit by auto fastforce+
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩2 (rev pvs@vs) ls⇩2 ?pc⇩2 ics frs sh⇩2"
using SCallNonStatic⇩1.prems method nclinit
by(cases "method P C' M'", cases "find_handler P ?xa h⇩2 frs sh⇩2")
(auto simp: handle_def; meson frames_of.cases)
finally show ?thesis using nclinit by (auto intro: exI[where x = ?pc⇩2])
qed
next
case (SCallInitThrow⇩1 es h⇩0 ls⇩0 sh⇩0 pvs h⇩1 ls⇩1 sh⇩1 C' M' Ts T body D a h⇩2 ls⇩2 sh⇩2)
show ?case
proof(cases "M' = clinit ∧ es = []")
case clinit: True then show ?thesis using SCallInitThrow⇩1 by simp
next
case nclinit: False
let ?σ⇩0 = "(None,h⇩0,(vs, ls⇩0, C,M,pc,ics)#frs,sh⇩0)"
let ?pc⇩1 = "pc + length(compEs⇩2 es)"
let ?frs⇩1 = "(rev pvs @ vs, ls⇩1, C,M,?pc⇩1,ics)#frs"
let ?σ⇩1 = "(None,h⇩1,?frs⇩1,sh⇩1)"
let ?frs⇩1' = "(rev pvs@vs,ls⇩1,C,M,?pc⇩1,Calling D [])#frs"
let ?σ⇩1' = "(None,h⇩1,?frs⇩1',sh⇩1)"
let ?frs⇩2 = "(rev pvs@vs,ls⇩1,C,M,?pc⇩1,Called [])#frs"
let ?σ⇩2 = "(None,h⇩2,?frs⇩2,sh⇩2)"
have ls: "ls⇩1 = ls⇩2" by(rule init⇩1_same_loc[OF SCallInitThrow⇩1.hyps(6)])
have method: "∃m'. P ⊢ C' sees M',Static:Ts→T = m' in D" using SCallInitThrow⇩1.hyps(3)
by (metis P_def compP⇩2_def sees_method_compP)
obtain a' where throw: "throw a = Throw a'" using eval⇩1_final[OF SCallInitThrow⇩1.hyps(6)] by clarsimp
have "Ex (WTrt2⇩1 P⇩1 E h⇩1 sh⇩1 (INIT D ([D],False) ← unit))"
using sees_method_is_class'[OF SCallInitThrow⇩1.hyps(3)] by auto
then obtain err' where pcs':
"Jcc_pieces P⇩1 E C M h⇩1 (rev pvs@vs) ls⇩1 ?pc⇩1 ics frs sh⇩1 I h⇩2 ls⇩2 sh⇩2 v xa (INIT D ([D],False) ← unit)
= (True, ?frs⇩1', (None,h⇩2,?frs⇩2,sh⇩2), err')"
using SCallInitThrow⇩1.prems(1) nclinit by auto
have IHI: "PROP ?P (INIT D ([D],False) ← unit) h⇩1 ls⇩1 sh⇩1 (throw a)
h⇩2 ls⇩2 sh⇩2 E C M ?pc⇩1 ics v a' (rev pvs@vs) frs I" by fact
have IH_es: "PROP ?Ps es h⇩0 ls⇩0 sh⇩0 (map Val pvs) h⇩1 ls⇩1 sh⇩1 C M pc ics pvs xa
(map Val pvs) vs frs I" by fact
have "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1" using IH_es SCallInitThrow⇩1.prems nclinit by auto fastforce+
also have "P ⊢ … -jvm→ ?σ⇩1'"
proof(cases "sh⇩1 D")
case None then show ?thesis using SCallInitThrow⇩1.hyps(1,3-6) SCallInitThrow⇩1.prems method
by(cases ics) auto
next
case (Some a)
then obtain sfs i where "a = (sfs,i)" by(cases a)
then show ?thesis using SCallInitThrow⇩1.hyps(1,3-6) SCallInitThrow⇩1.prems method Some
by(cases ics; case_tac i, auto)
qed
also obtain vs' where "P ⊢ … -jvm→ handle P C M a' h⇩2 (vs'@rev pvs@vs) ls⇩1 ?pc⇩1 ics frs sh⇩2"
using IHI pcs' throw by auto
finally show ?thesis using nclinit throw ls
by(auto intro!: exI[where x="?pc⇩1"] exI[where x="vs'@rev pvs"])
qed
next
case (SCallInit⇩1 es h⇩0 ls⇩0 sh⇩0 pvs h⇩1 ls⇩1 sh⇩1 C' M' Ts T body D v' h⇩2 ls⇩2 sh⇩2 ls⇩2' e' h⇩3 ls⇩3 sh⇩3)
show ?case
proof(cases "M' = clinit ∧ es = []")
case clinit: True then show ?thesis using SCallInit⇩1 by simp
next
case nclinit: False
let ?σ⇩0 = "(None,h⇩0,(vs, ls⇩0, C,M,pc,ics)#frs,sh⇩0)"
let ?pc⇩1 = "pc + length(compEs⇩2 es)"
let ?frs⇩1 = "(rev pvs @ vs, ls⇩1, C,M,?pc⇩1,ics)#frs"
let ?σ⇩1 = "(None,h⇩1,?frs⇩1,sh⇩1)"
let ?frs⇩1' = "(rev pvs@vs,ls⇩1,C,M,?pc⇩1,Calling D [])#frs"
let ?σ⇩1' = "(None,h⇩1,?frs⇩1',sh⇩1)"
let ?frs⇩2 = "(rev pvs@vs,ls⇩1,C,M,?pc⇩1,Called [])#frs"
let ?σ⇩2 = "(None,h⇩2,?frs⇩2,sh⇩2)"
let ?frs⇩2' = "([], ls⇩2', D,M',0,No_ics) # ?frs⇩1"
let ?σ⇩2' = "(None, h⇩2, ?frs⇩2', sh⇩2)"
have nclinit': "M' ≠ clinit" by fact
have ics: "ics = No_ics" using SCallInit⇩1.hyps(5) SCallInit⇩1.prems by simp
have "P⇩1 ⊢⇩1 ⟨es,(h⇩0, ls⇩0, sh⇩0)⟩ [⇒] ⟨map Val pvs,(h⇩1, ls⇩1, sh⇩1)⟩" by fact
hence [simp]: "length es = length pvs" by(auto dest:evals⇩1_preserves_elen)
have invoke: "P,C,M,?pc⇩1 ▹ Invokestatic C' M' (length Ts)"
using SCallInit⇩1.hyps(8) SCallInit⇩1.prems nclinit by(auto simp: add.assoc)
have nsub: "¬ sub_RI body" by(rule sees_wf⇩1_nsub_RI[OF wf SCallInit⇩1.hyps(3)])
have ls: "ls⇩1 = ls⇩2" by(rule init⇩1_same_loc[OF SCallInit⇩1.hyps(6)])
obtain sfs i where sh⇩2: "sh⇩2 D = Some(sfs,i)"
using init⇩1_Val_PD[OF SCallInit⇩1.hyps(6)] by clarsimp
have method: "∃m'. P ⊢ C' sees M',Static:Ts→T = m' in D" using SCallInit⇩1.hyps(3)
by (metis P_def compP⇩2_def sees_method_compP)
have "Ex (WTrt2⇩1 P⇩1 E h⇩1 sh⇩1 (INIT D ([D],False) ← unit))"
using sees_method_is_class'[OF SCallInit⇩1.hyps(3)] by auto
then obtain err' where pcs':
"Jcc_pieces P⇩1 E C M h⇩1 (rev pvs@vs) ls⇩1 ?pc⇩1 ics frs sh⇩1 I h⇩2 ls⇩2 sh⇩2 v' xa (INIT D ([D],False) ← unit)
= (True, ?frs⇩1', (None,h⇩2,?frs⇩2,sh⇩2), err')"
using SCallInit⇩1.prems(1) nclinit by auto
have IHI: "PROP ?P (INIT D ([D],False) ← unit) h⇩1 ls⇩1 sh⇩1 (Val v')
h⇩2 ls⇩2 sh⇩2 E C M ?pc⇩1 ics v' xa (rev pvs@vs) frs I" by fact
have IH_es: "PROP ?Ps es h⇩0 ls⇩0 sh⇩0 (map Val pvs) h⇩1 ls⇩1 sh⇩1 C M pc ics pvs xa
(map Val pvs) vs frs I" by fact
have "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1" using IH_es SCallInit⇩1.prems nclinit by auto fastforce+
also have "P ⊢ … -jvm→ ?σ⇩1'"
proof(cases "sh⇩1 D")
case None then show ?thesis using SCallInit⇩1.hyps(1,3-6,8-10) SCallInit⇩1.prems method
by(cases ics) auto
next
case (Some a)
then obtain sfs i where "a = (sfs,i)" by(cases a)
then show ?thesis using SCallInit⇩1.hyps(1,3-6,8-10) SCallInit⇩1.prems method Some
by(cases ics; case_tac i, auto)
qed
also have "P ⊢ … -jvm→ ?σ⇩2" using IHI pcs' by auto
also have "P ⊢ … -jvm→ ?σ⇩2'"
using jvm_Invokestatic_Called[OF assms(1) invoke _ SCallInit⇩1.hyps(3,8,9)] sh⇩2 ics by auto
finally have 1: "P ⊢ ?σ⇩0 -jvm→ ?σ⇩2'".
have "P⇩1 ⊢ C' sees M',Static: Ts→T = body in D" by fact
then have M'_in_D: "P⇩1 ⊢ D sees M',Static: Ts→T = body in D"
by(rule sees_method_idemp)
have M'_code: "compP⇩2 P⇩1,D,M',0 ⊳ compE⇩2 body @ [Return]" using beforeM M'_in_D by simp
have M'_xtab: "compP⇩2 P⇩1,D,M' ⊳ compxE⇩2 body 0 0/{..<size(compE⇩2 body)},0"
using M'_in_D by(rule beforexM)
have IH_body: "PROP ?P body h⇩2 ls⇩2' sh⇩2 e' h⇩3 ls⇩3 sh⇩3 (Class D # Ts) D M' 0 No_ics v xa [] ?frs⇩1
({..<size(compE⇩2 body)})" by fact
have cond: "Jcc_cond P⇩1 (Class D # Ts) D M' [] 0 No_ics {..<length (compE⇩2 body)} h⇩2 sh⇩2 body"
using nsub_RI_Jcc_pieces[OF assms(1) nsub] M'_code M'_xtab by clarsimp
show ?thesis (is "?Norm ∧ ?Err")
proof
show ?Norm (is "?val ⟶ ?trans")
proof
assume val: ?val
note 1
also have "P ⊢ ?σ⇩2' -jvm→ (None,h⇩3,([v],ls⇩3,D,M',size(compE⇩2 body),No_ics)#?frs⇩1,sh⇩3)"
using val IH_body SCallInit⇩1.prems M'_code cond nsub_RI_Jcc_pieces nsub by auto
also have "P ⊢ … -jvm→ (None, h⇩3, (v#vs, ls⇩2, C,M,?pc⇩1+1,ics)#frs,sh⇩3)"
using SCallInit⇩1.hyps(8) M'_code M'_in_D ls nclinit' by(cases T, auto)
finally show ?trans using nclinit by(auto simp:add.assoc)
qed
next
show ?Err (is "?throw ⟶ ?err")
proof
assume throw: ?throw
with IH_body obtain pc⇩2 vs' where
pc⇩2: "0 ≤ pc⇩2 ∧ pc⇩2 < size(compE⇩2 body) ∧
¬ caught P pc⇩2 h⇩3 xa (compxE⇩2 body 0 0)" and
2: "P ⊢ ?σ⇩2' -jvm→ handle P D M' xa h⇩3 vs' ls⇩3 pc⇩2 No_ics ?frs⇩1 sh⇩3"
using SCallInit⇩1.prems M'_code M'_xtab cond nsub_RI_Jcc_pieces nsub
by (auto simp del:split_paired_Ex)
have "handle P D M' xa h⇩3 vs' ls⇩3 pc⇩2 No_ics ?frs⇩1 sh⇩3 =
handle P C M xa h⇩3 (rev pvs @ vs) ls⇩2 ?pc⇩1 ics frs sh⇩3"
using pc⇩2 M'_in_D ls nclinit' by(auto simp add:handle_def)
then show "?err" using pc⇩2 jvm_trans[OF 1 2] nclinit
by(auto intro!:exI[where x="?pc⇩1"] exI[where x="rev pvs"])
qed
qed
qed
next
case (SCall⇩1 es h⇩1 ls⇩1 sh⇩1 pvs h⇩2 ls⇩2 sh⇩2 C' M' Ts T body D sfs ls⇩2' e' h⇩3 ls⇩3 sh⇩3)
show ?case
proof(cases "M' = clinit ∧ es = []")
case clinit: True
then have s1: "pvs = []" "h⇩1 = h⇩2" "ls⇩1 = ls⇩2" "sh⇩1 = sh⇩2"
using SCall⇩1.hyps(1) evals⇩1_cases(1) by blast+
then have ls⇩2': "ls⇩2' = replicate (max_vars body) undefined" using SCall⇩1.hyps(6) clinit by simp
let ?frs = "create_init_frame P C' # (vs, ls⇩1, C,M,pc,ics)#frs"
let ?σ⇩1 = "(None,h⇩1,?frs,sh⇩1)"
have method: "P⇩1 ⊢ C' sees clinit,Static: []→Void = body in C'"
using SCall⇩1.hyps(3) clinit s1(1) wf_sees_clinit[OF wf]
by (metis is_class_def option.collapse sees_method_fun sees_method_is_class)
then have M_code: "compP⇩2 P⇩1,C',clinit,0 ⊳ compE⇩2 body @ [Return]" by(rule beforeM)
have pcs: "Jcc_pieces P⇩1 E C M h⇩1 vs ls⇩1 pc ics frs sh⇩1 I h⇩3 ls⇩2 sh⇩3 v xa (C'∙⇩sclinit([]))
= (True, ?frs, (None, h⇩3, tl ?frs, sh⇩3(C'↦(fst(the(sh⇩3 C')),Done))),
P ⊢ (None, h⇩1, ?frs, sh⇩1) -jvm→
(case ics of
Called Cs ⇒ (None, h⇩3, (vs, ls⇩1, C, M, pc, Throwing Cs xa) # frs, sh⇩3(C' ↦ (fst (the (sh⇩3 C')), Error)))))"
using Jcc_pieces_clinit[OF assms(1),of E C M vs pc ics I h⇩1 sh⇩1 C' ls⇩1 frs h⇩3 ls⇩2 sh⇩3 v xa]
SCall⇩1.prems(1) clinit s1(1) by clarsimp
have IH_body: "PROP ?P body h⇩2 ls⇩2' sh⇩2 e' h⇩3 ls⇩3 sh⇩3 [] C' clinit 0 No_ics v xa [] (tl ?frs)
({..<size(compE⇩2 body)})" by fact
show ?thesis (is "?Norm ∧ ?Err")
proof
show ?Norm (is "?val ⟶ ?trans")
proof
assume val: ?val
then have "P ⊢ ?σ⇩1
-jvm→ (None, h⇩3, ([v], ls⇩3, C', clinit, size(compE⇩2 body), No_ics) # tl ?frs,sh⇩3)"
using IH_body Jcc_pieces_SCall_clinit_body[OF assms(1) wf pcs method] s1 ls⇩2' by clarsimp
also have "P ⊢ … -jvm→ (None, h⇩3, tl ?frs, sh⇩3(C'↦(fst(the(sh⇩3 C')),Done)))"
using jvm_Return_Init[OF M_code] by simp
finally show ?trans using pcs s1 clinit by simp
qed
next
show ?Err (is "?throw ⟶ ?err")
proof
assume throw: ?throw
with IH_body obtain pc⇩2 vs2 where
pc⇩2: "0 ≤ pc⇩2 ∧ pc⇩2 < size(compE⇩2 body) ∧
¬ caught P pc⇩2 h⇩3 xa (compxE⇩2 body 0 0)" and
2: "P ⊢ ?σ⇩1 -jvm→ handle P C' clinit xa h⇩3 vs2 ls⇩3 pc⇩2 No_ics (tl ?frs) sh⇩3"
using SCall⇩1.prems Jcc_pieces_SCall_clinit_body[OF assms(1) wf pcs method] s1 ls⇩2' by clarsimp
show ?err using SCall⇩1.prems(1) clinit
proof(cases ics)
case (Called Cs)
note 2
also have "handle P C' clinit xa h⇩3 vs2 ls⇩3 pc⇩2 No_ics (tl ?frs) sh⇩3
= (None, h⇩3, (vs, ls⇩1, C, M, pc, Throwing (C'#Cs) xa) # frs, sh⇩3)"
using Called pc⇩2 method by(simp add: handle_def)
also have "P ⊢ … -jvm→ (None, h⇩3, (vs, ls⇩1, C, M, pc, Throwing Cs xa) # frs,
sh⇩3(C' ↦ (fst (the (sh⇩3 C')), Error)))" using Called jvm_Throwing by simp
finally show ?thesis using pcs clinit Called by(clarsimp intro!: exI[where x="[]"])
qed(auto)
qed
qed
next
case nclinit: False
let ?σ⇩1 = "(None,h⇩1,(vs, ls⇩1, C,M,pc,ics)#frs,sh⇩1)"
let ?pc⇩2 = "pc + length(compEs⇩2 es)"
let ?frs⇩2 = "(rev pvs @ vs, ls⇩2, C,M,?pc⇩2,ics)#frs"
let ?σ⇩2 = "(None,h⇩2,?frs⇩2,sh⇩2)"
let ?frs⇩2' = "([], ls⇩2', D,M',0,No_ics) # ?frs⇩2"
let ?σ⇩2' = "(None, h⇩2, ?frs⇩2', sh⇩2)"
have nclinit': "M' ≠ clinit"
using wf_sees_clinit1[OF wf] visible_method_exists[OF SCall⇩1.hyps(3)]
sees_method_idemp[OF SCall⇩1.hyps(3)] nclinit SCall⇩1.hyps(5)
evals⇩1_preserves_elen[OF SCall⇩1.hyps(1)] by fastforce
have "P⇩1 ⊢⇩1 ⟨es,(h⇩1, ls⇩1, sh⇩1)⟩ [⇒] ⟨map Val pvs,(h⇩2, ls⇩2, sh⇩2)⟩" by fact
hence [simp]: "length es = length pvs" by(auto dest:evals⇩1_preserves_elen)
have invoke: "P,C,M,?pc⇩2 ▹ Invokestatic C' M' (length Ts)"
using SCall⇩1.hyps(5) SCall⇩1.prems nclinit by(auto simp: add.assoc)
have nsub: "¬ sub_RI body" by(rule sees_wf⇩1_nsub_RI[OF wf SCall⇩1.hyps(3)])
have IH_es: "PROP ?Ps es h⇩1 ls⇩1 sh⇩1 (map Val pvs) h⇩2 ls⇩2 sh⇩2 C M pc ics pvs xa
(map Val pvs) vs frs I" by fact
have "P ⊢ ?σ⇩1 -jvm→ ?σ⇩2" using IH_es SCall⇩1.prems nclinit by auto fastforce+
also have "P ⊢ … -jvm→ ?σ⇩2'" using jvm_Invokestatic[OF assms(1) invoke _ SCall⇩1.hyps(3,5,6)]
SCall⇩1.hyps(4) SCall⇩1.prems nclinit by auto
finally have 1: "P ⊢ ?σ⇩1 -jvm→ ?σ⇩2'".
have "P⇩1 ⊢ C' sees M',Static: Ts→T = body in D" by fact
then have M'_in_D: "P⇩1 ⊢ D sees M',Static: Ts→T = body in D"
by(rule sees_method_idemp)
have M'_code: "compP⇩2 P⇩1,D,M',0 ⊳ compE⇩2 body @ [Return]" using beforeM M'_in_D by simp
have M'_xtab: "compP⇩2 P⇩1,D,M' ⊳ compxE⇩2 body 0 0/{..<size(compE⇩2 body)},0"
using M'_in_D by(rule beforexM)
have IH_body: "PROP ?P body h⇩2 ls⇩2' sh⇩2 e' h⇩3 ls⇩3 sh⇩3 (Class D # Ts) D M' 0 No_ics v xa [] ?frs⇩2
({..<size(compE⇩2 body)})" by fact
have cond: "Jcc_cond P⇩1 (Class D # Ts) D M' [] 0 No_ics {..<length (compE⇩2 body)} h⇩2 sh⇩2 body"
using nsub_RI_Jcc_pieces[OF assms(1) nsub] M'_code M'_xtab by clarsimp
show ?thesis (is "?Norm ∧ ?Err")
proof
show ?Norm (is "?val ⟶ ?trans")
proof
assume val: ?val
note 1
also have "P ⊢ ?σ⇩2' -jvm→ (None,h⇩3,([v],ls⇩3,D,M',size(compE⇩2 body),No_ics)#?frs⇩2,sh⇩3)"
using val IH_body SCall⇩1.prems M'_code cond nsub_RI_Jcc_pieces nsub by auto
also have "P ⊢ … -jvm→ (None, h⇩3, (v#vs, ls⇩2, C,M,?pc⇩2+1,ics)#frs,sh⇩3)"
using SCall⇩1.hyps(5) M'_code M'_in_D nclinit' by(cases T, auto)
finally show ?trans using nclinit by(auto simp:add.assoc)
qed
next
show ?Err (is "?throw ⟶ ?err")
proof
assume throw: ?throw
with IH_body obtain pc⇩2 vs' where
pc⇩2: "0 ≤ pc⇩2 ∧ pc⇩2 < size(compE⇩2 body) ∧
¬ caught P pc⇩2 h⇩3 xa (compxE⇩2 body 0 0)" and
2: "P ⊢ ?σ⇩2' -jvm→ handle P D M' xa h⇩3 vs' ls⇩3 pc⇩2 No_ics ?frs⇩2 sh⇩3"
using SCall⇩1.prems M'_code M'_xtab cond nsub_RI_Jcc_pieces nsub
by (auto simp del:split_paired_Ex)
have "handle P D M' xa h⇩3 vs' ls⇩3 pc⇩2 No_ics ?frs⇩2 sh⇩3 =
handle P C M xa h⇩3 (rev pvs @ vs) ls⇩2 ?pc⇩2 ics frs sh⇩3"
using pc⇩2 M'_in_D nclinit' by(auto simp add:handle_def)
then show "?err" using pc⇩2 jvm_trans[OF 1 2] nclinit by(auto intro:exI[where x="?pc⇩2"])
qed
qed
qed
next
case Block⇩1 then show ?case using nsub_RI_Jcc_pieces by auto
next
case (Seq⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 w h⇩1 ls⇩1 sh⇩1 e⇩2 e⇩2' h⇩2 ls⇩2 sh⇩2)
let ?pc⇩1 = "pc + length(compE⇩2 e⇩1)"
let ?σ⇩0 = "(None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0)"
let ?σ⇩1 = "(None,h⇩1,(vs,ls⇩1,C,M,?pc⇩1+1,ics)#frs,sh⇩1)"
let ?I = "I - pcs (compxE⇩2 e⇩2 (Suc ?pc⇩1) (length vs))"
have Isub: "{pc..<pc + length (compE⇩2 e⇩1)} ⊆ ?I" using Seq⇩1.prems by clarsimp
have IH: "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 (Val w) h⇩1 ls⇩1 sh⇩1 E C M pc ics w xa vs frs ?I" by fact
have "P ⊢ ?σ⇩0 -jvm→ (None,h⇩1,(w#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
using Seq⇩1.prems nsub_RI_Jcc_pieces IH Isub by auto
also have "P ⊢ … -jvm→ ?σ⇩1" using Seq⇩1 by auto
finally have eval⇩1: "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1".
let ?pc⇩2 = "?pc⇩1 + 1 + length(compE⇩2 e⇩2)"
let ?I' = "I - pcs(compxE⇩2 e⇩1 pc (size vs))"
have IH⇩2: "PROP ?P e⇩2 h⇩1 ls⇩1 sh⇩1 e⇩2' h⇩2 ls⇩2 sh⇩2 E C M (?pc⇩1+1) ics v xa vs frs
?I'" by fact
have Isub2: "{Suc (pc + length (compE⇩2 e⇩1))..<Suc (pc + length (compE⇩2 e⇩1) + length (compE⇩2 e⇩2))}
⊆ ?I'" using Seq⇩1.prems by clarsimp
show ?case (is "?Norm ∧ ?Err")
proof
show ?Norm (is "?val ⟶ ?trans")
proof
assume val: ?val
note eval⇩1
also have "P ⊢ ?σ⇩1 -jvm→ (None,h⇩2,(v#vs,ls⇩2,C,M,?pc⇩2,ics)#frs,sh⇩2)"
using val Seq⇩1.prems nsub_RI_Jcc_pieces IH⇩2 Isub2 by auto
finally show ?trans by(simp add:add.assoc)
qed
next
show ?Err (is "?throw ⟶ ?err")
proof
assume throw: ?throw
then obtain pc⇩2 vs' where
pc⇩2: "?pc⇩1+1 ≤ pc⇩2 ∧ pc⇩2 < ?pc⇩2 ∧
¬ caught P pc⇩2 h⇩2 xa (compxE⇩2 e⇩2 (?pc⇩1+1) (size vs))" and
eval⇩2: "P ⊢ ?σ⇩1 -jvm→ handle P C M xa h⇩2 (vs'@vs) ls⇩2 pc⇩2 ics frs sh⇩2"
using IH⇩2 Seq⇩1.prems nsub_RI_Jcc_pieces Isub2 by auto
show "?err" using pc⇩2 jvm_trans[OF eval⇩1 eval⇩2] by(auto intro: exI[where x=pc⇩2])
qed
qed
next
case (SeqThrow⇩1 e⇩0 h⇩0 ls⇩0 sh⇩0 e h⇩1 ls⇩1 sh⇩1 e⇩1)
let ?I = "I - pcs (compxE⇩2 e⇩1 (Suc (pc + length (compE⇩2 e⇩0))) (length vs))"
obtain a' where throw: "throw e = Throw a'" using eval⇩1_final[OF SeqThrow⇩1.hyps(1)] by clarsimp
have Isub: "{pc..<pc + length (compE⇩2 e⇩0)} ⊆ ?I" using SeqThrow⇩1.prems by clarsimp
have "PROP ?P e⇩0 h⇩0 ls⇩0 sh⇩0 (throw e) h⇩1 ls⇩1 sh⇩1 E C M pc ics v a' vs frs ?I" by fact
then show ?case using SeqThrow⇩1.prems throw nsub_RI_Jcc_pieces Isub by auto
next
case (CondT⇩1 e h⇩0 ls⇩0 sh⇩0 h⇩1 ls⇩1 sh⇩1 e⇩1 e' h⇩2 ls⇩2 sh⇩2 e⇩2)
let ?pc⇩1 = "pc + length(compE⇩2 e)"
let ?σ⇩0 = "(None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0)"
let ?σ⇩1 = "(None,h⇩1,(vs,ls⇩1,C,M,?pc⇩1+1,ics)#frs,sh⇩1)"
let ?d = "size vs"
let ?xt⇩1 = "compxE⇩2 e⇩1 (pc+size(compE⇩2 e)+1) ?d"
let ?xt⇩2 = "compxE⇩2 e⇩2 (pc+size(compE⇩2 e)+size(compE⇩2 e⇩1)+2) ?d"
let ?I = "I - (pcs ?xt⇩1 ∪ pcs ?xt⇩2)"
have Isub: "{pc..<pc + length (compE⇩2 e)} ⊆ ?I" using CondT⇩1.prems by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 true h⇩1 ls⇩1 sh⇩1 E C M pc ics (Bool True) xa vs frs ?I" by fact
have "P ⊢ ?σ⇩0 -jvm→ (None,h⇩1,(Bool(True)#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
using CondT⇩1.prems nsub_RI_Jcc_pieces IH Isub by(auto simp: Int_Un_distrib)
also have "P ⊢ … -jvm→ ?σ⇩1" using CondT⇩1 by auto
finally have eval⇩1: "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1".
let ?pc⇩1' = "?pc⇩1 + 1 + length(compE⇩2 e⇩1)"
let ?pc⇩2' = "?pc⇩1' + 1 + length(compE⇩2 e⇩2)"
let ?I' = "I - pcs(compxE⇩2 e pc ?d) - pcs(compxE⇩2 e⇩2 (?pc⇩1'+1) ?d)"
have IH2: "PROP ?P e⇩1 h⇩1 ls⇩1 sh⇩1 e' h⇩2 ls⇩2 sh⇩2 E C M (?pc⇩1+1) ics v xa vs frs ?I'" by fact
show ?case (is "?Norm ∧ ?Err")
proof
show ?Norm (is "?val ⟶ ?trans")
proof
assume val: ?val
note eval⇩1
also have "P ⊢ ?σ⇩1 -jvm→ (None,h⇩2,(v#vs,ls⇩2,C,M,?pc⇩1',ics)#frs,sh⇩2)"
using val CondT⇩1.prems nsub_RI_Jcc_pieces IH2 by(fastforce simp:Int_Un_distrib)
also have "P ⊢ … -jvm→ (None,h⇩2,(v#vs,ls⇩2,C,M,?pc⇩2',ics)#frs,sh⇩2)"
using CondT⇩1 nsub_RI_Jcc_pieces by(auto simp:add.assoc)
finally show ?trans by(simp add:add.assoc)
qed
next
show ?Err (is "?throw ⟶ ?err")
proof
assume throw: ?throw
moreover
note IH2
ultimately obtain pc⇩2 vs' where
pc⇩2: "?pc⇩1+1 ≤ pc⇩2 ∧ pc⇩2 < ?pc⇩1' ∧
¬ caught P pc⇩2 h⇩2 xa (compxE⇩2 e⇩1 (?pc⇩1+1) (size vs))" and
eval⇩2: "P ⊢ ?σ⇩1 -jvm→ handle P C M xa h⇩2 (vs'@vs) ls⇩2 pc⇩2 ics frs sh⇩2"
using CondT⇩1.prems nsub_RI_Jcc_pieces by (fastforce simp:Int_Un_distrib)
show "?err" using pc⇩2 jvm_trans[OF eval⇩1 eval⇩2] by(auto intro: exI[where x=pc⇩2])
qed
qed
next
case (CondF⇩1 e h⇩0 ls⇩0 sh⇩0 h⇩1 ls⇩1 sh⇩1 e⇩2 e' h⇩2 ls⇩2 sh⇩2 e⇩1)
let ?pc⇩1 = "pc + length(compE⇩2 e)"
let ?pc⇩2 = "?pc⇩1 + 1 + length(compE⇩2 e⇩1)+ 1"
let ?pc⇩2' = "?pc⇩2 + length(compE⇩2 e⇩2)"
let ?σ⇩0 = "(None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0)"
let ?σ⇩1 = "(None,h⇩1,(vs,ls⇩1,C,M,?pc⇩2,ics)#frs,sh⇩1)"
let ?d = "size vs"
let ?xt⇩1 = "compxE⇩2 e⇩1 (pc+size(compE⇩2 e)+1) ?d"
let ?xt⇩2 = "compxE⇩2 e⇩2 (pc+size(compE⇩2 e)+size(compE⇩2 e⇩1)+2) ?d"
let ?I = "I - (pcs ?xt⇩1 ∪ pcs ?xt⇩2)"
let ?I' = "I - pcs(compxE⇩2 e pc ?d) - pcs(compxE⇩2 e⇩1 (?pc⇩1+1) ?d)"
have pcs: "pcs(compxE⇩2 e pc ?d) ∩ pcs(?xt⇩1 @ ?xt⇩2) = {}"
using CondF⇩1.prems by (simp add:Int_Un_distrib)
have Isub: "{pc..<pc + length (compE⇩2 e)} ⊆ ?I" using CondF⇩1.prems by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 false h⇩1 ls⇩1 sh⇩1 E C M pc ics (Bool False) xa vs frs ?I" by fact
have IH2: "PROP ?P e⇩2 h⇩1 ls⇩1 sh⇩1 e' h⇩2 ls⇩2 sh⇩2 E C M ?pc⇩2 ics v xa vs frs ?I'" by fact
have "P ⊢ ?σ⇩0 -jvm→ (None,h⇩1,(Bool(False)#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
using CondF⇩1.prems nsub_RI_Jcc_pieces IH Isub pcs by auto
also have "P ⊢ … -jvm→ ?σ⇩1" using CondF⇩1 by auto
finally have eval⇩1: "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1".
show ?case (is "?Norm ∧ ?Err")
proof
show ?Norm (is "?val ⟶ ?trans")
proof
assume val: ?val
note eval⇩1
also have "P ⊢ ?σ⇩1 -jvm→ (None,h⇩2,(v#vs,ls⇩2,C,M,?pc⇩2',ics)#frs,sh⇩2)"
using val CondF⇩1.prems nsub_RI_Jcc_pieces IH2 by(fastforce simp:Int_Un_distrib)
finally show ?trans by(simp add:add.assoc)
qed
next
show ?Err (is "?throw ⟶ ?err")
proof
let ?I' = "I - pcs(compxE⇩2 e pc ?d) - pcs(compxE⇩2 e⇩1 (?pc⇩1+1) ?d)"
assume throw: ?throw
then obtain pc⇩2 vs' where
pc⇩2: "?pc⇩2 ≤ pc⇩2 ∧ pc⇩2 < ?pc⇩2' ∧
¬ caught P pc⇩2 h⇩2 xa (compxE⇩2 e⇩2 ?pc⇩2 ?d)" and
eval⇩2: "P ⊢ ?σ⇩1 -jvm→ handle P C M xa h⇩2 (vs'@vs) ls⇩2 pc⇩2 ics frs sh⇩2"
using CondF⇩1.prems nsub_RI_Jcc_pieces IH2 by(fastforce simp:Int_Un_distrib)
show "?err" using pc⇩2 jvm_trans[OF eval⇩1 eval⇩2] by(auto intro: exI[where x=pc⇩2])
qed
qed
next
case (CondThrow⇩1 e h⇩0 ls⇩0 sh⇩0 f h⇩1 ls⇩1 sh⇩1 e⇩1 e⇩2)
let ?d = "size vs"
let ?xt⇩1 = "compxE⇩2 e⇩1 (pc+size(compE⇩2 e)+1) ?d"
let ?xt⇩2 = "compxE⇩2 e⇩2 (pc+size(compE⇩2 e)+size(compE⇩2 e⇩1)+2) ?d"
let ?I = "I - (pcs ?xt⇩1 ∪ pcs ?xt⇩2)"
have Isub: "{pc..<pc + length (compE⇩2 e)} ⊆ ?I" using CondThrow⇩1.prems by clarsimp
have "pcs(compxE⇩2 e pc ?d) ∩ pcs(?xt⇩1 @ ?xt⇩2) = {}"
using CondThrow⇩1.prems by (simp add:Int_Un_distrib)
moreover have "PROP ?P e h⇩0 ls⇩0 sh⇩0 (throw f) h⇩1 ls⇩1 sh⇩1 E C M pc ics v xa vs frs ?I" by fact
ultimately show ?case using CondThrow⇩1.prems nsub_RI_Jcc_pieces Isub by auto
next
case (WhileF⇩1 e h⇩0 ls⇩0 sh⇩0 h⇩1 ls⇩1 sh⇩1 c)
let ?pc = "pc + length(compE⇩2 e)"
let ?pc' = "?pc + length(compE⇩2 c) + 3"
have Isub: "{pc..<pc + length (compE⇩2 e)} ⊆ I - pcs (compxE⇩2 c (Suc (pc + length (compE⇩2 e))) (length vs))"
using WhileF⇩1.prems by clarsimp
have Isub2: "{Suc (pc + length (compE⇩2 e))..<Suc (pc + length (compE⇩2 e) + length (compE⇩2 c))}
⊆ I - pcs (compxE⇩2 e pc (length vs))" using WhileF⇩1.prems by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 false h⇩1 ls⇩1 sh⇩1 E C M pc ics (Bool False) xa vs frs
(I - pcs (compxE⇩2 c (Suc (pc + length (compE⇩2 e))) (length vs)))" by fact
have "P ⊢ (None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0) -jvm→
(None,h⇩1,(Bool False#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using WhileF⇩1.prems nsub_RI_Jcc_pieces IH Isub by auto
also have "P ⊢ … -jvm→ (None,h⇩1,(vs,ls⇩1,C,M,?pc',ics)#frs,sh⇩1)"
using WhileF⇩1 by (auto simp:add.assoc)
also have "P ⊢ … -jvm→ (None,h⇩1,(Unit#vs,ls⇩1,C,M,?pc'+1,ics)#frs,sh⇩1)"
using WhileF⇩1.prems by (auto simp:eval_nat_numeral)
finally show ?case by (simp add:add.assoc eval_nat_numeral)
next
case (WhileT⇩1 e h⇩0 ls⇩0 sh⇩0 h⇩1 ls⇩1 sh⇩1 c v⇩1 h⇩2 ls⇩2 sh⇩2 e⇩3 h⇩3 ls⇩3 sh⇩3)
let ?pc = "pc + length(compE⇩2 e)"
let ?pc' = "?pc + length(compE⇩2 c) + 1"
let ?σ⇩0 = "(None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0)"
let ?σ⇩2 = "(None,h⇩2,(vs,ls⇩2,C,M,pc,ics)#frs,sh⇩2)"
have Isub: "{pc..<pc + length (compE⇩2 e)} ⊆ I - pcs (compxE⇩2 c (Suc (pc + length (compE⇩2 e))) (length vs))"
using WhileT⇩1.prems by clarsimp
have Isub2: "{Suc (pc + length (compE⇩2 e))..<Suc (pc + length (compE⇩2 e) + length (compE⇩2 c))}
⊆ I - pcs (compxE⇩2 e pc (length vs))" using WhileT⇩1.prems by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 true h⇩1 ls⇩1 sh⇩1 E C M pc ics (Bool True) xa vs frs
(I - pcs (compxE⇩2 c (Suc (pc + length (compE⇩2 e))) (length vs)))" by fact
have IH2: "PROP ?P c h⇩1 ls⇩1 sh⇩1 (Val v⇩1) h⇩2 ls⇩2 sh⇩2 E C M (Suc ?pc) ics v⇩1 xa vs frs
(I - pcs (compxE⇩2 e pc (length vs)))" by fact
have "P ⊢ ?σ⇩0 -jvm→ (None,h⇩1,(Bool True#vs,ls⇩1,C,M,?pc,ics)#frs,sh⇩1)"
using WhileT⇩1.prems nsub_RI_Jcc_pieces IH Isub by auto
also have "P ⊢ … -jvm→ (None,h⇩1,(vs,ls⇩1,C,M,?pc+1,ics)#frs,sh⇩1)"
using WhileT⇩1.prems by auto
also have "P ⊢ … -jvm→ (None,h⇩2,(v⇩1#vs,ls⇩2,C,M,?pc',ics)#frs,sh⇩2)"
using WhileT⇩1.prems nsub_RI_Jcc_pieces IH2 Isub2 by auto
also have "P ⊢ … -jvm→ ?σ⇩2" using WhileT⇩1.prems by auto
finally have 1: "P ⊢ ?σ⇩0 -jvm→ ?σ⇩2".
show ?case (is "?Norm ∧ ?Err")
proof
show ?Norm (is "?val ⟶ ?trans")
proof
assume val: ?val
note 1
also have "P ⊢ ?σ⇩2 -jvm→ (None,h⇩3,(v#vs,ls⇩3,C,M,?pc'+3,ics)#frs,sh⇩3)"
using val WhileT⇩1 by (auto simp add:add.assoc eval_nat_numeral)
finally show ?trans by(simp add:add.assoc eval_nat_numeral)
qed
next
show ?Err (is "?throw ⟶ ?err")
proof
assume throw: ?throw
moreover
have "PROP ?P (while (e) c) h⇩2 ls⇩2 sh⇩2 e⇩3 h⇩3 ls⇩3 sh⇩3 E C M pc ics v xa vs frs I" by fact
ultimately obtain pc⇩2 vs' where
pc⇩2: "pc ≤ pc⇩2 ∧ pc⇩2 < ?pc'+3 ∧
¬ caught P pc⇩2 h⇩3 xa (compxE⇩2 (while (e) c) pc (size vs))" and
2: "P ⊢ ?σ⇩2 -jvm→ handle P C M xa h⇩3 (vs'@vs) ls⇩3 pc⇩2 ics frs sh⇩3"
using WhileT⇩1.prems by (auto simp:add.assoc eval_nat_numeral)
show "?err" using pc⇩2 jvm_trans[OF 1 2] by(auto intro: exI[where x=pc⇩2])
qed
qed
next
case (WhileCondThrow⇩1 e h ls sh e' h' ls' sh' c)
let ?I = "I - pcs (compxE⇩2 c (Suc (pc + length (compE⇩2 e))) (length vs))"
obtain a' where throw: "throw e' = Throw a'" using eval⇩1_final[OF WhileCondThrow⇩1.hyps(1)] by clarsimp
have Isub: "{pc..<pc + length (compE⇩2 e)} ⊆ ?I" using WhileCondThrow⇩1.prems by clarsimp
have "PROP ?P e h ls sh (throw e') h' ls' sh' E C M pc ics v a' vs frs ?I" by fact
then show ?case using WhileCondThrow⇩1.prems throw nsub_RI_Jcc_pieces Isub by auto
next
case (WhileBodyThrow⇩1 e h⇩0 ls⇩0 sh⇩0 h⇩1 ls⇩1 sh⇩1 c e' h⇩2 ls⇩2 sh⇩2)
let ?pc⇩1 = "pc + length(compE⇩2 e)"
let ?σ⇩0 = "(None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0)"
let ?σ⇩1 = "(None,h⇩1,(vs,ls⇩1,C,M,?pc⇩1+1,ics)#frs,sh⇩1)"
let ?I = "I - pcs (compxE⇩2 c (Suc (pc + length (compE⇩2 e))) (length vs))"
have Isub: "{pc..<pc + length (compE⇩2 e)} ⊆ ?I"
using WhileBodyThrow⇩1.prems by clarsimp
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 true h⇩1 ls⇩1 sh⇩1 E C M pc ics (Bool True) xa vs frs ?I" by fact
then have "P ⊢ ?σ⇩0 -jvm→ (None,h⇩1,(Bool(True)#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
using WhileBodyThrow⇩1.prems nsub_RI_Jcc_pieces Isub by auto
also have "P ⊢ … -jvm→ ?σ⇩1" using WhileBodyThrow⇩1 by auto
finally have eval⇩1: "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1".
let ?pc⇩1' = "?pc⇩1 + 1 + length(compE⇩2 c)"
show ?case (is "?Norm ∧ ?Err")
proof
show ?Norm by simp
next
show ?Err (is "?throw ⟶ ?err")
proof
assume throw: ?throw
moreover
have "PROP ?P c h⇩1 ls⇩1 sh⇩1 (throw e') h⇩2 ls⇩2 sh⇩2 E C M (?pc⇩1+1) ics v xa vs frs
(I - pcs (compxE⇩2 e pc (size vs)))" by fact
ultimately obtain pc⇩2 vs' where
pc⇩2: "?pc⇩1+1 ≤ pc⇩2 ∧ pc⇩2 < ?pc⇩1' ∧
¬ caught P pc⇩2 h⇩2 xa (compxE⇩2 c (?pc⇩1+1) (size vs))" and
eval⇩2: "P ⊢ ?σ⇩1 -jvm→ handle P C M xa h⇩2 (vs'@vs) ls⇩2 pc⇩2 ics frs sh⇩2"
using WhileBodyThrow⇩1.prems nsub_RI_Jcc_pieces by (fastforce simp:Int_Un_distrib)
show "?err" using pc⇩2 jvm_trans[OF eval⇩1 eval⇩2] by(auto intro: exI[where x=pc⇩2])
qed
qed
next
case (Throw⇩1 e h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1)
let ?pc = "pc + size(compE⇩2 e)"
have Isub: "{pc..<pc + length (compE⇩2 e)} ⊆ I" using Throw⇩1.prems by clarsimp
show ?case (is "?Norm ∧ ?Err")
proof
show ?Norm by simp
next
show ?Err (is "?throw ⟶ ?err")
proof
assume throw:?throw
have "PROP ?P e h⇩0 ls⇩0 sh⇩0 (addr a) h⇩1 ls⇩1 sh⇩1 E C M pc ics (Addr a) a vs frs I" by fact
then have "P ⊢ (None, h⇩0, (vs, ls⇩0, C, M, pc, ics) # frs, sh⇩0) -jvm→
(None, h⇩1, (Addr xa#vs, ls⇩1, C, M, ?pc, ics) # frs, sh⇩1)"
using Throw⇩1 nsub_RI_Jcc_pieces Isub throw by auto
also have "P ⊢ … -jvm→ handle P C M xa h⇩1 (Addr xa#vs) ls⇩1 ?pc ics frs sh⇩1"
using Throw⇩1.prems by(auto simp add:handle_def)
finally show "?err" by(auto intro!: exI[where x="?pc"] exI[where x="[Addr xa]"])
qed
qed
next
case (ThrowNull⇩1 e h⇩0 ls⇩0 sh⇩0 h⇩1 ls⇩1 sh⇩1)
let ?pc = "pc + size(compE⇩2 e)"
let ?xa = "addr_of_sys_xcpt NullPointer"
have Isub: "{pc..<pc + length (compE⇩2 e)} ⊆ I" using ThrowNull⇩1.prems by clarsimp
show ?case (is "?Norm ∧ ?Err")
proof
show ?Norm by simp
next
show ?Err (is "?throw ⟶ ?err")
proof
assume throw: ?throw
have "PROP ?P e h⇩0 ls⇩0 sh⇩0 null h⇩1 ls⇩1 sh⇩1 E C M pc ics Null xa vs frs I" by fact
then have "P ⊢ (None, h⇩0, (vs, ls⇩0, C, M, pc, ics) # frs, sh⇩0) -jvm→
(None, h⇩1, (Null#vs, ls⇩1, C, M, ?pc, ics) # frs, sh⇩1)"
using ThrowNull⇩1.prems nsub_RI_Jcc_pieces Isub by auto
also have "P ⊢ … -jvm→ handle P C M ?xa h⇩1 (Null#vs) ls⇩1 ?pc ics frs sh⇩1"
using ThrowNull⇩1.prems by(auto simp add:handle_def)
finally show "?err" using throw by(auto intro!: exI[where x="?pc"] exI[where x="[Null]"])
qed
qed
next
case (ThrowThrow⇩1 e h ls sh e' h' ls' sh')
obtain a' where throw: "throw e' = Throw a'" using eval⇩1_final[OF ThrowThrow⇩1.hyps(1)] by clarsimp
have Isub: "{pc..<pc + length (compE⇩2 e)} ⊆ I" using ThrowThrow⇩1.prems by clarsimp
have "PROP ?P e h ls sh (throw e') h' ls' sh' E C M pc ics v a' vs frs I" by fact
then show ?case using ThrowThrow⇩1.prems throw nsub_RI_Jcc_pieces Isub by auto
next
case (Try⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 v⇩1 h⇩1 ls⇩1 sh⇩1 Ci i e⇩2)
let ?pc⇩1 = "pc + length(compE⇩2 e⇩1)"
let ?pc⇩1' = "?pc⇩1 + 2 + length(compE⇩2 e⇩2)"
have "{pc..<pc+size(compE⇩2 (try e⇩1 catch(Ci i) e⇩2))} ⊆ I" using Try⇩1.prems by simp
also have "P,C,M ⊳ compxE⇩2 (try e⇩1 catch(Ci i) e⇩2) pc (size vs) / I,size vs"
using Try⇩1.prems by simp
ultimately have "P,C,M ⊳ compxE⇩2 e⇩1 pc (size vs) / {pc..<pc + length (compE⇩2 e⇩1)},size vs"
by(rule beforex_try)
hence "P ⊢ (None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0) -jvm→
(None,h⇩1,(v⇩1#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
using Try⇩1 nsub_RI_Jcc_pieces by auto blast
also have "P ⊢ … -jvm→ (None,h⇩1,(v⇩1#vs,ls⇩1,C,M,?pc⇩1',ics)#frs,sh⇩1)"
using Try⇩1.prems by auto
finally show ?case by (auto simp:add.assoc)
next
case (TryCatch⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 D fs Ci i e⇩2 e⇩2' h⇩2 ls⇩2 sh⇩2)
let ?e = "try e⇩1 catch(Ci i) e⇩2"
let ?xt = "compxE⇩2 ?e pc (size vs)"
let ?σ⇩0 = "(None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0)"
let ?ls⇩1 = "ls⇩1[i := Addr a]"
let ?pc⇩1 = "pc + length(compE⇩2 e⇩1)"
let ?pc⇩1' = "?pc⇩1 + 2"
let ?σ⇩1 = "(None,h⇩1,(vs,?ls⇩1,C,M, ?pc⇩1',ics) # frs,sh⇩1)"
have I: "{pc..<pc + length (compE⇩2 (try e⇩1 catch(Ci i) e⇩2))} ⊆ I"
and beforex: "P,C,M ⊳ ?xt/I,size vs" using TryCatch⇩1.prems by simp+
have "P ⊢ ?σ⇩0 -jvm→ (None,h⇩1,((Addr a)#vs,ls⇩1,C,M, ?pc⇩1+1,ics) # frs,sh⇩1)"
proof -
have ics: "ics = No_ics" using TryCatch⇩1.prems by auto
have "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 (Throw a) h⇩1 ls⇩1 sh⇩1 E C M pc ics v a vs frs {pc..<pc + length (compE⇩2 e⇩1)}"
by fact
moreover have "P,C,M ⊳ compxE⇩2 e⇩1 pc (size vs)/{pc..<?pc⇩1},size vs"
using beforex I pcs_subset by(force elim!: beforex_appendD1)
ultimately have
"∃pc⇩1. pc ≤ pc⇩1 ∧ pc⇩1 < ?pc⇩1 ∧
¬ caught P pc⇩1 h⇩1 a (compxE⇩2 e⇩1 pc (size vs)) ∧
(∃vs'. P ⊢ ?σ⇩0 -jvm→ handle P C M a h⇩1 (vs'@vs) ls⇩1 pc⇩1 ics frs sh⇩1)"
using TryCatch⇩1.prems nsub_RI_Jcc_pieces by auto
then obtain pc⇩1 vs' where
pc⇩1_in_e⇩1: "pc ≤ pc⇩1" "pc⇩1 < ?pc⇩1" and
pc⇩1_not_caught: "¬ caught P pc⇩1 h⇩1 a (compxE⇩2 e⇩1 pc (size vs))" and
0: "P ⊢ ?σ⇩0 -jvm→ handle P C M a h⇩1 (vs'@vs) ls⇩1 pc⇩1 ics frs sh⇩1" by iprover
from beforex obtain xt⇩0 xt⇩1
where ex_tab: "ex_table_of P C M = xt⇩0 @ ?xt @ xt⇩1"
and disj: "pcs xt⇩0 ∩ I = {}" by(auto simp:beforex_def)
have hp: "h⇩1 a = Some (D, fs)" "P⇩1 ⊢ D ≼⇧* Ci" by fact+
have "pc⇩1 ∉ pcs xt⇩0" using pc⇩1_in_e⇩1 I disj by auto
with pc⇩1_in_e⇩1 pc⇩1_not_caught hp
show ?thesis using ex_tab 0 ics by(simp add:handle_def matches_ex_entry_def)
qed
also have "P ⊢ … -jvm→ ?σ⇩1" using TryCatch⇩1 by auto
finally have 1: "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1" .
let ?pc⇩2 = "?pc⇩1' + length(compE⇩2 e⇩2)"
let ?I⇩2 = "{?pc⇩1' ..< ?pc⇩2}"
have "P,C,M ⊳ compxE⇩2 ?e pc (size vs) / I,size vs" by fact
hence beforex⇩2: "P,C,M ⊳ compxE⇩2 e⇩2 ?pc⇩1' (size vs) / ?I⇩2, size vs"
using I pcs_subset[of _ ?pc⇩1'] by(auto elim!:beforex_appendD2)
have IH⇩2: "PROP ?P e⇩2 h⇩1 ?ls⇩1 sh⇩1 e⇩2' h⇩2 ls⇩2 sh⇩2 E C M ?pc⇩1' ics v xa vs frs ?I⇩2" by fact
show ?case (is "?Norm ∧ ?Err")
proof
show ?Norm (is "?val ⟶ ?trans")
proof
assume val: ?val
note 1 also have "P ⊢ ?σ⇩1 -jvm→ (None,h⇩2,(v#vs,ls⇩2,C,M,?pc⇩2,ics)#frs,sh⇩2)"
using val beforex⇩2 IH⇩2 TryCatch⇩1.prems nsub_RI_Jcc_pieces by auto
finally show ?trans by(simp add:add.assoc)
qed
next
show ?Err (is "?throw ⟶ ?err")
proof
assume throw: ?throw
then obtain pc⇩2 vs' where
pc⇩2: "?pc⇩1+2 ≤ pc⇩2 ∧ pc⇩2 < ?pc⇩2 ∧
¬ caught P pc⇩2 h⇩2 xa (compxE⇩2 e⇩2 ?pc⇩1' (size vs))" and
2: "P ⊢ ?σ⇩1 -jvm→ handle P C M xa h⇩2 (vs'@vs) ls⇩2 pc⇩2 ics frs sh⇩2"
using IH⇩2 beforex⇩2 TryCatch⇩1.prems nsub_RI_Jcc_pieces by auto
show ?err using pc⇩2 jvm_trans[OF 1 2]
by (simp add:match_ex_entry) (auto intro: exI[where x=pc⇩2])
qed
qed
next
case (TryThrow⇩1 e⇩1 h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 D fs Ci i e⇩2)
let ?σ⇩0 = "(None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0)"
let ?pc⇩1 = "pc + length(compE⇩2 e⇩1)"
let ?e = "try e⇩1 catch(Ci i) e⇩2"
let ?xt = "compxE⇩2 ?e pc (size vs)"
have I: "{pc..<pc + length (compE⇩2 (try e⇩1 catch(Ci i) e⇩2))} ⊆ I"
and beforex: "P,C,M ⊳ ?xt/I,size vs" using TryThrow⇩1.prems by simp+
have "PROP ?P e⇩1 h⇩0 ls⇩0 sh⇩0 (Throw a) h⇩1 ls⇩1 sh⇩1 E C M pc ics v a vs frs
{pc..<pc + length (compE⇩2 e⇩1)}" by fact
moreover have "P,C,M ⊳ compxE⇩2 e⇩1 pc (size vs)/{pc..<?pc⇩1},size vs"
using beforex I pcs_subset by(force elim!: beforex_appendD1)
ultimately have
"∃pc⇩1. pc ≤ pc⇩1 ∧ pc⇩1 < ?pc⇩1 ∧
¬ caught P pc⇩1 h⇩1 a (compxE⇩2 e⇩1 pc (size vs)) ∧
(∃vs'. P ⊢ ?σ⇩0 -jvm→ handle P C M a h⇩1 (vs'@vs) ls⇩1 pc⇩1 ics frs sh⇩1)"
using TryThrow⇩1.prems nsub_RI_Jcc_pieces by auto
then obtain pc⇩1 vs' where
pc⇩1_in_e⇩1: "pc ≤ pc⇩1" "pc⇩1 < ?pc⇩1" and
pc⇩1_not_caught: "¬ caught P pc⇩1 h⇩1 a (compxE⇩2 e⇩1 pc (size vs))" and
0: "P ⊢ ?σ⇩0 -jvm→ handle P C M a h⇩1 (vs'@vs) ls⇩1 pc⇩1 ics frs sh⇩1" by iprover
show ?case (is "?N ∧ (?eq ⟶ ?err)")
proof
show ?N by simp
next
{ assume ?eq
with TryThrow⇩1 pc⇩1_in_e⇩1 pc⇩1_not_caught 0
have "?err" by (simp add:match_ex_entry) auto
}
thus "?eq ⟶ ?err" by iprover
qed
next
case Nil⇩1 thus ?case by simp
next
case (Cons⇩1 e h⇩0 ls⇩0 sh⇩0 v h⇩1 ls⇩1 sh⇩1 es fs h⇩2 ls⇩2 sh⇩2)
let ?pc⇩1 = "pc + length(compE⇩2 e)"
let ?σ⇩0 = "(None,h⇩0,(vs,ls⇩0,C,M,pc,ics)#frs,sh⇩0)"
let ?σ⇩1 = "(None,h⇩1,(v#vs,ls⇩1,C,M,?pc⇩1,ics)#frs,sh⇩1)"
have IH: "PROP ?P e h⇩0 ls⇩0 sh⇩0 (Val v) h⇩1 ls⇩1 sh⇩1 [] C M pc ics v xa vs frs
(I - pcs (compxEs⇩2 es ?pc⇩1 (Suc (length vs))))" by fact
then have 1: "P ⊢ ?σ⇩0 -jvm→ ?σ⇩1" using Jcc_pieces_Cons[OF _ Cons⇩1.prems(1-5)] by auto
let ?pc⇩2 = "?pc⇩1 + length(compEs⇩2 es)"
have IHs: "PROP ?Ps es h⇩1 ls⇩1 sh⇩1 fs h⇩2 ls⇩2 sh⇩2 C M ?pc⇩1 ics (tl ws) xa es' (v#vs) frs
(I - pcs (compxE⇩2 e pc (length vs)))" by fact
show ?case (is "?Norm ∧ ?Err")
proof
show ?Norm (is "?val ⟶ ?trans")
proof
assume val: ?val
note 1
also have "P ⊢ ?σ⇩1 -jvm→ (None,h⇩2,(rev(ws) @ vs,ls⇩2,C,M,?pc⇩2,ics)#frs,sh⇩2)"
using val IHs Cons⇩1.prems by fastforce
finally show ?trans by(simp add:add.assoc)
qed
next
show ?Err (is "?throw ⟶ (∃pc⇩2. ?H pc⇩2)")
proof
assume throw: ?throw
then obtain pc⇩2 vs' where
pc⇩2: "?pc⇩1 ≤ pc⇩2 ∧ pc⇩2 < ?pc⇩2 ∧
¬ caught P pc⇩2 h⇩2 xa (compxEs⇩2 es ?pc⇩1 (size vs + 1))" and
2: "P ⊢ ?σ⇩1 -jvm→ handle P C M xa h⇩2 (vs'@v#vs) ls⇩2 pc⇩2 ics frs sh⇩2"
using IHs Cons⇩1.prems by(fastforce simp:Cons_eq_append_conv neq_Nil_conv)
have "?H pc⇩2" using Cons⇩1.prems pc⇩2 jvm_trans[OF 1 2] by(auto intro!: exI[where x="vs'@[v]"])
thus "∃pc⇩2. ?H pc⇩2" by iprover
qed
qed
next
case (ConsThrow⇩1 e h⇩0 ls⇩0 sh⇩0 a h⇩1 ls⇩1 sh⇩1 es)
then show ?case using Jcc_pieces_Cons[OF _ ConsThrow⇩1.prems(1-5)]
by (fastforce simp:Cons_eq_append_conv)
next
case InitFinal⇩1 then show ?case using eval⇩1_final_same[OF InitFinal⇩1.hyps(1)] by clarsimp
next
case (InitNone⇩1 sh C⇩0 C' Cs e h l e' h' l' sh')
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa
(INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
using InitNone⇩1.prems(1) by clarsimp
let ?sh = "(sh(C⇩0 ↦ (sblank P⇩1 C⇩0, Prepared)))"
obtain ics: "ics_of(hd frs') = Calling C⇩0 Cs"
and frs⇩1: "frs' ≠ Nil" using pcs by clarsimp
then have 1: "P ⊢ (None,h,frs',sh) -jvm→ (None,h,frs',?sh)"
using InitNone⇩1 jvm_InitNone[where P = P] by(cases frs', simp+)
show ?case (is "(?e1 ⟶ ?jvm1) ∧ (?e2 ⟶ ?err)")
proof(rule conjI)
{ assume val: ?e1
note 1
also have "P ⊢ (None,h,frs',?sh) -jvm→ (None,h',(vs,l,C,M,pc,Called [])#frs,sh')"
using InitNone⇩1.hyps(3)[of E] Jcc_pieces_InitNone[OF assms(1) pcs] InitNone⇩1.prems val
by clarsimp
finally have ?jvm1 using pcs by simp
}
thus "?e1 ⟶ ?jvm1" by simp
next
{ assume throw: ?e2
note 1
also obtain vs' where "P ⊢ (None,h,frs',?sh)
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh'"
using InitNone⇩1.hyps(3)[of E] Jcc_pieces_InitNone[OF assms(1) pcs] throw
by clarsimp presburger
finally have ?err using pcs by auto
}
thus "?e2 ⟶ ?err" by simp
qed
next
case (InitDone⇩1 sh C⇩0 sfs C' Cs e h l e' h' l' sh')
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa
(INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
using InitDone⇩1.prems(1) by clarsimp
let ?frs' = "(calling_to_scalled (hd frs'))#(tl frs')"
have IH: "PROP ?P (INIT C' (Cs,True) ← e) h l sh e' h' l' sh' E C M pc ics v xa vs frs I"
by fact
obtain ics: "ics_of(hd frs') = Calling C⇩0 Cs"
and frs⇩1: "frs' ≠ Nil" using pcs by clarsimp
then have 1: "P ⊢ (None,h,frs',sh) -jvm→ (None,h,?frs',sh)"
using InitDone⇩1 jvm_InitDP[where P = P] by(cases frs', simp+)
show ?case (is "(?e1 ⟶ ?jvm1) ∧ (?e2 ⟶ ?err)")
proof(rule conjI)
{ assume val: ?e1
note 1
also have "P ⊢ (None,h,?frs',sh) -jvm→ (None,h',(vs,l,C,M,pc,Called [])#frs,sh')"
using IH Jcc_pieces_InitDP[OF assms(1) pcs] InitDone⇩1.prems val by clarsimp
finally have ?jvm1 using pcs by simp
}
thus "?e1 ⟶ ?jvm1" by simp
next
{ assume throw: ?e2
note 1
also obtain vs' where "P ⊢ (None,h,?frs',sh)
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh'"
using IH Jcc_pieces_InitDP[OF assms(1) pcs] InitDone⇩1.prems throw by clarsimp
finally have ?err using pcs by auto
}
thus "?e2 ⟶ ?err" by simp
qed
next
case (InitProcessing⇩1 sh C⇩0 sfs C' Cs e h l e' h' l' sh')
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa
(INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
using InitProcessing⇩1.prems(1) by clarsimp
let ?frs' = "(calling_to_scalled (hd frs'))#(tl frs')"
have IH: "PROP ?P (INIT C' (Cs,True) ← e) h l sh e' h' l' sh' E C M pc ics v xa vs frs I"
by fact
obtain ics: "ics_of(hd frs') = Calling C⇩0 Cs"
and frs⇩1: "frs' ≠ Nil" using pcs by clarsimp
then have 1: "P ⊢ (None,h,frs',sh) -jvm→ (None,h,?frs',sh)"
using InitProcessing⇩1 jvm_InitDP[where P = P] by(cases frs', simp+)
show ?case (is "(?e1 ⟶ ?jvm1) ∧ (?e2 ⟶ ?err)")
proof(rule conjI)
{ assume val: ?e1
note 1
also have "P ⊢ (None,h,?frs',sh) -jvm→ (None,h',(vs,l,C,M,pc,Called [])#frs,sh')"
using IH Jcc_pieces_InitDP[OF assms(1) pcs] InitProcessing⇩1.prems val by clarsimp
finally have ?jvm1 using pcs by simp
}
thus "?e1 ⟶ ?jvm1" by simp
next
{ assume throw: ?e2
note 1
also obtain vs' where "P ⊢ (None,h,?frs',sh)
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh'"
using IH Jcc_pieces_InitDP[OF assms(1) pcs] InitProcessing⇩1.prems throw by clarsimp
finally have ?err using pcs by auto
}
thus "?e2 ⟶ ?err" by simp
qed
next
case (InitError⇩1 sh C⇩0 sfs Cs e h l e' h' l' sh' C')
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa
(INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
using InitError⇩1.prems(1) by clarsimp
let ?e⇩0 = "THROW NoClassDefFoundError"
let ?frs' = "(calling_to_sthrowing (hd frs') (addr_of_sys_xcpt NoClassDefFoundError))#(tl frs')"
have IH: "PROP ?P (RI (C⇩0,?e⇩0) ; Cs ← e) h l sh e' h' l' sh' E C M pc ics v xa vs frs I" by fact
obtain ics: "ics_of(hd frs') = Calling C⇩0 Cs"
and frs⇩1: "frs' ≠ Nil"
and tl: "tl frs' = frs" using pcs by clarsimp
then have 1: "P ⊢ (None,h,frs',sh) -jvm→ (None,h,?frs',sh)"
proof(cases frs')
case (Cons a list)
obtain vs' l' C' M' pc' ics' where a: "a = (vs',l',C',M',pc',ics')" by(cases a)
then have "ics' = Calling C⇩0 Cs" using Cons ics by simp
then show ?thesis
using Cons a IH InitError⇩1.prems jvm_InitError[where P = P] InitError⇩1.hyps(1) by simp
qed(simp)
show ?case (is "(?e1 ⟶ ?jvm1) ∧ (?e2 ⟶ ?err)")
proof(rule conjI)
{ assume val: ?e1
then have False using val rinit⇩1_throw[OF InitError⇩1.hyps(2)] by blast
then have ?jvm1 using pcs by simp
}
thus "?e1 ⟶ ?jvm1" by simp
next
{ assume throw: ?e2
let ?frs = "(calling_to_throwing (hd frs') (addr_of_sys_xcpt NoClassDefFoundError))#(tl frs')"
have exec: "exec (P, (None,h,?frs,sh)) = Some (None,h,?frs',sh)"
using exec_ErrorThrowing[where sh=sh, OF InitError⇩1.hyps(1)] ics by(cases "hd frs'", simp)
obtain vs' where 2: "P ⊢ (None,h,?frs,sh) -jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh'"
using IH Jcc_pieces_InitError[OF assms(1) pcs InitError⇩1.hyps(1)] throw by clarsimp
have neq: "(None, h, ?frs, sh) ≠ handle P C M xa h' (vs' @ vs) l pc ics frs sh'"
using tl ics by(cases "hd frs'", simp add: handle_frs_tl_neq)
note 1
also have "P ⊢ (None,h,?frs',sh) -jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh'"
using exec_1_exec_all_conf[OF exec 2] neq by simp
finally have ?err using pcs by auto
}
thus "?e2 ⟶ ?err" by simp
qed
next
case (InitObject⇩1 sh C⇩0 sfs sh' C' Cs e h l e' h' l' sh'')
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l'
(sh(C⇩0 ↦ (sfs, Processing))) v xa (INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
using InitObject⇩1.prems(1) by clarsimp
let ?frs' = "(calling_to_called (hd frs'))#(tl frs')"
have IH: "PROP ?P (INIT C' (C⇩0#Cs,True) ← e) h l sh' e' h' l' sh'' E C M pc ics v xa vs frs I"
by fact
obtain ics: "ics_of(hd frs') = Calling C⇩0 Cs"
and frs⇩1: "frs' ≠ Nil" using pcs by clarsimp
then have 1: "P ⊢ (None,h,frs',sh) -jvm→ (None,h,?frs',sh')"
proof(cases frs')
case (Cons a list)
obtain vs' l' C' M' pc' ics' where a: "a = (vs',l',C',M',pc',ics')" by(cases a)
then have "ics' = Calling C⇩0 Cs" using Cons ics by simp
then show ?thesis
using Cons Nil a IH InitObject⇩1 jvm_InitObj[where P = P] by simp
qed(simp)
show ?case (is "(?e1 ⟶ ?jvm1) ∧ (?e2 ⟶ ?err)")
proof(rule conjI)
{ assume val: ?e1
note 1
also have "P ⊢ (None,h,?frs',sh') -jvm→ (None,h',(vs,l,C,M,pc,Called [])#frs,sh'')"
using IH Jcc_pieces_InitObj[OF assms(1) pcs] InitObject⇩1 val by simp
finally have ?jvm1 using pcs by simp
}
thus "?e1 ⟶ ?jvm1" by simp
next
{ assume throw: ?e2
note 1
also obtain vs' where "P ⊢ (None,h,?frs',sh')
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh''"
using IH Jcc_pieces_InitObj[OF assms(1) pcs] InitObject⇩1 throw by clarsimp
finally have ?err using pcs by auto
}
thus "?e2 ⟶ ?err" by simp
qed
next
case (InitNonObject⇩1 sh C⇩0 sfs D a b sh' C' Cs e h l e' h' l' sh'')
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l'
(sh(C⇩0 ↦ (sfs,Processing))) v xa (INIT C' (C⇩0 # Cs,False) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
using InitNonObject⇩1.prems(1) by clarsimp
let ?frs' = "(calling_to_calling (hd frs') D)#(tl frs')"
have cls1: "is_class P⇩1 D" using InitNonObject⇩1.hyps(2,3) class_wf wf wf_cdecl_supD by blast
have cls_aux: "distinct (C⇩0#Cs) ∧ supercls_lst P⇩1 (C⇩0#Cs)" using InitNonObject⇩1.prems(1) by auto
then have cls2: "D ∉ set (C⇩0 # Cs)"
proof -
have "distinct (D # C⇩0 # Cs)"
using InitNonObject⇩1.hyps(2,3) cls_aux wf wf_supercls_distinct_app by blast
then show "D ∉ set (C⇩0 # Cs)"
by (metis distinct.simps(2))
qed
have cls3: "∀C∈set (C⇩0 # Cs). P⇩1 ⊢ C ≼⇧* D" using InitNonObject⇩1.hyps(2,3) cls_aux
by (metis r_into_rtrancl rtrancl_into_rtrancl set_ConsD subcls1.subcls1I supercls_lst.simps(1))
have IH: "PROP ?P (INIT C' (D # C⇩0 # Cs,False) ← e) h l sh' e' h' l' sh'' E C M pc ics v xa vs frs I"
by fact
obtain r where cls: "class P C⇩0 = ⌊(D, r)⌋" using InitNonObject⇩1.hyps(3)
by (metis assms class_compP compP⇩2_def)
obtain ics: "ics_of(hd frs') = Calling C⇩0 Cs"
and frs⇩1: "frs' ≠ Nil" using pcs by clarsimp
then have 1: "P ⊢ (None,h,frs',sh) -jvm→ (None,h,?frs',sh')"
proof(cases frs')
case (Cons a list)
obtain vs' l' C' M' pc' ics' where a: "a = (vs',l',C',M',pc',ics')" by(cases a)
then have "ics' = Calling C⇩0 Cs" using Cons ics by simp
then show ?thesis
using Cons a IH InitNonObject⇩1 jvm_InitNonObj[OF _ _ cls] by simp
qed(simp)
show ?case (is "(?e1 ⟶ ?jvm1) ∧ (?e2 ⟶ ?err)")
proof(rule conjI)
{ assume val: ?e1
note 1
also have "P ⊢ (None,h,?frs',sh') -jvm→ (None,h',(vs,l,C,M,pc,Called [])#frs,sh'')"
using IH Jcc_pieces_InitNonObj[OF assms(1) cls1 cls2 cls3 pcs] InitNonObject⇩1 val by simp
finally have ?jvm1 using pcs by simp
}
thus "?e1 ⟶ ?jvm1" by simp
next
{ assume throw: ?e2
note 1
also obtain vs' where "P ⊢ (None,h,?frs',sh')
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh''"
using IH Jcc_pieces_InitNonObj[OF assms(1) cls1 cls2 cls3 pcs] InitNonObject⇩1 throw by clarsimp
finally have ?err using pcs by auto
}
thus "?e2 ⟶ ?err" by simp
qed
next
case (InitRInit⇩1 C⇩0 Cs e h l sh e' h' l' sh' C')
then obtain frs' err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh' v xa
(INIT C' (C⇩0 # Cs,True) ← e)
= (True, frs', (None, h', (vs, l, C, M, pc, Called []) # frs, sh'), err)"
using InitRInit⇩1.prems(1) by clarsimp
have IH: "PROP ?P (RI (C⇩0,C⇩0∙⇩sclinit([])) ; Cs ← e) h l sh e' h' l' sh' E C M pc ics v xa vs frs I"
by fact
show ?case (is "(?e1 ⟶ ?jvm1) ∧ (?e2 ⟶ ?err)")
proof(rule conjI)
{ assume val: ?e1
have "P ⊢ (None,h,frs',sh) -jvm→ (None,h',(vs,l,C,M,pc,Called [])#frs,sh')"
using IH Jcc_pieces_InitRInit[OF assms(1,2) pcs] InitRInit⇩1.prems val by simp
then have ?jvm1 using pcs by simp
}
thus "?e1 ⟶ ?jvm1" by simp
next
{ assume throw: ?e2
obtain vs' where "P ⊢ (None,h,frs',sh)
-jvm→ handle P C M xa h' (vs'@vs) l pc ics frs sh'"
using IH Jcc_pieces_InitRInit[OF assms(1,2) pcs] InitRInit⇩1 throw by clarsimp
then have ?err using pcs by auto
}
thus "?e2 ⟶ ?err" by simp
qed
next
case (RInit⇩1 e h l sh v1 h' l' sh' C⇩0 sfs i sh'' C' Cs e' e⇩1 h⇩1 l⇩1 sh⇩1)
let ?frs = "(vs,l,C,M,pc,Called (C⇩0#Cs)) # frs"
let ?frs' = "(vs,l,C,M,pc,Called Cs) # frs"
have clinit: "e = C⇩0∙⇩sclinit([])" using RInit⇩1
by (metis Jcc_cond.simps(2) eval⇩1_final_same exp.distinct(101) final_def)
then obtain err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h⇩1 l⇩1 sh⇩1 v xa
(RI (C⇩0,C⇩0∙⇩sclinit([])) ; Cs ← e')
= (True, ?frs, (None, h⇩1, (vs, l, C, M, pc, Called []) # frs, sh⇩1), err)"
using RInit⇩1.prems(1) by simp
have shC: "∀C'∈set Cs. ∃sfs. sh C' = ⌊(sfs, Processing)⌋" using RInit⇩1.prems(1) clinit by clarsimp
then have shC'': "∀C'∈set Cs. ∃sfs. sh'' C' = ⌊(sfs, Processing)⌋"
using clinit⇩1_proc_pres[OF wf] RInit⇩1.hyps(1) clinit RInit⇩1.hyps(4) RInit⇩1.prems(1)
by (auto simp: fun_upd_apply)
have loc: "l = l'" using clinit⇩1_loc_pres RInit⇩1.hyps(1) clinit by simp
have IH: "PROP ?P e h l sh (Val v1) h' l' sh' E C M pc (Called Cs) v1 xa vs (tl ?frs') I" by fact
then have IH':
"PROP ?P (C⇩0∙⇩sclinit([])) h l sh (Val v1) h' l' sh' E C M pc (Called Cs) v1 xa vs (tl ?frs') I"
using clinit by simp
have IH2: "PROP ?P (INIT C' (Cs,True) ← e') h' l' sh'' e⇩1 h⇩1 l⇩1 sh⇩1 E C M
pc ics v xa vs frs I" by fact
have "P ⊢ (None,h,?frs,sh) -jvm→ (None,h,create_init_frame P C⇩0 # ?frs',sh)" by(rule jvm_Called)
also have "P ⊢ … -jvm→ (None,h',?frs',sh'')"
using IH' Jcc_pieces_RInit_clinit[OF assms(1-2) pcs,of h' l' sh'] RInit⇩1.hyps(3,4) by simp
finally have jvm1: "P ⊢ (None,h,?frs,sh) -jvm→ (None,h',?frs',sh'')" .
show ?case (is "(?e1 ⟶ ?jvm1) ∧ (?e2 ⟶ ?err)")
proof(rule conjI)
{ assume val: ?e1
note jvm1
also have "P ⊢ (None,h',?frs',sh'') -jvm→ (None,h⇩1,(vs,l,C,M,pc,Called [])#frs,sh⇩1)"
using IH2 Jcc_pieces_RInit_Init[OF assms(1-2) shC'' pcs,of h'] RInit⇩1.hyps(5) loc val by auto
finally have ?jvm1 using pcs clinit by simp
}
thus "?e1 ⟶ ?jvm1" by simp
next
{ assume throw: ?e2
note jvm1
also obtain vs' where "P ⊢ (None,h',?frs',sh'')
-jvm→ handle P C M xa h⇩1 (vs'@vs) l pc ics frs sh⇩1"
using IH2 Jcc_pieces_RInit_Init[OF assms(1-2) shC'' pcs,of h'] RInit⇩1.hyps(5) loc throw by auto
finally have ?err using pcs clinit by auto
}
thus "?e2 ⟶ ?err" by simp
qed
next
case (RInitInitFail⇩1 e h l sh a h' l' sh' C⇩0 sfs i sh'' D Cs e' e⇩1 h⇩1 l⇩1 sh⇩1)
let ?frs = "(vs,l,C,M,pc,Called (C⇩0#D#Cs)) # frs"
let ?frs' = "(vs,l,C,M,pc,Called (D#Cs)) # frs"
let "?frsT" = "λxa1. (vs,l,C,M,pc,Throwing (C⇩0#D#Cs) xa1) # frs"
let "?frsT'" = "λxa1. (vs,l,C,M,pc,Throwing (D#Cs) xa1) # frs"
obtain xa' where xa': "throw a = Throw xa'"
by (metis RInitInitFail⇩1.hyps(1) eval⇩1_final exp.distinct(101) final_def)
have e⇩1: "e⇩1 = Throw xa'" using xa' rinit⇩1_throw RInitInitFail⇩1.hyps(5) by simp
show ?case
proof(cases "e = C⇩0∙⇩sclinit([])")
case clinit: True
then obtain err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h⇩1 l⇩1 sh⇩1 v xa'
(RI (C⇩0,C⇩0∙⇩sclinit([])) ; D # Cs ← e')
= (True, ?frs, (None, h⇩1, (vs, l, C, M, pc, Called []) # frs, sh⇩1), err)"
using RInitInitFail⇩1.prems(1) by simp
have loc: "l = l'" using clinit⇩1_loc_pres RInitInitFail⇩1.hyps(1) clinit by simp
have IH: "PROP ?P e h l sh (throw a) h' l' sh' E C M pc (Called (D#Cs)) v xa' vs frs I"
by fact
then have IH':
"PROP ?P (C⇩0∙⇩sclinit([])) h l sh (Throw xa') h' l' sh' E C M pc (Called (D#Cs)) v xa' vs
frs I" using clinit xa' by simp
have IH2: "PROP ?P (RI (D,throw a) ; Cs ← e') h' l' sh'' e⇩1 h⇩1 l⇩1 sh⇩1 E C M
pc ics v xa' vs frs I" by fact
have "P ⊢ (None,h,?frs,sh) -jvm→ (None,h,create_init_frame P C⇩0 # ?frs',sh)" by(rule jvm_Called)
also have "P ⊢ … -jvm→ (None,h',(vs, l, C, M, pc, Throwing (D#Cs) xa') # frs,sh'')"
using IH' Jcc_pieces_RInit_clinit[OF assms(1-2) pcs,of h' l' sh'] RInitInitFail⇩1.hyps(3,4)
by simp
also obtain vs'' where "P ⊢ … -jvm→ handle P C M xa' h⇩1 (vs''@vs) l pc ics frs sh⇩1"
using IH2 pcs Jcc_pieces_RInit_RInit[OF assms(1) pcs] RInitInitFail⇩1.hyps(3,4)
xa' loc e⇩1 xa' by clarsimp
finally show ?thesis using pcs e⇩1 clinit by auto
next
case throw: False
then have eT: "e = Throw xa'" "h = h'" "l = l'" "sh = sh'" using xa' RInitInitFail⇩1.prems(1)
eval⇩1_final_same[OF RInitInitFail⇩1.hyps(1)] by clarsimp+
obtain a' where "class P⇩1 C⇩0 = ⌊a'⌋" using RInitInitFail⇩1.prems by(auto simp: is_class_def)
then obtain stk' loc' M' pc' ics' where "create_init_frame P C⇩0 = (stk',loc',C⇩0,M',pc',ics')"
using create_init_frame_wf_eq[OF wf] by(cases "create_init_frame P C⇩0", simp)
then obtain rhs err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh'' v xa'
(RI (C⇩0,e) ; D#Cs ← e') = (True, ?frsT xa', rhs, err)"
using RInitInitFail⇩1.prems(1) eT by clarsimp
have IH2: "PROP ?P (RI (D,throw a) ; Cs ← e') h' l' sh'' e⇩1 h⇩1 l⇩1 sh⇩1 E C M
pc ics v xa' vs frs I" by fact
have "P ⊢ (None,h,?frsT xa',sh') -jvm→ (None,h,?frsT' xa',sh'(C⇩0 ↦ (fst (the (sh' C⇩0)), Error)))"
by(rule jvm_Throwing)
also obtain vs' where "P ⊢ ... -jvm→ handle P C M xa' h⇩1 (vs'@vs) l pc ics frs sh⇩1"
using IH2 Jcc_pieces_RInit_RInit[OF assms(1) pcs] RInitInitFail⇩1.hyps(3,4)
eT e⇩1 xa' by clarsimp
finally show ?thesis using pcs e⇩1 throw eT by auto
qed
next
case (RInitFailFinal⇩1 e h l sh a h' l' sh' C⇩0 sfs i sh'' e'')
let ?frs = "(vs,l,C,M,pc,Called [C⇩0]) # frs"
let ?frs' = "(vs,l,C,M,pc,Called []) # frs"
let "?frsT" = "λxa1. (vs,l,C,M,pc,Throwing [C⇩0] xa1) # frs"
let "?frsT'" = "λxa1. (vs,l,C,M,pc,Throwing [] xa1) # frs"
obtain xa' where xa': "throw a = Throw xa'"
by (metis RInitFailFinal⇩1.hyps(1) eval⇩1_final exp.distinct(101) final_def)
show ?case
proof(cases "e = C⇩0∙⇩sclinit([])")
case clinit: True
then obtain err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh'' v xa'
(RI (C⇩0,C⇩0∙⇩sclinit([])) ; [] ← unit) = (True, ?frs, (None, h', ?frs', sh''), err)"
using RInitFailFinal⇩1.prems(1) by clarsimp
have IH: "PROP ?P e h l sh (throw a) h' l' sh' E C M pc (Called []) v xa' vs frs I" by fact
then have IH':
"PROP ?P (C⇩0∙⇩sclinit([])) h l sh (throw a) h' l' sh' E C M pc (Called []) v xa' vs frs I"
using clinit by simp
have "P ⊢ (None,h,?frs,sh) -jvm→ (None,h,create_init_frame P C⇩0 # ?frs',sh)"
by(rule jvm_Called)
also have "P ⊢ … -jvm→ (None,h',?frsT' xa',sh'')"
using IH' Jcc_pieces_RInit_clinit[OF assms(1-2) pcs,of h' l' sh'] xa'
RInitFailFinal⇩1.hyps(3,4) by simp
also have
"P ⊢ … -jvm→ handle (compP compMb⇩2 P⇩1) C M xa' h' vs l pc No_ics frs sh''"
using RInitFailFinal⇩1.hyps(3,4) jvm_RInit_throw[where h=h' and sh=sh''] by simp
finally show ?thesis using xa' pcs clinit by(clarsimp intro!: exI[where x="[]"])
next
case throw: False
then have eT: "e = Throw xa'" "h = h'" "sh = sh'" using xa' RInitFailFinal⇩1.prems(1)
eval⇩1_final_same[OF RInitFailFinal⇩1.hyps(1)] by clarsimp+
obtain a where "class P⇩1 C⇩0 = ⌊a⌋" using RInitFailFinal⇩1.prems by(auto simp: is_class_def)
then obtain stk' loc' M' pc' ics' where "create_init_frame P C⇩0 = (stk',loc',C⇩0,M',pc',ics')"
using create_init_frame_wf_eq[OF wf] by(cases "create_init_frame P C⇩0", simp)
then obtain rhs err where pcs: "Jcc_pieces P⇩1 E C M h vs l pc ics frs sh I h' l' sh'' v xa'
(RI (C⇩0,e) ; [] ← unit) = (True, ?frsT xa', rhs, err)"
using RInitFailFinal⇩1.prems(1) eT by clarsimp
have "P ⊢ (None,h,?frsT xa',sh) -jvm→ (None,h,?frsT' xa',sh(C⇩0 ↦ (fst (the (sh C⇩0)), Error)))"
by(rule jvm_Throwing)
also have "P ⊢ … -jvm→ handle P C M xa' h' vs l pc No_ics frs sh''"
using RInitFailFinal⇩1.hyps(3,4) jvm_RInit_throw[where h=h and sh=sh''] eT by simp
finally show ?thesis using pcs xa' by(clarsimp intro!: exI[where x="[]"])
qed
qed
lemma atLeast0AtMost[simp]: "{0::nat..n} = {..n}"
by auto
lemma atLeast0LessThan[simp]: "{0::nat..<n} = {..<n}"
by auto
fun exception :: "'a exp ⇒ addr option" where
"exception (Throw a) = Some a"
| "exception e = None"
lemma comp⇩2_correct:
assumes wf: "wf_J⇩1_prog P⇩1"
and "method": "P⇩1 ⊢ C sees M,b:Ts→T = body in C"
and eval: "P⇩1 ⊢⇩1 ⟨body,(h,ls,sh)⟩ ⇒ ⟨e',(h',ls',sh')⟩"
and nclinit: "M ≠ clinit"
shows "compP⇩2 P⇩1 ⊢ (None,h,[([],ls,C,M,0,No_ics)],sh) -jvm→ (exception e',h',[],sh')"
(is "_ ⊢ ?σ⇩0 -jvm→ ?σ⇩1")
proof -
let ?P = "compP⇩2 P⇩1"
let ?E = "case b of Static ⇒ Ts | NonStatic ⇒ Class C#Ts"
have nsub: "¬sub_RI body" using sees_wf⇩1_nsub_RI[OF wf method] by simp
have code: "?P,C,M,0 ⊳ compE⇩2 body" using beforeM[OF "method"] by auto
have xtab: "?P,C,M ⊳ compxE⇩2 body 0 (size[])/{..<size(compE⇩2 body)},size[]"
using beforexM[OF "method"] by auto
have cond: "Jcc_cond P⇩1 ?E C M [] 0 No_ics {..<size(compE⇩2 body)} h sh body"
using nsub_RI_Jcc_pieces nsub code xtab by auto
{ fix v assume [simp]: "e' = Val v"
have "?P ⊢ ?σ⇩0 -jvm→ (None,h',[([v],ls',C,M,size(compE⇩2 body),No_ics)],sh')"
using Jcc[OF wf eval cond] nsub_RI_Jcc_pieces[OF _ nsub] by auto
also have "?P ⊢ … -jvm→ ?σ⇩1" using beforeM[OF "method"] nclinit by auto
finally have ?thesis .
}
moreover
{ fix a assume [simp]: "e' = Throw a"
obtain pc vs' where pc: "0 ≤ pc ∧ pc < size(compE⇩2 body) ∧
¬ caught ?P pc h' a (compxE⇩2 body 0 0)"
and 1: "?P ⊢ ?σ⇩0 -jvm→ handle ?P C M a h' vs' ls' pc No_ics [] sh'"
using Jcc[OF wf eval cond] nsub_RI_Jcc_pieces[OF _ nsub] by auto meson
from pc have "handle ?P C M a h' vs' ls' pc No_ics [] sh' = ?σ⇩1" using xtab "method" nclinit
by(auto simp:handle_def compMb⇩2_def)
with 1 have ?thesis by simp
}
ultimately show ?thesis using eval⇩1_final[OF eval] by(auto simp:final_def)
qed
end