Up to index of Isabelle/HOL/objinit
theory BVSpecTypeSafe = Correct:(* Title: HOL/MicroJava/BV/BVSpecTypeSafe.thy ID: $Id: BVSpecTypeSafe.html,v 1.1 2002/11/28 14:12:09 kleing Exp $ Author: Cornelia Pusch, Gerwin Klein Copyright 1999 Technische Universitaet Muenchen *) header {* \isaheader{BV Type Safety Proof}\label{sec:BVSpecTypeSafe} *} theory BVSpecTypeSafe = Correct: text {* This theory contains proof that the specification of the bytecode verifier only admits type safe programs. *} section {* Preliminaries *} text {* Simp and intro setup for the type safety proof: *} lemmas defs1 = correct_state_def correct_frame_def sup_state_conv wt_instr_def eff_def norm_eff_def eff_bool_def lemmas correctE = correct_stateE2 correct_frameE lemmas widen_rules[intro] = approx_val_widen approx_loc_imp_approx_loc_sup approx_stk_imp_approx_stk_sup lemmas [simp del] = split_paired_All text {* If we have a welltyped program and a conforming state, we can directly infer that the current instruction is well typed: *} lemma wt_jvm_prog_impl_wt_instr_cor: "\<lbrakk> wt_jvm_prog G phi; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc" apply (elim correct_stateE correct_frameE) apply simp apply (blast intro: wt_jvm_prog_impl_wt_instr) done section {* Exception Handling *} text {* Exceptions don't touch anything except the stack: *} lemma exec_instr_xcpt: "(fst (exec_instr i G hp ihp stk vars Cl sig pc z frs) = Some xcp) = (\<exists>stk'. exec_instr i G hp ihp stk vars Cl sig pc z frs = (Some xcp, hp, ihp, (stk', vars, Cl, sig, pc, z)#frs))" by (cases i, auto simp add: split_beta split: split_if_asm) text {* Relates @{text match_any} from the Bytecode Verifier with @{text match_exception_table} from the operational semantics: *} lemma in_match_any: "match_exception_table G xcpt pc et = Some pc' \<Longrightarrow> \<exists>C. C \<in> set (match_any G pc et) \<and> G \<turnstile> xcpt \<preceq>C C \<and> match_exception_table G C pc et = Some pc'" (is "PROP ?P et" is "?match et \<Longrightarrow> ?match_any et") proof (induct et) show "PROP ?P []" by simp fix e es assume IH: "PROP ?P es" assume match: "?match (e#es)" obtain start_pc end_pc handler_pc catch_type where [simp]: "e = (start_pc, end_pc, handler_pc, catch_type)" by (cases e) from IH match show "?match_any (e#es)" proof (cases "match_exception_entry G xcpt pc e") case False with match have "match_exception_table G xcpt pc es = Some pc'" by simp with IH obtain C where set: "C \<in> set (match_any G pc es)" and C: "G \<turnstile> xcpt \<preceq>C C" and m: "match_exception_table G C pc es = Some pc'" by blast from set have "C \<in> set (match_any G pc (e#es))" by simp moreover from False C have "¬ match_exception_entry G C pc e" by - (erule contrapos_nn, auto simp add: match_exception_entry_def elim: rtrancl_trans) with m have "match_exception_table G C pc (e#es) = Some pc'" by simp moreover note C ultimately show ?thesis by blast next case True with match have "match_exception_entry G catch_type pc e" by (simp add: match_exception_entry_def) moreover from True match obtain "start_pc \<le> pc" "pc < end_pc" "G \<turnstile> xcpt \<preceq>C catch_type" "handler_pc = pc'" by (simp add: match_exception_entry_def) ultimately show ?thesis by auto qed qed lemma match_et_imp_match: "match_exception_table G X pc et = Some handler \<Longrightarrow> match G X pc et = [X]" apply (simp add: match_some_entry) apply (induct et) apply (auto split: split_if_asm) done text {* We can prove separately that the recursive search for exception handlers (@{text find_handler}) in the frame stack results in a conforming state (if there was no matching exception handler in the current frame). We require that the exception is a valid, initialized heap address, and that the state before the exception occured conforms. *} lemma uncaught_xcpt_correct: "\<And>f. \<lbrakk> wt_jvm_prog G phi; xcp = Addr adr; hp adr = Some T; is_init hp ihp xcp; G,phi \<turnstile>JVM (None, hp, ihp, f#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM (find_handler G (Some xcp) hp ihp frs)\<surd>" (is "\<And>f. \<lbrakk> ?wt; ?adr; ?hp; ?init; ?correct (None, hp, ihp, f#frs) \<rbrakk> \<Longrightarrow> ?correct (?find frs)") proof (induct frs) -- "the base case is trivial, as it should be" show "?correct (?find [])" by (simp add: correct_state_def) -- "we will need both forms @{text wt_jvm_prog} and @{text wf_prog} later" assume wt: ?wt then obtain mb where wf: "wf_prog mb G" by (simp add: wt_jvm_prog_def) -- "these do not change in the induction:" assume adr: ?adr assume hp: ?hp assume init: ?init -- "the assumption for the cons case:" fix f f' frs' assume cr: "?correct (None, hp, ihp, f#f'#frs')" -- "the induction hypothesis as produced by Isabelle, immediatly simplified with the fixed assumptions above" assume "\<And>f. \<lbrakk> ?wt; ?adr; ?hp; ?init; ?correct (None, hp, ihp, f#frs') \<rbrakk> \<Longrightarrow> ?correct (?find frs')" with wt adr hp init have IH: "\<And>f. ?correct (None, hp, ihp, f#frs') \<Longrightarrow> ?correct (?find frs')" by blast obtain stk loc C sig pc r where f' [simp]: "f' = (stk,loc,C,sig,pc,r)" by (cases f') from cr have cr': "?correct (None, hp, ihp, f'#frs')" by (auto simp add: correct_state_def) then obtain rT maxs maxl ins et where meth: "method (G,C) sig = Some (C,rT,maxs,maxl,ins,et)" by (fastsimp elim!: correct_stateE) hence [simp]: "ex_table_of (snd (snd (the (method (G, C) sig)))) = et" by simp show "?correct (?find (f'#frs'))" proof (cases "match_exception_table G (cname_of hp xcp) pc et") case None with cr' IH show ?thesis by simp next fix handler_pc assume match: "match_exception_table G (cname_of hp xcp) pc et = Some handler_pc" (is "?match (cname_of hp xcp) = _") from wt meth cr' [simplified] have wti: "wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc" by (rule wt_jvm_prog_impl_wt_instr_cor) from cr meth obtain C' mn pts ST LT z where ins: "ins ! pc = Invoke C' mn pts \<or> ins ! pc = Invoke_special C' mn pts" and phi: "phi C sig ! pc = Some ((ST, LT),z)" by (simp add: correct_state_def) fast from match obtain D where in_any: "D \<in> set (match_any G pc et)" and D: "G \<turnstile> cname_of hp xcp \<preceq>C D" and match': "?match D = Some handler_pc" by (blast dest: in_match_any) from ins have "xcpt_names (ins ! pc, G, pc, et) = match_any G pc et" by auto with wti phi have "\<forall>D\<in>set (match_any G pc et). the (?match D) < length ins \<and> G \<turnstile> Some (([Init (Class D)], LT),z) <=' phi C sig!the (?match D)" by (simp add: wt_instr_def eff_def xcpt_eff_def) (fast dest!: bspec) with in_any match' obtain pc: "handler_pc < length ins" "G \<turnstile> Some (([Init (Class D)], LT),z) <=' phi C sig ! handler_pc" by auto then obtain ST' LT' where phi': "phi C sig ! handler_pc = Some ((ST',LT'),z)" and less: "G \<turnstile> ([Init (Class D)], LT) <=s (ST',LT')" by auto from cr' phi meth f' have "correct_frame G hp ihp (ST, LT) maxl ins f'" by (unfold correct_state_def) auto then obtain len: "length loc = 1+length (snd sig)+maxl" and loc: "approx_loc G hp ihp loc LT" and csi: "consistent_init stk loc (ST, LT) ihp" and cor: "(fst sig = init \<longrightarrow> corresponds stk loc (ST, LT) ihp (fst r) (PartInit C) \<and> (\<exists>l. fst r = Addr l \<and> hp l \<noteq> None \<and> (ihp l = PartInit C \<or> (\<exists>C'. ihp l = Init (Class C')))))" by (fastsimp elim!: correct_frameE) let ?f = "([xcp], loc, C, sig, handler_pc, r)" have "correct_frame G hp ihp (ST', LT') maxl ins ?f" proof - from wf less loc have "approx_loc G hp ihp loc LT'" by (simp add: sup_state_conv) blast moreover from D adr hp have "G,hp \<turnstile> xcp ::\<preceq> Class D" by (simp add: conf_def obj_ty_def) with init have "G,hp,ihp \<turnstile> xcp ::\<preceq>i Init (Class D)" by (simp add: iconf_def) with wf less loc have "approx_stk G hp ihp [xcp] ST'" by (auto simp add: sup_state_conv approx_stk_def approx_val_def iconf_def subtype_def elim!: conf_widen split: Err.split init_ty.split) moreover note len pc phi' csi cor ultimately show ?thesis apply (simp add: correct_frame_def) apply (blast intro: consistent_init_xcp consistent_init_widen corresponds_widen corresponds_xcp) done qed with cr' match phi phi' meth show ?thesis by (unfold correct_state_def) auto qed qed text {* The requirement of lemma @{text uncaught_xcpt_correct} (that the exception is a valid, initialized reference on the heap) is always met for welltyped instructions and conformant states: *} lemma exec_instr_xcpt_hp: "\<lbrakk> fst (exec_instr (ins!pc) G hp ihp stk vars Cl sig pc r frs) = Some xcp; wt_instr (ins!pc) G Cl rT (phi C sig) maxs (fst sig=init) (length ins) et pc; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> \<exists>adr T. xcp = Addr adr \<and> hp adr = Some T \<and> is_init hp ihp xcp" (is "\<lbrakk> ?xcpt; ?wt; ?correct \<rbrakk> \<Longrightarrow> _") proof - note [simp] = split_beta raise_system_xcpt_def note [split] = split_if_asm option.split_asm assume wt: ?wt assume correct: ?correct hence pre: "preallocated hp ihp" .. assume xcpt: ?xcpt with pre show ?thesis proof (cases "ins!pc") case New with xcpt pre show ?thesis by (auto dest: new_Addr_OutOfMemory dest!: preallocatedD) next case Throw from correct obtain ST LT z where "phi C sig ! pc = Some ((ST, LT), z)" "approx_stk G hp ihp stk ST" by (blast elim: correct_stateE correct_frameE) with Throw wt xcpt pre show ?thesis apply (unfold wt_instr_def) apply (clarsimp simp add: approx_val_def iconf_def) apply (blast dest: non_npD)+ done next case Invoke_special with xcpt pre show ?thesis by (auto dest: new_Addr_OutOfMemory dest!: preallocatedD) qed (auto dest!: preallocatedD) qed lemma cname_of_xcp [intro]: "\<lbrakk>preallocated hp ihp; xcp = Addr (XcptRef x)\<rbrakk> \<Longrightarrow> cname_of hp xcp = Xcpt x" by (auto elim: preallocatedE [of hp ihp x]) lemma prealloc_is_init [simp]: "preallocated hp ihp \<Longrightarrow> is_init hp ihp (Addr (XcptRef x))" by (drule preallocatedD) blast text {* Finally we can state that the next state always conforms when an exception occured: *} lemma xcpt_correct: "\<lbrakk> wt_jvm_prog G phi; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig=init) (length ins) et pc; fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = Some xcp; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs); G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" proof - assume wtp: "wt_jvm_prog G phi" assume meth: "method (G,C) sig = Some (C,rT,maxs,maxl,ins,et)" assume wt: "wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig=init) (length ins) et pc" assume xp: "fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = Some xcp" assume s': "Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)" assume correct: "G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>" from wtp obtain wfmb where wf: "wf_prog wfmb G" by (simp add: wt_jvm_prog_def) note xp' = meth s' xp note wtp moreover from xp wt correct obtain adr T where adr: "xcp = Addr adr" "hp adr = Some T" "is_init hp ihp xcp" by (blast dest: exec_instr_xcpt_hp) moreover note correct ultimately have "G,phi \<turnstile>JVM find_handler G (Some xcp) hp ihp frs \<surd>" by (rule uncaught_xcpt_correct) with xp' have "match_exception_table G (cname_of hp xcp) pc et = None \<Longrightarrow> ?thesis" (is "?m (cname_of hp xcp) = _ \<Longrightarrow> _" is "?match = _ \<Longrightarrow> _") by (clarsimp simp add: exec_instr_xcpt split_beta) moreover { fix handler assume some_handler: "?match = Some handler" from correct meth obtain ST LT z where hp_ok: "G \<turnstile>h hp \<surd>" and h_ini: "h_init G hp ihp" and prehp: "preallocated hp ihp" and class: "is_class G C" and phi_pc: "phi C sig ! pc = Some ((ST,LT),z)" and frame: "correct_frame G hp ihp (ST, LT) maxl ins (stk, loc, C, sig, pc, r)" and frames: "correct_frames G hp ihp phi rT sig z r frs" .. from frame obtain stk: "approx_stk G hp ihp stk ST" and loc: "approx_loc G hp ihp loc LT" and pc: "pc < length ins" and len: "length loc = length (snd sig)+maxl+1" and cin: "consistent_init stk loc (ST, LT) ihp" and cor: "fst sig = init \<longrightarrow> corresponds stk loc (ST, LT) ihp (fst r) (PartInit C) \<and> (\<exists>l. fst r = Addr l \<and> hp l \<noteq> None \<and> (ihp l = PartInit C \<or> (\<exists>C'. ihp l = Init (Class C'))))" .. from wt obtain eff: "\<forall>(pc', s')\<in>set (xcpt_eff (ins!pc) G pc (phi C sig!pc) et). pc' < length ins \<and> G \<turnstile> s' <=' phi C sig!pc'" by (simp add: wt_instr_def eff_def) from some_handler xp' have state': "state' = (None, hp, ihp, ([xcp], loc, C, sig, handler, r)#frs)" by (cases "ins!pc", auto simp add: raise_system_xcpt_def split_beta split: split_if_asm) -- "takes long!" let ?f' = "([xcp], loc, C, sig, handler, r)" from eff obtain ST' LT' where phi_pc': "phi C sig ! handler = Some ((ST', LT'),z)" and frame': "correct_frame G hp ihp (ST',LT') maxl ins ?f'" proof (cases "ins!pc") case Return -- "can't generate exceptions:" with xp' have False by (simp add: split_beta split: split_if_asm) thus ?thesis .. next case New with some_handler xp' have xcp: "xcp = Addr (XcptRef OutOfMemory)" by (simp add: raise_system_xcpt_def split_beta new_Addr_OutOfMemory) with prehp have "cname_of hp xcp = Xcpt OutOfMemory" .. with New some_handler phi_pc eff obtain ST' LT' where phi': "phi C sig ! handler = Some ((ST', LT'),z)" and less: "G \<turnstile> ([Init (Class (Xcpt OutOfMemory))], LT) <=s (ST', LT')" and pc': "handler < length ins" by (simp add: xcpt_eff_def match_et_imp_match) blast note phi' moreover { from xcp prehp have "G,hp \<turnstile> xcp ::\<preceq> Class (Xcpt OutOfMemory)" by (auto simp add: conf_def obj_ty_def dest!: preallocatedD) with xcp prehp have "G,hp,ihp \<turnstile> xcp ::\<preceq>i Init (Class (Xcpt OutOfMemory))" by (simp add: iconf_def) moreover from wf less loc have "approx_loc G hp ihp loc LT'" by (simp add: sup_state_conv) blast moreover from wf less cin have "consistent_init [xcp] loc (ST',LT') ihp" by (blast intro: consistent_init_xcp consistent_init_widen) moreover note wf less pc' len cor ultimately have "correct_frame G hp ihp (ST',LT') maxl ins ?f'" by (unfold correct_frame_def) (auto simp add: sup_state_conv approx_stk_def approx_val_def split: err.split elim!: iconf_widen intro: corresponds_xcp corresponds_widen) } ultimately show ?thesis by (rule that) next case Getfield with some_handler xp' have xcp: "xcp = Addr (XcptRef NullPointer)" by (simp add: raise_system_xcpt_def split_beta split: split_if_asm) with prehp have "cname_of hp xcp = Xcpt NullPointer" .. with Getfield some_handler phi_pc eff obtain ST' LT' where phi': "phi C sig ! handler = Some ((ST', LT'), z)" and less: "G \<turnstile> ([Init (Class (Xcpt NullPointer))], LT) <=s (ST', LT')" and pc': "handler < length ins" by (simp add: xcpt_eff_def match_et_imp_match) blast note phi' moreover { from xcp prehp have "G,hp,ihp \<turnstile> xcp ::\<preceq>i Init (Class (Xcpt NullPointer))" by (auto simp add: iconf_def conf_def obj_ty_def dest!: preallocatedD) moreover from wf less loc have "approx_loc G hp ihp loc LT'" by (simp add: sup_state_conv) blast moreover from wf less cin have "consistent_init [xcp] loc (ST', LT') ihp" by (blast intro: consistent_init_xcp consistent_init_widen) moreover note wf less pc' len cor ultimately have "correct_frame G hp ihp (ST',LT') maxl ins ?f'" by (unfold correct_frame_def) (auto simp add: sup_state_conv approx_stk_def approx_val_def split: err.split elim!: iconf_widen intro: corresponds_xcp corresponds_widen) } ultimately show ?thesis by (rule that) next case Putfield with some_handler xp' have xcp: "xcp = Addr (XcptRef NullPointer)" by (simp add: raise_system_xcpt_def split_beta split: split_if_asm) with prehp have "cname_of hp xcp = Xcpt NullPointer" .. with Putfield some_handler phi_pc eff obtain ST' LT' where phi': "phi C sig ! handler = Some ((ST', LT'), z)" and less: "G \<turnstile> ([Init (Class (Xcpt NullPointer))], LT) <=s (ST', LT')" and pc': "handler < length ins" by (simp add: xcpt_eff_def match_et_imp_match) blast note phi' moreover { from xcp prehp have "G,hp,ihp \<turnstile> xcp ::\<preceq>i Init (Class (Xcpt NullPointer))" by (auto simp add: iconf_def conf_def obj_ty_def dest!: preallocatedD) moreover from wf less loc have "approx_loc G hp ihp loc LT'" by (simp add: sup_state_conv) blast moreover from wf less cin have "consistent_init [xcp] loc (ST', LT') ihp" by (blast intro: consistent_init_xcp consistent_init_widen) moreover note wf less pc' len cor ultimately have "correct_frame G hp ihp (ST',LT') maxl ins ?f'" by (unfold correct_frame_def) (auto simp add: sup_state_conv approx_stk_def approx_val_def split: err.split elim!: iconf_widen intro: corresponds_xcp corresponds_widen) } ultimately show ?thesis by (rule that) next case Checkcast with some_handler xp' have xcp: "xcp = Addr (XcptRef ClassCast)" by (simp add: raise_system_xcpt_def split_beta split: split_if_asm) with prehp have "cname_of hp xcp = Xcpt ClassCast" .. with Checkcast some_handler phi_pc eff obtain ST' LT' where phi': "phi C sig ! handler = Some ((ST', LT'), z)" and less: "G \<turnstile> ([Init (Class (Xcpt ClassCast))], LT) <=s (ST', LT')" and pc': "handler < length ins" by (simp add: xcpt_eff_def match_et_imp_match) blast note phi' moreover { from xcp prehp have "G,hp,ihp \<turnstile> xcp ::\<preceq>i Init (Class (Xcpt ClassCast))" by (auto simp add: iconf_def conf_def obj_ty_def dest!: preallocatedD) moreover from wf less loc have "approx_loc G hp ihp loc LT'" by (simp add: sup_state_conv) blast moreover from wf less cin have "consistent_init [xcp] loc (ST', LT') ihp" by (blast intro: consistent_init_xcp consistent_init_widen) moreover note wf less pc' len cor ultimately have "correct_frame G hp ihp (ST',LT') maxl ins ?f'" by (unfold correct_frame_def) (auto simp add: sup_state_conv approx_stk_def approx_val_def split: err.split elim!: iconf_widen intro: corresponds_xcp corresponds_widen) } ultimately show ?thesis by (rule that) next case Invoke with phi_pc eff have "\<forall>D\<in>set (match_any G pc et). the (?m D) < length ins \<and> G \<turnstile> Some (([Init (Class D)], LT),z) <=' phi C sig!the (?m D)" by (simp add: xcpt_eff_def) moreover from some_handler obtain D where "D \<in> set (match_any G pc et)" and D: "G \<turnstile> cname_of hp xcp \<preceq>C D" and "?m D = Some handler" by (blast dest: in_match_any) ultimately obtain pc': "handler < length ins" and "G \<turnstile> Some (([Init (Class D)], LT), z) <=' phi C sig ! handler" by auto then obtain ST' LT' where phi': "phi C sig ! handler = Some ((ST', LT'), z)" and less: "G \<turnstile> ([Init (Class D)], LT) <=s (ST', LT')" by auto from xp wt correct obtain addr T where xcp: "xcp = Addr addr" "hp addr = Some T" "is_init hp ihp xcp" by (blast dest: exec_instr_xcpt_hp) note phi' moreover { from xcp D have "G,hp,ihp \<turnstile> xcp ::\<preceq>i Init (Class D)" by (simp add: iconf_def conf_def obj_ty_def) moreover from wf less loc have "approx_loc G hp ihp loc LT'" by (simp add: sup_state_conv) blast moreover from wf less cin have "consistent_init [xcp] loc (ST', LT') ihp" by (blast intro: consistent_init_xcp consistent_init_widen) moreover note wf less pc' len cor ultimately have "correct_frame G hp ihp (ST',LT') maxl ins ?f'" by (unfold correct_frame_def) (auto simp add: sup_state_conv approx_stk_def approx_val_def split: err.split elim!: iconf_widen intro: corresponds_xcp corresponds_widen) } ultimately show ?thesis by (rule that) next case Invoke_special with phi_pc eff have "\<forall>D\<in>set (match_any G pc et). the (?m D) < length ins \<and> G \<turnstile> Some (([Init (Class D)], LT),z) <=' phi C sig!the (?m D)" by (simp add: xcpt_eff_def) moreover from some_handler obtain D where "D \<in> set (match_any G pc et)" and D: "G \<turnstile> cname_of hp xcp \<preceq>C D" and "?m D = Some handler" by (blast dest: in_match_any) ultimately obtain pc': "handler < length ins" and "G \<turnstile> Some (([Init (Class D)], LT), z) <=' phi C sig ! handler" by auto then obtain ST' LT' where phi': "phi C sig ! handler = Some ((ST', LT'), z)" and less: "G \<turnstile> ([Init (Class D)], LT) <=s (ST', LT')" by auto from xp wt correct obtain addr T where xcp: "xcp = Addr addr" "hp addr = Some T" "is_init hp ihp xcp" by (blast dest: exec_instr_xcpt_hp) note phi' moreover { from xcp D have "G,hp,ihp \<turnstile> xcp ::\<preceq>i Init (Class D)" by (simp add: iconf_def conf_def obj_ty_def) moreover from wf less loc have "approx_loc G hp ihp loc LT'" by (simp add: sup_state_conv) blast moreover from wf less cin have "consistent_init [xcp] loc (ST', LT') ihp" by (blast intro: consistent_init_xcp consistent_init_widen) moreover note wf less pc' len cor ultimately have "correct_frame G hp ihp (ST',LT') maxl ins ?f'" by (unfold correct_frame_def) (auto simp add: sup_state_conv approx_stk_def approx_val_def split: err.split elim!: iconf_widen intro: corresponds_xcp corresponds_widen) } ultimately show ?thesis by (rule that) next case Throw with phi_pc eff have "\<forall>D\<in>set (match_any G pc et). the (?m D) < length ins \<and> G \<turnstile> Some (([Init (Class D)], LT), z) <=' phi C sig!the (?m D)" by (simp add: xcpt_eff_def) moreover from some_handler obtain D where "D \<in> set (match_any G pc et)" and D: "G \<turnstile> cname_of hp xcp \<preceq>C D" and "?m D = Some handler" by (blast dest: in_match_any) ultimately obtain pc': "handler < length ins" and "G \<turnstile> Some (([Init (Class D)], LT), z) <=' phi C sig ! handler" by auto then obtain ST' LT' where phi': "phi C sig ! handler = Some ((ST', LT'), z)" and less: "G \<turnstile> ([Init (Class D)], LT) <=s (ST', LT')" by auto from xp wt correct obtain addr T where xcp: "xcp = Addr addr" "hp addr = Some T" "is_init hp ihp xcp" by (blast dest: exec_instr_xcpt_hp) note phi' moreover { from xcp D have "G,hp,ihp \<turnstile> xcp ::\<preceq>i Init (Class D)" by (simp add: iconf_def conf_def obj_ty_def) moreover from wf less loc have "approx_loc G hp ihp loc LT'" by (simp add: sup_state_conv) blast moreover note wf less pc' len from wf less cin have "consistent_init [xcp] loc (ST', LT') ihp" by (blast intro: consistent_init_xcp consistent_init_widen) moreover note wf less pc' len cor ultimately have "correct_frame G hp ihp (ST',LT') maxl ins ?f'" by (unfold correct_frame_def) (auto simp add: sup_state_conv approx_stk_def approx_val_def split: err.split elim!: iconf_widen intro: corresponds_xcp corresponds_widen) } ultimately show ?thesis by (rule that) qed (insert xp', auto) -- "the other instructions do not generate exceptions" from state' meth hp_ok class frames phi_pc' frame' h_ini prehp have ?thesis by simp (rule correct_stateI) } ultimately show ?thesis by (cases "?match") blast+ qed section {* Single Instructions *} text {* In this section we look at each single (welltyped) instruction, and prove that the state after execution of the instruction still conforms. Since we have already handled exceptions above, we can now assume, that on exception occurs for this (single step) execution. *} lemmas [iff] = not_Err_eq lemma Load_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins!pc = Load idx; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs); G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs1 map_eq_Cons) apply (rule conjI) apply (rule approx_loc_imp_approx_val_sup) apply simp+ apply (rule conjI) apply (blast intro: approx_stk_imp_approx_stk_sup approx_loc_imp_approx_loc_sup) apply (rule conjI) apply (blast intro: approx_stk_imp_approx_stk_sup approx_loc_imp_approx_loc_sup) apply (rule conjI) apply (drule consistent_init_loc_nth) apply assumption+ apply (erule consistent_init_widen_split) apply simp apply blast apply assumption apply (rule impI, erule impE, assumption, elim exE conjE) apply (simp add: corresponds_stk_cons) apply (frule corresponds_loc_nth) apply assumption apply assumption apply (rule conjI) apply (rule impI) apply (simp add: init_le_PartInit2) apply (blast intro: corresponds_widen_split) done lemma Store_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins!pc = Store idx; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs); G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs1 map_eq_Cons) apply (blast intro: approx_stk_imp_approx_stk_sup approx_loc_imp_approx_loc_subst approx_loc_imp_approx_loc_sup consistent_init_store consistent_init_widen_split corresponds_widen_split corresponds_var_upd) done lemma LitPush_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins!pc = LitPush v; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs); G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs1 approx_val_def iconf_def init_le_Init sup_PTS_eq map_eq_Cons) apply (rule conjI) apply (blast dest: conf_litval intro: conf_widen) apply (rule conjI) apply (clarsimp simp add: is_init_def split: val.split) apply (rule conjI) apply (blast dest: approx_stk_imp_approx_stk_sup) apply (rule conjI) apply (blast dest: approx_loc_imp_approx_loc_sup) apply (rule conjI) apply (drule consistent_init_Init_stk) apply (erule consistent_init_widen_split) apply (simp add: subtype_def) apply blast apply assumption apply (rule impI, erule impE, assumption, elim conjE exE) apply (simp add: corresponds_stk_cons) apply (blast intro: corresponds_widen_split) done lemma Cast_conf2: "\<lbrakk> wf_prog ok G; G,h\<turnstile>v::\<preceq>RefT rt; cast_ok G C h v; G\<turnstile>Class C\<preceq>T; is_class G C\<rbrakk> \<Longrightarrow> G,h\<turnstile>v::\<preceq>T" apply (unfold cast_ok_def) apply (frule widen_Class) apply (elim exE disjE) apply (simp add: null) apply (clarsimp simp add: conf_def obj_ty_def) apply (cases v) apply (auto intro: rtrancl_trans) done lemmas defs2 = defs1 raise_system_xcpt_def lemma Checkcast_correct: "\<lbrakk> wt_jvm_prog G phi; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins!pc = Checkcast D; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs); G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>; fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = None \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs2 map_eq_Cons approx_val_def wt_jvm_prog_def split: split_if_asm) apply (rule conjI) apply (clarsimp simp add: iconf_def init_le_Init) apply (blast intro: Cast_conf2) apply (rule conjI) apply (erule approx_stk_imp_approx_stk_sup) apply assumption+ apply (rule conjI) apply (erule approx_loc_imp_approx_loc_sup) apply assumption+ apply (rule conjI) apply (drule consistent_init_pop) apply (drule consistent_init_widen_split) apply assumption+ apply (clarsimp simp add: init_le_Init) apply (erule consistent_init_Init_stk) apply (clarsimp simp add: init_le_Init corresponds_stk_cons) apply (blast intro: corresponds_widen_split) done lemma Getfield_correct: "\<lbrakk> wt_jvm_prog G phi; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins!pc = Getfield F D; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs); G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>; fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = None \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs2 map_eq_Cons wt_jvm_prog_def approx_val_def iconf_def init_le_Init2 split: option.split split_if_asm) apply (frule conf_widen) apply assumption+ apply (drule conf_RefTD) apply (clarsimp simp add: defs2 approx_val_def) apply (rule conjI) apply (clarsimp simp add: iconf_def init_le_Init) apply (rule conjI) apply (drule widen_cfs_fields, assumption+) apply (simp add: hconf_def oconf_def lconf_def) apply (erule allE, erule allE, erule impE, assumption) apply (simp (no_asm_use)) apply (erule allE, erule allE, erule impE, assumption) apply (elim exE conjE) apply simp apply (erule conf_widen, assumption+) apply (clarsimp simp: is_init_def split: val.split) apply (simp add: h_init_def o_init_def l_init_def) apply (erule allE, erule allE, erule impE, assumption) apply (drule hconfD, assumption) apply (drule widen_cfs_fields, assumption+) apply (drule oconf_objD, assumption) apply clarsimp apply (erule allE, erule impE) back apply blast apply (clarsimp simp add: is_init_def) apply (clarsimp simp add: init_le_Init corresponds_stk_cons) apply (blast intro: approx_stk_imp_approx_stk_sup approx_loc_imp_approx_loc_sup consistent_init_Init_stk consistent_init_pop consistent_init_widen_split corresponds_widen_split) done lemma Putfield_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins!pc = Putfield F D; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>; fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = None \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" proof - assume wf: "wf_prog wt G" assume meth: "method (G,C) sig = Some (C,rT,maxs,maxl,ins,et)" assume ins: "ins!pc = Putfield F D" assume wt: "wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc" assume exec: "Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)" assume conf: "G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>" assume no_x: "fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = None" from ins conf meth obtain ST LT z where heap_ok: "G\<turnstile>h hp\<surd>" and pre_alloc: "preallocated hp ihp" and init_ok: "h_init G hp ihp" and phi_pc: "phi C sig!pc = Some ((ST,LT),z)" and is_class_C: "is_class G C" and frame: "correct_frame G hp ihp (ST,LT) maxl ins (stk,loc,C,sig,pc,r)" and frames: "correct_frames G hp ihp phi rT sig z r frs" by (fastsimp elim: correct_stateE) from phi_pc ins wt obtain vT oT vT' tST ST' LT' where ST: "ST = (Init vT) # (Init oT) # tST" and suc_pc: "Suc pc < length ins" and phi_suc: "phi C sig ! Suc pc = Some ((ST',LT'),z)" and less: "G \<turnstile> (tST, LT) <=s (ST', LT')" and class_D: "is_class G D" and field: "field (G, D) F = Some (D, vT')" and v_less: "G \<turnstile> Init vT \<preceq>i Init vT'" and o_less: "G \<turnstile> Init oT \<preceq>i Init (Class D)" by (unfold wt_instr_def eff_def eff_bool_def norm_eff_def) (clarsimp simp add: init_le_Init2, blast) from ST frame obtain vt ot stk' where stk : "stk = vt#ot#stk'" and app_v: "approx_val G hp ihp vt (OK (Init vT))" and app_o: "approx_val G hp ihp ot (OK (Init oT))" and app_s: "approx_stk G hp ihp stk' tST" and app_l: "approx_loc G hp ihp loc LT" and consi: "consistent_init (vt#ot#stk') loc ((Init vT)#(Init oT)#tST,LT) ihp" and corr: "fst sig = init \<longrightarrow> corresponds (vt#ot#stk') loc (Init vT#Init oT#tST,LT) ihp (fst r) (PartInit C) \<and> (\<exists>l. fst r = Addr l \<and> hp l \<noteq> None \<and> (ihp l = PartInit C \<or> (\<exists>C'. ihp l = Init (Class C'))))" and len_l: "length loc = Suc (length (snd sig) + maxl)" by - (erule correct_frameE, simp, blast) from app_v app_o obtain "G,hp \<turnstile> vt ::\<preceq> vT" and conf_o: "G,hp \<turnstile> ot ::\<preceq> oT" and is_init_vo: "is_init hp ihp vt" "is_init hp ihp ot" by (simp add: approx_val_def iconf_def) with wf v_less have conf_v: "G,hp \<turnstile> vt ::\<preceq> vT'" by (auto simp add: subtype_def intro: conf_widen) { assume "ot = Null" with exec ins meth stk obtain x where "fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = Some x" by (simp add: split_beta raise_system_xcpt_def) with no_x have ?thesis by simp } moreover { assume "ot \<noteq> Null" with o_less conf_o obtain x C' fs oT' where ot_addr: "ot = Addr x" and hp_Some: "hp x = Some (C',fs)" and "G \<turnstile> (Class C') \<preceq> oT" by (fastsimp simp add: subtype_def dest: widen_RefT2 conf_RefTD) with o_less have C': "G \<turnstile> C' \<preceq>C D" by (auto simp add: subtype_def dest: widen_trans) with wf field have fields: "map_of (fields (G, C')) (F, D) = Some vT'" by - (rule widen_cfs_fields) let ?hp' = "hp(x\<mapsto>(C', fs((F, D)\<mapsto>vt)))" and ?f' = "(stk', loc, C, sig, Suc pc, r)" from exec ins meth stk ot_addr hp_Some have state': "state' = Norm (?hp', ihp, ?f'#frs)" by (simp add: raise_system_xcpt_def) from hp_Some have hext: "hp \<le>| ?hp'" by (rule sup_heap_update_value) with fields hp_Some conf_v heap_ok have hp'_ok: "G \<turnstile>h ?hp' \<surd>" by (blast intro: hconf_imp_hconf_field_update ) from app_v have "is_init hp ihp vt" by (simp add: approx_val_def iconf_def) with init_ok hp_Some have hp'_init: "h_init G ?hp' ihp" by (rule h_init_field_update) from fields hp_Some heap_ok pre_alloc have pre_alloc': "preallocated ?hp' ihp" by (rule preallocated_field_update) from corr less have corr': "fst sig = init \<longrightarrow> corresponds stk' loc (tST, LT) ihp (fst r) (PartInit C) \<and> (\<exists>l. fst r = Addr l \<and> ?hp' l \<noteq> None \<and> (ihp l = PartInit C \<or> (\<exists>C'. ihp l = Init (Class C'))))" by (clarsimp simp add: corresponds_stk_cons simp del: fun_upd_apply) simp from consi stk less have "consistent_init stk' loc (ST', LT') ihp" by (blast intro: consistent_init_pop consistent_init_widen) with wf app_l app_s len_l suc_pc less hext corr' have f'_correct: "correct_frame G ?hp' ihp (ST', LT') maxl ins (stk',loc,C,sig,Suc pc,r)" by (simp add: correct_frame_def sup_state_conv) (blast intro: approx_stk_imp_approx_stk_sup_heap approx_stk_imp_approx_stk_sup approx_loc_imp_approx_loc_sup_heap approx_loc_imp_approx_loc_sup corresponds_widen_split) from wf frames hp_Some fields conf_v have "correct_frames G ?hp' ihp phi rT sig z r frs" by - (rule correct_frames_imp_correct_frames_field_update) with state' ins meth is_class_C phi_suc hp'_ok hp'_init f'_correct pre_alloc' have ?thesis by simp (rule correct_stateI) } ultimately show ?thesis by blast qed lemma New_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins!pc = New X; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>; fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = None \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" proof - assume wf: "wf_prog wt G" assume meth: "method (G,C) sig = Some (C,rT,maxs,maxl,ins,et)" assume ins: "ins!pc = New X" assume wt: "wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc" assume exec: "Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)" assume conf: "G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>" assume no_x: "fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = None" from conf meth obtain ST LT z where heap_ok: "G\<turnstile>h hp\<surd>" and init_ok: "h_init G hp ihp" and phi_pc: "phi C sig!pc = Some ((ST,LT),z)" and prealloc: "preallocated hp ihp" and is_class_C: "is_class G C" and frame: "correct_frame G hp ihp (ST,LT) maxl ins (stk,loc,C,sig,pc,r)" and frames: "correct_frames G hp ihp phi rT sig z r frs" .. from phi_pc ins wt obtain ST' LT' where is_class_X: "is_class G X" and maxs: "length ST < maxs" and suc_pc: "Suc pc < length ins" and phi_suc: "phi C sig ! Suc pc = Some ((ST', LT'),z)" and new_type: "UnInit X pc \<notin> set ST" and less: "G \<turnstile> (UnInit X pc#ST, replace (OK (UnInit X pc)) Err LT) <=s (ST', LT')" (is "G \<turnstile> (_,?LT) <=s (ST',LT')") by (unfold wt_instr_def eff_def eff_bool_def norm_eff_def) auto obtain oref xp' where new_Addr: "new_Addr hp = (oref,xp')" by (cases "new_Addr hp") with ins no_x obtain hp: "hp oref = None" and "xp' = None" by (auto dest: new_AddrD simp add: raise_system_xcpt_def) with exec ins meth new_Addr have state': "state' = Norm (hp(oref\<mapsto>blank G X), ihp(oref := UnInit X pc), (Addr oref # stk, loc, C, sig, Suc pc, r) # frs)" (is "state' = Norm (?hp', ?ihp', ?f # frs)") by simp moreover from wf hp heap_ok is_class_X have hp': "G \<turnstile>h ?hp' \<surd>" by - (rule hconf_imp_hconf_newref, auto simp add: oconf_def blank_def dest: fields_is_type) moreover from hp heap_ok init_ok have "h_init G ?hp' ?ihp'" by (rule h_init_newref) moreover from hp have sup: "hp \<le>| ?hp'" by (rule sup_heap_newref) from frame obtain cons: "consistent_init stk loc (ST, LT) ihp" and a_loc: "approx_loc G hp ihp loc LT" and a_stk: "approx_stk G hp ihp stk ST" and corr: "fst sig = init \<longrightarrow> corresponds stk loc (ST, LT) ihp (fst r) (PartInit C) \<and> (\<exists>l. fst r = Addr l \<and> hp l \<noteq> None \<and> (ihp l = PartInit C \<or> (\<exists>C'. ihp l = Init (Class C'))))" .. from a_loc have a_loc': "approx_loc G hp ihp loc ?LT" by (rule approx_loc_replace_Err) from corr a_loc a_stk new_type hp have corr': "fst sig = init \<longrightarrow> corresponds (Addr oref#stk) loc (UnInit X pc#ST, ?LT) ?ihp' (fst r) (PartInit C) \<and> (\<exists>l. fst r = Addr l \<and> ?hp' l \<noteq> None \<and> (?ihp' l = PartInit C \<or> (\<exists>C'. ?ihp' l = Init (Class C'))))" apply (clarsimp simp add: corresponds_stk_cons simp del: fun_upd_apply) apply (drule corresponds_new_val2, assumption+) apply (auto intro: corresponds_replace_Err) done from new_type have "OK (UnInit X pc) \<notin> set (map OK ST) \<union> set ?LT" by (auto simp add: replace_removes_elem) with cons a_stk a_loc' hp have "consistent_init (Addr oref # stk) loc (UnInit X pc#ST,?LT) ?ihp'" by (blast intro: consistent_init_newref consistent_init_replace_Err) from this less have "consistent_init (Addr oref # stk) loc (ST',LT') ?ihp'" by (rule consistent_init_widen) with hp frame less suc_pc wf corr' a_loc' have "correct_frame G ?hp' ?ihp' (ST', LT') maxl ins ?f" apply (unfold correct_frame_def sup_state_conv) apply (clarsimp simp add: map_eq_Cons conf_def blank_def corresponds_stk_cons) apply (insert sup, unfold blank_def) apply (blast intro: corresponds_widen_split approx_stk_imp_approx_stk_sup approx_stk_newref approx_stk_imp_approx_stk_sup_heap approx_loc_imp_approx_loc_sup_heap approx_loc_imp_approx_loc_sup approx_loc_newref approx_val_newref sup) done moreover from hp frames wf heap_ok is_class_X have "correct_frames G ?hp' ?ihp' phi rT sig z r frs" by (unfold blank_def) (rule correct_frames_imp_correct_frames_newref, auto simp add: oconf_def dest: fields_is_type) moreover from hp prealloc have "preallocated ?hp' ?ihp'" by (rule preallocated_newref) ultimately show ?thesis by simp (rule correct_stateI) qed text {* \bf Method Invocation *} lemmas [simp del] = split_paired_Ex lemma Invoke_correct: "\<lbrakk> wt_jvm_prog G phi; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Invoke C' mn pTs; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>; fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = None \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" proof - assume wtprog: "wt_jvm_prog G phi" assume method: "method (G,C) sig = Some (C,rT,maxs,maxl,ins,et)" assume ins: "ins ! pc = Invoke C' mn pTs" assume wti: "wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc" assume state': "Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)" assume approx: "G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>" assume no_xcp: "fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = None" from wtprog obtain wfmb where wfprog: "wf_prog wfmb G" by (simp add: wt_jvm_prog_def) from approx method obtain s z where heap_ok: "G\<turnstile>h hp\<surd>" and init_ok: "h_init G hp ihp" and phi_pc: "phi C sig!pc = Some (s,z)" and prealloc:"preallocated hp ihp" and is_class_C: "is_class G C" and frame: "correct_frame G hp ihp s maxl ins (stk, loc, C, sig, pc, r)" and frames: "correct_frames G hp ihp phi rT sig z r frs" .. from ins wti phi_pc obtain apTs X ST LT D' rT body where is_class: "is_class G C'" and s: "s = (rev apTs @ X # ST, LT)" and l: "length apTs = length pTs" and w: "\<forall>(x,y)\<in>set (zip apTs pTs). G \<turnstile> x \<preceq>i (Init y)" and mC': "method (G, C') (mn, pTs) = Some (D', rT, body)" and pc: "Suc pc < length ins" and eff: "G \<turnstile> norm_eff (Invoke C' mn pTs) G pc (Some (s,z)) <=' phi C sig!Suc pc" and X: "G \<turnstile> X \<preceq>i Init (Class C')" and ni: "mn \<noteq> init" by (simp add: wt_instr_def eff_def) blast from eff obtain ST' LT' z' where s': "phi C sig ! Suc pc = Some ((ST',LT'),z')" by (simp add: norm_eff_def split_paired_Ex) fast from s ins frame obtain a_stk: "approx_stk G hp ihp stk (rev apTs @ X # ST)" and a_loc: "approx_loc G hp ihp loc LT" and init: "consistent_init stk loc s ihp" and suc_l: "length loc = Suc (length (snd sig) + maxl)" by (simp add: correct_frame_def) from a_stk obtain opTs stk' oX where opTs: "approx_stk G hp ihp opTs (rev apTs)" and oX: "approx_val G hp ihp oX (OK X)" and a_stk': "approx_stk G hp ihp stk' ST" and stk': "stk = opTs @ oX # stk'" and l_o: "length opTs = length apTs" "length stk' = length ST" by (auto dest!: approx_stk_append_lemma) from oX have X_oX: "G,hp,ihp \<turnstile> oX ::\<preceq>i X" by (simp add: approx_val_def) with wfprog X have oX_conf: "G,hp \<turnstile> oX ::\<preceq> (Class C')" by (auto simp add: approx_val_def iconf_def init_le_Init2 dest: conf_widen) from stk' l_o l have oX_pos: "stk ! length pTs = oX" by (simp add: nth_append) with state' method ins no_xcp oX_conf obtain ref where oX_Addr: "oX = Addr ref" by (auto simp add: raise_system_xcpt_def dest: conf_RefTD) with oX_conf obtain D fs where hp_Some: "hp ref = Some (D,fs)" and D_le_C': "G \<turnstile> D \<preceq>C C'" by (fastsimp dest: conf_RefTD) from D_le_C' wfprog mC' obtain D'' rT' mxl' mxs' ins' et' where mD: "method (G, D) (mn, pTs) = Some (D'', rT', mxs', mxl', ins', et')" "G \<turnstile> rT' \<preceq> rT" by (auto dest!: subtype_widen_methd) blast let ?loc' = "oX # rev opTs @ replicate mxl' arbitrary" let ?f = "([], ?loc', D'', (mn, pTs), 0, arbitrary)" let ?f' = "(stk, loc, C, sig, pc, r)" from oX_Addr oX_pos hp_Some state' method ins stk' l_o l mD have state'_val: "state' = Norm (hp, ihp, ?f# ?f' # frs)" by (simp add: raise_system_xcpt_def) from is_class D_le_C' have is_class_D: "is_class G D" by (auto dest: subcls_is_class2) with mD wfprog obtain mD'': "method (G, D'') (mn, pTs) = Some (D'', rT', mxs', mxl', ins', et')" "is_class G D''" by (auto dest: method_in_md) from wtprog mD'' have start: "wt_start G D'' mn pTs mxl' (phi D'' (mn, pTs)) \<and> ins' \<noteq> []" by (auto dest: wt_jvm_prog_impl_wt_start) then obtain LT0 z0 where LT0: "phi D'' (mn, pTs) ! 0 = Some (([], LT0),z0)" by (clarsimp simp add: wt_start_def sup_state_conv) have c_f: "correct_frame G hp ihp ([], LT0) mxl' ins' ?f" proof - let ?T = "OK (Init (Class D''))" from ni start LT0 have sup_loc: "G \<turnstile> (?T # map OK (map Init pTs) @ replicate mxl' Err) <=l LT0" (is "G \<turnstile> ?LT <=l LT0") by (simp add: wt_start_def sup_state_conv) have r: "approx_loc G hp ihp (replicate mxl' arbitrary) (replicate mxl' Err)" by (simp add: approx_loc_def approx_val_Err list_all2_def set_replicate_conv_if) from wfprog mD is_class_D have "G \<turnstile> Class D \<preceq> Class D''" by (auto dest: method_wf_mdecl) with hp_Some oX_Addr oX X have a: "approx_val G hp ihp oX ?T" by (auto simp add: is_init_def init_le_Init2 approx_val_def iconf_def conf_def) from w l have "\<forall>(x,y)\<in>set (zip (map (\<lambda>x. x) apTs) (map Init pTs)). G \<turnstile> x \<preceq>i y" by (simp only: zip_map) auto hence "\<forall>(x,y)\<in>set (zip apTs (map Init pTs)). G \<turnstile> x \<preceq>i y" by simp with l have "\<forall>(x,y)\<in>set (zip (rev apTs) (rev (map Init pTs))). G \<turnstile> x \<preceq>i y" by (auto simp add: zip_rev) with wfprog l l_o opTs have "approx_loc G hp ihp opTs (map OK (rev (map Init pTs)))" by (auto intro: assConv_approx_stk_imp_approx_loc) hence "approx_stk G hp ihp opTs (rev (map Init pTs))" by (simp add: approx_stk_def) hence "approx_stk G hp ihp (rev opTs) (map Init pTs)" by (simp add: approx_stk_rev) hence "approx_loc G hp ihp (rev opTs) (map OK (map Init pTs))" by (simp add: approx_stk_def) with r a l_o l have "approx_loc G hp ihp ?loc' ?LT" by (auto simp add: approx_loc_append approx_stk_def) from wfprog this sup_loc have loc: "approx_loc G hp ihp ?loc' LT0" by (rule approx_loc_imp_approx_loc_sup) from l l_o have "length pTs = length opTs" by auto hence "consistent_init [] ?loc' ([],?LT) ihp" by (blast intro: consistent_init_start) with sup_loc have "consistent_init [] ?loc' ([],LT0) ihp" by (auto intro: consistent_init_widen_split) with start loc l_o l ni show ?thesis by (simp add: correct_frame_def) qed from X X_oX oX_Addr hp_Some obtain X' where X': "X = Init (Class X')" by (auto simp add: init_le_Init2 iconf_def conf_def dest!: widen_Class) with X mC' wf obtain mD'' rT'' b'' where "method (G, X') (mn, pTs) = Some (mD'', rT'', b'')" "G \<turnstile> rT'' \<preceq> rT" by (simp add: subtype_def) (drule subtype_widen_methd, assumption+, blast) with X' state'_val heap_ok mD'' ins method phi_pc s l frames s' LT0 c_f frame is_class_C ni init_ok prealloc show "G,phi \<turnstile>JVM state'\<surd>" apply simp apply (rule correct_stateI, assumption+) apply clarsimp apply (intro exI conjI impI) apply (rule refl) apply blast apply assumption apply assumption done qed lemma Invoke_special_correct: "\<lbrakk> wt_jvm_prog G phi; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Invoke_special C' mn pTs; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>; fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = None \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" proof - assume wtprog: "wt_jvm_prog G phi" assume method: "method (G,C) sig = Some (C,rT,maxs,maxl,ins,et)" assume ins: "ins ! pc = Invoke_special C' mn pTs" assume wti: "wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc" assume state': "Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)" assume approx: "G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>" assume no_x: "fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = None" from wtprog obtain wfmb where wfprog: "wf_prog wfmb G" by (simp add: wt_jvm_prog_def) from approx method obtain s z where heap_ok: "G\<turnstile>h hp\<surd>" and init_ok: "h_init G hp ihp" and prealloc:"preallocated hp ihp" and phi_pc: "phi C sig!pc = Some (s,z)" and is_class_C: "is_class G C" and frame: "correct_frame G hp ihp s maxl ins (stk, loc, C, sig, pc, r)" and frames: "correct_frames G hp ihp phi rT sig z r frs" .. from ins wti phi_pc obtain apTs X ST LT rT' maxs' mxl' ins' et' where s: "s = (rev apTs @ X # ST, LT)" and l: "length apTs = length pTs" and is_class: "is_class G C'" and w: "\<forall>(x,y)\<in>set (zip apTs pTs). G \<turnstile> x \<preceq>i (Init y)" and mC': "method (G, C') (mn, pTs) = Some (C', rT', maxs', mxl', ins', et')" and pc: "Suc pc < length ins" and eff: "G \<turnstile> norm_eff (Invoke_special C' mn pTs) G pc (Some (s,z)) <=' phi C sig!Suc pc" and X: "(\<exists>pc. X = UnInit C' pc) \<or> (X = PartInit C \<and> G \<turnstile> C \<prec>C1 C' \<and> ¬z)" and is_init: "mn = init" by (simp add: wt_instr_def split_paired_Ex eff_def) blast from s eff obtain ST' LT' z' where s': "phi C sig ! Suc pc = Some ((ST',LT'),z')" by (clarsimp simp add: norm_eff_def) blast from s ins frame obtain a_stk: "approx_stk G hp ihp stk (rev apTs @ X # ST)" and a_loc: "approx_loc G hp ihp loc LT" and init: "consistent_init stk loc (rev apTs @ X # ST, LT) ihp" and corr: "fst sig = init \<longrightarrow> corresponds stk loc s ihp (fst r) (PartInit C) \<and> (\<exists>l. fst r = Addr l \<and> hp l \<noteq> None \<and> (ihp l = PartInit C \<or> (\<exists>C'. ihp l = Init (Class C'))))" and suc_l: "length loc = Suc (length (snd sig) + maxl)" by (simp add: correct_frame_def) from a_stk obtain opTs stk' oX where opTs: "approx_stk G hp ihp opTs (rev apTs)" and oX: "approx_val G hp ihp oX (OK X)" and a_stk': "approx_stk G hp ihp stk' ST" and stk': "stk = opTs @ oX # stk'" and l_o: "length opTs = length apTs" "length stk' = length ST" by (fastsimp dest!: approx_stk_append_lemma) from stk' l_o l have oX_pos: "stk ! length pTs = oX" by (simp add: nth_append) from state' method ins no_x oX_pos have "oX \<noteq> Null" by (simp add: raise_system_xcpt_def split: split_if_asm) moreover from wfprog X oX have oX_conf: "G,hp \<turnstile> oX ::\<preceq> (Class C')" by (auto simp add: approx_val_def iconf_def) (blast dest: conf_widen) ultimately obtain ref obj D fs where oX_Addr: "oX = Addr ref" and hp_Some: "hp ref = Some (D,fs)" and D_le_C': "G \<turnstile> D \<preceq>C C'" by (fastsimp dest: conf_RefTD) let ?new = "new_Addr hp" let ?ref' = "fst ?new" let ?xp' = "snd ?new" let ?hp' = "hp(?ref'\<mapsto>blank G D)" let ?loc' = "Addr ?ref' # rev opTs @ replicate mxl' arbitrary" let ?ihp' = "if C' = Object then ihp(?ref':= Init (Class D)) else ihp(?ref' := PartInit C')" let ?r' = "if C' = Object then (Addr ?ref', Addr ?ref') else (Addr ?ref', Null)" let ?f = "([], ?loc', C', (mn, pTs), 0, ?r')" let ?f' = "(stk, loc, C, sig, pc, r)" from state' method ins no_x have norm: "?xp' = None" by (simp add: split_beta split: split_if_asm) with oX_Addr oX_pos hp_Some state' method ins stk' l_o l mC' have state'_val: "state' = Norm (?hp', ?ihp', ?f# ?f' # frs)" by (simp add: raise_system_xcpt_def split_beta) obtain ref' xp' where new_Addr: "new_Addr hp = (ref',xp')" by (cases "new_Addr hp") auto with norm have new_ref': "hp ref' = None" by (auto dest: new_AddrD) from is_class D_le_C' have is_class_D: "is_class G D" by (auto dest: subcls_is_class2) from wtprog is_class mC' have start: "wt_start G C' mn pTs mxl' (phi C' (mn, pTs)) \<and> ins' \<noteq> []" by (auto dest: wt_jvm_prog_impl_wt_start) then obtain LT0 where LT0: "phi C' (mn, pTs) ! 0 = Some (([], LT0),C'=Object)" by (clarsimp simp add: wt_start_def sup_state_conv) let ?T = "OK (if C' \<noteq> Object then PartInit C' else Init (Class C'))" from start LT0 is_init have sup_loc: "G \<turnstile> (?T # map OK (map Init pTs) @ replicate mxl' Err) <=l LT0" (is "G \<turnstile> ?LT <=l LT0") by (simp add: wt_start_def sup_state_conv) have c_f: "correct_frame G ?hp' ?ihp' ([], LT0) mxl' ins' ?f" proof - have r: "approx_loc G ?hp' ?ihp' (replicate mxl' arbitrary) (replicate mxl' Err)" by (simp add: approx_loc_def approx_val_Err list_all2_def set_replicate_conv_if) from new_Addr obtain fs where "?hp' ref' = Some (D,fs)" by (simp add: blank_def) hence "G,?hp' \<turnstile> Addr ref' ::\<preceq> Class C'" by (auto simp add: new_Addr D_le_C' intro: conf_obj_AddrI) hence a: "approx_val G ?hp' ?ihp' (Addr ?ref') ?T" by (auto simp add: approx_val_def iconf_def new_Addr blank_def is_init_def) from w l have "\<forall>(x,y)\<in>set (zip (map (\<lambda>x. x) apTs) (map Init pTs)). G \<turnstile> x \<preceq>i y" by (simp only: zip_map) auto hence "\<forall>(x,y)\<in>set (zip apTs (map Init pTs)). G \<turnstile> x \<preceq>i y" by simp with l have "\<forall>(x,y)\<in>set (zip (rev apTs) (rev (map Init pTs))). G \<turnstile> x \<preceq>i y" by (auto simp add: zip_rev) with wfprog l l_o opTs have "approx_loc G hp ihp opTs (map OK (rev (map Init pTs)))" by (auto intro: assConv_approx_stk_imp_approx_loc) hence "approx_stk G hp ihp opTs (rev (map Init pTs))" by (simp add: approx_stk_def) hence "approx_stk G hp ihp (rev opTs) (map Init pTs)" by (simp add: approx_stk_rev) hence "approx_loc G hp ihp (rev opTs) (map OK (map Init pTs))" by (simp add: approx_stk_def) with new_Addr new_ref' have "approx_loc G hp ?ihp' (rev opTs) (map OK (map Init pTs))" by (auto dest: approx_loc_newref) moreover from new_Addr new_ref' have "hp \<le>| ?hp'" by simp ultimately have "approx_loc G ?hp' ?ihp' (rev opTs) (map OK (map Init pTs))" by (rule approx_loc_imp_approx_loc_sup_heap) with r a l_o l have "approx_loc G ?hp' ?ihp' ?loc' ?LT" by (auto simp add: approx_loc_append) from wfprog this sup_loc have loc: "approx_loc G ?hp' ?ihp' ?loc' LT0" by (rule approx_loc_imp_approx_loc_sup) from new_Addr new_ref' l_o l have "corresponds [] ?loc' ([], ?LT) ?ihp' (Addr ref') (PartInit C')" apply (simp add: corresponds_def corr_stk_def corr_loc_cons split del: split_if) apply (rule conjI) apply (simp add: corr_val_def) apply (rule corr_loc_start) apply clarsimp apply (erule disjE) apply (erule imageE, erule imageE) apply simp apply blast apply (drule in_set_replicateD) apply assumption apply simp apply blast done with sup_loc have corr': "corresponds [] ?loc' ([], LT0) ?ihp' (Addr ref') (PartInit C')" by (fastsimp elim: corresponds_widen_split) from l_o l have "length (rev opTs @ replicate mxl' arbitrary) = length (map OK (map Init pTs) @ replicate mxl' Err)" by simp moreover have "\<forall>x\<in>set (map OK (map Init pTs) @ replicate mxl' Err). x = Err \<or> (\<exists>t. x = OK (Init t))" by (auto dest: in_set_replicateD) ultimately have "consistent_init [] ?loc' ([], ?LT) ?ihp'" apply (unfold consistent_init_def) apply (unfold corresponds_def) apply (simp (no_asm) add: corr_stk_def corr_loc_empty corr_loc_cons split del: split_if) apply safe apply (rule exI) apply (rule conjI) apply (simp (no_asm)) apply (rule corr_loc_start) apply assumption+ apply blast apply (rule exI) apply (rule conjI) defer apply (blast intro: corr_loc_start) apply (rule impI) apply (simp add: new_Addr split del: split_if) apply (rule conjI) apply (rule refl) apply (simp add: corr_val_def new_Addr split: split_if_asm) done with sup_loc have "consistent_init [] ?loc' ([], LT0) ?ihp'" by (auto intro: consistent_init_widen_split) with start loc l_o l corr' new_Addr new_ref' show ?thesis by (simp add: correct_frame_def split: split_if_asm) qed from a_stk a_loc init suc_l pc new_Addr new_ref' s corr have c_f': "correct_frame G ?hp' ?ihp' (rev apTs @ X # ST, LT) maxl ins ?f'" apply (unfold correct_frame_def) apply simp apply (rule conjI) apply (rule impI) apply (rule conjI) apply (drule approx_stk_newref, assumption) apply (rule approx_stk_imp_approx_stk_sup_heap, assumption) apply simp apply (rule conjI) apply (drule approx_loc_newref, assumption) apply (rule approx_loc_imp_approx_loc_sup_heap, assumption) apply simp apply (rule conjI) apply (rule consistent_init_new_val, assumption+) apply (rule impI, erule impE, assumption, elim exE conjE) apply (rule conjI) apply (rule corresponds_new_val2, assumption+) apply simp apply (rule exI, rule conjI) apply (rule impI) apply assumption apply simp apply (rule impI) apply (rule conjI) apply (drule approx_stk_newref, assumption) apply (rule approx_stk_imp_approx_stk_sup_heap, assumption) apply simp apply (rule conjI) apply (drule approx_loc_newref, assumption) apply (rule approx_loc_imp_approx_loc_sup_heap, assumption) apply simp apply (rule conjI) apply (rule consistent_init_new_val, assumption+) apply (rule impI, erule impE, assumption, elim exE conjE) apply (rule conjI) apply (rule corresponds_new_val2, assumption+) apply simp apply (rule exI, rule conjI) apply (rule impI) apply (rule conjI) apply assumption apply simp apply simp done from new_Addr new_ref' heap_ok is_class_D wfprog have hp'_ok: "G \<turnstile>h ?hp' \<surd>" by (auto intro: hconf_imp_hconf_newref oconf_blank) with new_Addr new_ref' have ihp'_ok: "h_init G ?hp' ?ihp'" by (auto intro!: h_init_newref) from hp_Some new_ref' have neq_ref: "ref \<noteq> ref'" by auto with new_Addr oX_Addr X oX hp_Some have ctor_ok: "constructor_ok G ?hp' ?ihp' (Addr ref) C' (C'=Object) ?r'" apply (unfold constructor_ok_def) apply (simp add: approx_val_def iconf_def) apply (erule disjE) apply (clarsimp simp add: blank_def) apply (elim exE conjE) apply (simp add: blank_def) done from new_Addr new_ref' frames have c_frs: "correct_frames G ?hp' ?ihp' phi rT sig z r frs" by (auto simp add: blank_def intro: correct_frames_imp_correct_frames_newref) from new_Addr new_ref' prealloc have prealloc': "preallocated ?hp' ?ihp'" by (auto intro: preallocated_newref) from state'_val heap_ok mC' ins method phi_pc s l ctor_ok c_f' c_frs frames s' LT0 c_f is_class_C is_class new_Addr new_ref' hp'_ok ihp'_ok prealloc' show "G,phi \<turnstile>JVM state'\<surd>" apply (unfold correct_state_def) apply (simp split del: split_if) apply (intro exI conjI impI) apply (rule refl) apply assumption apply (simp add: oX_pos oX_Addr hp_Some neq_ref) done qed lemmas [simp del] = map_append lemma Return_correct_not_init: "\<lbrakk> fst sig \<noteq> init; wt_jvm_prog G phi; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Return; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" proof - assume wtjvm: "wt_jvm_prog G phi" assume mthd: "method (G,C) sig = Some (C,rT,maxs,maxl,ins,et)" assume ins: "ins!pc = Return" assume wt: "wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc" assume state: "Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)" assume approx:"G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>" from approx mthd obtain s z where heap_ok: "G \<turnstile>h hp\<surd>" and init_ok: "h_init G hp ihp" and prealloc:"preallocated hp ihp" and classC: "is_class G C" and some: "phi C sig ! pc = Some (s, z)" and frame: "correct_frame G hp ihp s maxl ins (stk, loc, C, sig, pc, r)" and frames: "correct_frames G hp ihp phi rT sig z r frs" .. obtain mn pTs where sig: "sig = (mn,pTs)" by (cases sig) moreover assume "fst sig \<noteq> init" ultimately have not_init: "mn \<noteq> init" by simp from ins some sig wt obtain T ST LT where s: "s = (T # ST, LT)" and T: "G \<turnstile> T \<preceq>i Init rT" and pc: "pc < length ins" by (simp add: wt_instr_def eff_def eff_bool_def norm_eff_def) blast from frame s obtain rval stk' loc where stk: "stk = rval # stk'" and val: "approx_val G hp ihp rval (OK T)" and approx_stk: "approx_stk G hp ihp stk' ST" and approx_val: "approx_loc G hp ihp loc LT" and consistent: "consistent_init stk loc (T # ST, LT) ihp" and len: "length loc = Suc (length (snd sig) + maxl)" by (simp add: correct_frame_def) blast from stk mthd ins state have "frs = [] \<Longrightarrow> ?thesis" by (simp add: correct_state_def) moreover { fix f frs' assume frs: "frs = f#frs'" obtain stk0 loc0 C0 sig0 pc0 r0 where f: "f = (stk0, loc0, C0, sig0, pc0, r0)" by (cases f) let ?r' = "(stk0 ! length pTs, snd r0)" let ?stk' = "drop (Suc (length pTs)) stk0" let ?f' = "(rval#?stk',loc0,C0,sig0,Suc pc0,r0)" from stk mthd ins sig f frs not_init state have state': "state' = Norm (hp, ihp, ?f' # frs')" by (simp add: split_beta) from f frs frames sig obtain ST0 LT0 T0 z0 rT0 maxs0 maxl0 ins0 et0 C' apTs D D' rT' body' where class_C0: "is_class G C0" and methd_C0: "method (G, C0) sig0 = Some (C0, rT0, maxs0, maxl0, ins0, et0)" and ins0: "ins0 ! pc0 = Invoke C' mn pTs \<or> ins0 ! pc0 = Invoke_special C' mn pTs" and phi_pc0: "phi C0 sig0 ! pc0 = Some ((rev apTs @ T0 # ST0, LT0), z0)" and apTs: "length apTs = length pTs" and methd_C': "method (G, C') sig = Some (D', rT', body')" "G \<turnstile> rT \<preceq> rT'" and c_fr: "correct_frame G hp ihp (rev apTs @ T0 # ST0, LT0) maxl0 ins0 (stk0, loc0, C0, sig0, pc0, r0)" and c_frs: "correct_frames G hp ihp phi rT0 sig0 z0 r0 frs'" apply simp (* fixme: this script sucks *) apply (elim conjE exE) apply (rule that) apply assumption+ apply simp apply ( (rule conjI,rule refl)+ ) apply (rule refl) apply assumption+ apply simp apply assumption done from c_fr obtain a_stk0: "approx_stk G hp ihp stk0 (rev apTs @ T0 # ST0)" and a_loc0: "approx_loc G hp ihp loc0 LT0" and cons0: "consistent_init stk0 loc0 (rev apTs @ T0 # ST0, LT0) ihp" and corr0: "fst sig0 = init \<longrightarrow> corresponds stk0 loc0 (rev apTs @ T0 # ST0, LT0) ihp (fst r0) (PartInit C0) \<and> (\<exists>l. fst r0 = Addr l \<and> hp l \<noteq> None \<and> (ihp l = PartInit C0 \<or> (\<exists>C'. ihp l = Init (Class C'))))" and pc0: "pc0 < length ins0" and lenloc0:"length loc0 = Suc (length (snd sig0) + maxl0)" by (unfold correct_frame_def) simp from pc0 wtjvm methd_C0 have wt0: "wt_instr (ins0!pc0) G C0 rT0 (phi C0 sig0) maxs0 (fst sig0 = init) (length ins0) et0 pc0" by - (rule wt_jvm_prog_impl_wt_instr) from ins0 apTs phi_pc0 not_init sig methd_C' wt0 obtain ST'' LT'' where Suc_pc0: "Suc pc0 < length ins0" and phi_Suc_pc0: "phi C0 sig0 ! Suc pc0 = Some ((ST'',LT''),z0)" and T0: "G \<turnstile> T0 \<preceq>i Init (Class C')" and less: "G \<turnstile> (Init rT' # ST0, LT0) <=s (ST'',LT'')" apply (simp add: wt_instr_def) apply (erule disjE) apply (simp add: eff_def eff_bool_def norm_eff_def) apply (elim exE conjE) apply (rotate_tac -7) (* fixme *) apply clarsimp apply blast apply simp done from wtjvm obtain mb where wf: "wf_prog mb G" by (simp add: wt_jvm_prog_def) from a_stk0 obtain apts v stk0' where stk0': "stk0 = apts @ v # stk0'" and len: "length apts = length apTs" and v: "approx_val G hp ihp v (OK T0)" and a_stk0': "approx_stk G hp ihp stk0' ST0" by - (drule approx_stk_append_lemma, auto) from stk0' len v a_stk0' wf apTs val T wf methd_C' have a_stk': "approx_stk G hp ihp (rval # drop (Suc (length pTs)) stk0) (Init rT'#ST0)" apply simp apply (rule approx_val_widen, assumption+) apply (clarsimp simp add: init_le_Init2) apply (erule widen_trans) apply assumption done from stk0' len apTs cons0 have cons': "consistent_init (rval # drop (Suc (length pTs)) stk0) loc0 (Init rT'#ST0, LT0) ihp" apply simp apply (drule consistent_init_append) apply simp apply (drule consistent_init_pop) apply (rule consistent_init_Init_stk) apply assumption done from stk0' len apTs corr0 have corr': "fst sig0 = init \<longrightarrow> corresponds (rval # drop (Suc (length pTs)) stk0) loc0 (Init rT'#ST0, LT0) ihp (fst r0) (PartInit C0) \<and> (\<exists>l. fst r0 = Addr l \<and> hp l \<noteq> None \<and> (ihp l = PartInit C0 \<or> (\<exists>C'. ihp l = Init (Class C'))))" apply clarsimp apply (drule corresponds_append) apply simp apply (simp add: corresponds_stk_cons) done with cons' lenloc0 a_loc0 Suc_pc0 a_stk' wf have frame': "correct_frame G hp ihp (ST'',LT'') maxl0 ins0 ?f'" apply (simp add: correct_frame_def) apply (insert less) apply (clarsimp simp add: sup_state_conv map_eq_Cons) apply (rule conjI) apply (rule approx_val_widen, assumption+) apply (rule conjI) apply (rule approx_stk_imp_approx_stk_sup, assumption+) apply (rule conjI) apply (rule approx_loc_imp_approx_loc_sup, assumption+) apply (rule conjI) apply (rule consistent_init_widen_split, assumption) apply simp apply blast apply assumption apply (rule impI, erule impE, assumption, erule conjE) apply (rule corresponds_widen_split, assumption) apply simp apply blast apply assumption apply blast done from state' heap_ok init_ok frame' c_frs class_C0 methd_C0 phi_Suc_pc0 prealloc have ?thesis by (simp add: correct_state_def) } ultimately show "G,phi \<turnstile>JVM state'\<surd>" by (cases frs, blast+) qed lemma Return_correct_init: "\<lbrakk> fst sig = init; wt_jvm_prog G phi; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Return; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs); G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" proof - assume wtjvm: "wt_jvm_prog G phi" assume mthd: "method (G,C) sig = Some (C,rT,maxs,maxl,ins,et)" assume ins: "ins!pc = Return" assume wt: "wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc" assume state: "Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)" assume approx:"G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>" from approx mthd obtain s z where heap_ok: "G \<turnstile>h hp\<surd>" and init_ok: "h_init G hp ihp" and prealloc:"preallocated hp ihp" and classC: "is_class G C" and some: "phi C sig ! pc = Some (s, z)" and frame: "correct_frame G hp ihp s maxl ins (stk, loc, C, sig, pc, r)" and frames: "correct_frames G hp ihp phi rT sig z r frs" .. obtain mn pTs where sig: "sig = (mn,pTs)" by (cases sig) moreover assume sig_in: "fst sig = init" ultimately have is_init: "mn = init" by simp from ins some sig is_init wt obtain T ST LT where s: "s = (T # ST, LT)" and T: "G \<turnstile> T \<preceq>i Init rT" and z: "z" and pc: "pc < length ins" by (simp add: wt_instr_def eff_def eff_bool_def norm_eff_def) blast from frame s sig_in obtain rval stk' loc where stk: "stk = rval # stk'" and val: "approx_val G hp ihp rval (OK T)" and approx_stk: "approx_stk G hp ihp stk' ST" and approx_val: "approx_loc G hp ihp loc LT" and consistent: "consistent_init stk loc (T # ST, LT) ihp" and corr: "corresponds stk loc (T # ST, LT) ihp (fst r) (PartInit C)" and len: "length loc = Suc (length (snd sig) + maxl)" by (simp add: correct_frame_def) blast from stk mthd ins state have "frs = [] \<Longrightarrow> ?thesis" by (simp add: correct_state_def) moreover { fix f frs' assume frs: "frs = f#frs'" obtain stk0 loc0 C0 sig0 pc0 r0 where f: "f = (stk0, loc0, C0, sig0, pc0, r0)" by (cases f) from f frs frames sig is_init obtain ST0 LT0 T0 z0 rT0 maxs0 maxl0 ins0 et0 C' apTs D D' rT' body' where class_C0: "is_class G C0" and methd_C0: "method (G, C0) sig0 = Some (C0, rT0, maxs0, maxl0, ins0, et0)" and ins0: "ins0 ! pc0 = Invoke C' mn pTs \<or> ins0 ! pc0 = Invoke_special C' mn pTs" and phi_pc0: "phi C0 sig0 ! pc0 = Some ((rev apTs @ T0 # ST0, LT0), z0)" and apTs: "length apTs = length pTs" and methd_C': "method (G, C') sig = Some (D', rT', body')" "G \<turnstile> rT \<preceq> rT'" and ctor_ok: "constructor_ok G hp ihp (stk0 ! length apTs) C' z r" and c_fr: "correct_frame G hp ihp (rev apTs @ T0 # ST0, LT0) maxl0 ins0 (stk0, loc0, C0, sig0, pc0, r0)" and c_frs: "correct_frames G hp ihp phi rT0 sig0 z0 r0 frs'" apply simp apply (elim conjE exE) apply (rule that) apply assumption+ apply simp apply assumption+ apply simp apply ( (rule conjI,rule refl)+ ) apply (rule refl) apply assumption+ apply simp apply assumption done from c_fr obtain a_stk0: "approx_stk G hp ihp stk0 (rev apTs @ T0 # ST0)" and a_loc0: "approx_loc G hp ihp loc0 LT0" and cons0: "consistent_init stk0 loc0 (rev apTs @ T0 # ST0, LT0) ihp" and corr0: "fst sig0 = init \<longrightarrow> corresponds stk0 loc0 (rev apTs @ T0 # ST0, LT0) ihp (fst r0) (PartInit C0) \<and> (\<exists>l. fst r0 = Addr l \<and> hp l \<noteq> None \<and> (ihp l = PartInit C0 \<or> (\<exists>C'. ihp l = Init (Class C'))))" and pc0: "pc0 < length ins0" and lenloc0:"length loc0 = Suc (length (snd sig0) + maxl0)" by (unfold correct_frame_def) simp from pc0 wtjvm methd_C0 have wt0: "wt_instr (ins0!pc0) G C0 rT0 (phi C0 sig0) maxs0 (fst sig0 = init) (length ins0) et0 pc0" by - (rule wt_jvm_prog_impl_wt_instr) let ?z' = "if \<exists>D. T0 = PartInit D then True else z0" let ?ST' = "Init rT' # replace T0 (Init (theClass T0)) ST0" let ?LT' = "replace (OK T0) (OK (Init (theClass T0))) LT0" from ins0 apTs phi_pc0 is_init sig methd_C' wt0 obtain ST'' LT'' where Suc_pc0: "Suc pc0 < length ins0" and phi_Suc_pc0: "phi C0 sig0 ! Suc pc0 = Some ((ST'',LT''),?z')" and T0: "(\<exists>pc. T0 = UnInit C' pc) \<or> (T0 = PartInit C0 \<and> G \<turnstile> C0 \<prec>C1 C' \<and> ¬z0)" and less: "G \<turnstile> (?ST', ?LT') <=s (ST'',LT'')" apply (simp add: wt_instr_def) apply (erule disjE) apply simp apply (simp add: eff_def eff_bool_def norm_eff_def) apply (elim exE conjE) apply (clarsimp simp add: nth_append) apply blast done from a_stk0 obtain apts oX stk0' where stk0': "stk0 = apts @ oX # stk0'" "length apts = length apTs" and a_val: "approx_val G hp ihp oX (OK T0)" and a_stk: "approx_stk G hp ihp stk0' ST0" by - (drule approx_stk_append_lemma, auto) with apTs have oX_pos: "stk0!length pTs = oX" by (simp add: nth_append) let ?c = "snd r" let ?r' = "if r0 = (oX,Null) then (oX, ?c) else r0" let ?stk' = "rval#(replace oX ?c stk0')" let ?loc' = "replace oX ?c loc0" let ?f' = "(?stk',?loc',C0,sig0,Suc pc0,?r')" from stk apTs stk0' mthd ins sig f frs is_init state oX_pos have state': "state' = Norm (hp, ihp, ?f' # frs')" by (simp add: split_beta) from wtjvm obtain mb where "wf_prog mb G" by (simp add: wt_jvm_prog_def) from ctor_ok z apTs oX_pos a_val T0 obtain C'' D pc' a c fs1 fs3 where a: "oX = Addr a" and ihp_a: "ihp a = UnInit C'' pc' \<or> ihp a = PartInit D" and hp_a: "hp a = Some (C'', fs1)" and c: "snd r = Addr c" and ihp_c: "ihp c = Init (Class C'')" and hp_c: "hp c = Some (C'', fs3)" by (simp add: constructor_ok_def, clarify) auto from a_val a hp_a T0 have "G \<turnstile> C'' \<preceq>C C'\<and> (T0 = PartInit C0 \<longrightarrow> G \<turnstile> C'' \<preceq>C C0)" apply - apply (erule disjE) apply (clarsimp simp add: approx_val_def iconf_def) apply (clarsimp simp add: approx_val_def iconf_def) apply (simp add: conf_def) apply (rule rtrancl_trans, assumption) apply blast done with c hp_c ihp_c heap_ok T0 have a_val': "approx_val G hp ihp (snd r) (OK (Init (theClass T0)))" apply (simp add: approx_val_def iconf_def is_init_def) apply (erule disjE) apply clarsimp apply (rule conf_obj_AddrI, assumption+) apply clarsimp apply (rule conf_obj_AddrI, assumption+) done from stk0' cons0 T0 have corr: "corresponds stk0' loc0 (ST0,LT0) ihp oX T0" apply simp apply (erule disjE) apply (elim exE) apply (drule consistent_init_append) apply simp apply (drule consistent_init_corresponds_stk_cons) apply blast apply (simp add: corresponds_stk_cons) apply (drule consistent_init_append) apply simp apply (drule consistent_init_corresponds_stk_cons) apply blast apply (simp add: corresponds_stk_cons) done from a_val a_val' a_loc0 T0 corr have a_loc': "approx_loc G hp ihp ?loc' ?LT'" by (auto elim: approx_loc_replace simp add: corresponds_def) from wf T methd_C' a_val a_val' a_stk corr T0 val have a_stk': "approx_stk G hp ihp ?stk' ?ST'" apply - apply clarsimp apply (rule conjI) apply (clarsimp simp add: approx_val_def iconf_def init_le_Init2) apply (rule conf_widen, assumption+) apply (erule widen_trans, assumption) apply (unfold approx_stk_def) apply (erule disjE) apply (elim exE conjE) apply (drule approx_loc_replace) apply assumption back apply assumption apply blast apply (simp add: corresponds_def corr_stk_def) apply (simp add: replace_map_OK) apply (elim exE conjE) apply (drule approx_loc_replace) apply assumption back apply assumption apply blast apply (simp add: corresponds_def corr_stk_def) apply (simp add: replace_map_OK) done from stk0' apTs cons0 have "consistent_init stk0' loc0 (ST0,LT0) ihp" apply simp apply (drule consistent_init_append, simp) apply (erule consistent_init_pop) done with a_stk a_loc0 a_val have "consistent_init ?stk' ?loc' (?ST', ?LT') ihp" apply - apply (rule consistent_init_Init_stk) apply (erule consisten_init_replace) apply assumption+ apply (rule refl) done from this less have cons': "consistent_init ?stk' ?loc' (ST'',LT'') ihp" by (rule consistent_init_widen) from stk0' len apTs corr0 have "fst sig0 = init \<longrightarrow> corresponds (rval # stk0') loc0 (Init rT'#ST0, LT0) ihp (fst r0) (PartInit C0)" apply clarsimp apply (drule corresponds_append) apply simp apply (simp add: corresponds_stk_cons) done with a_stk a_loc0 a_val have "fst sig0 = init \<longrightarrow> corresponds ?stk' ?loc' (?ST', ?LT') ihp (fst r0) (PartInit C0)" apply - apply clarify apply (simp add: corresponds_stk_cons) apply (erule corresponds_replace) apply assumption+ apply simp apply blast done with less have corr': "fst sig0 = init \<longrightarrow> corresponds ?stk' ?loc' (ST'', LT'') ihp (fst r0) (PartInit C0)" apply - apply (rule impI, erule impE, assumption) apply (rule corresponds_widen) apply assumption+ apply blast done have fst_r': "fst ?r' = fst r0" by simp from lenloc0 a_loc' Suc_pc0 a_stk' cons' less fst_r' corr' corr0 have c_fr': "correct_frame G hp ihp (ST'', LT'') maxl0 ins0 ?f'" apply (unfold correct_frame_def) apply clarify apply (clarsimp simp add: sup_state_conv map_eq_Cons split del: split_if) apply (rule conjI) apply (rule approx_val_widen, assumption+) apply (rule conjI) apply (rule approx_stk_imp_approx_stk_sup, assumption+) apply (rule approx_loc_imp_approx_loc_sup, assumption+) done from c_frs have frs'1: "fst sig0 \<noteq> init \<Longrightarrow> correct_frames G hp ihp phi rT0 sig0 ?z' ?r' frs'" apply - apply (cases frs') apply simp apply (clarsimp split del: split_if) apply (intro exI conjI) apply assumption apply (rule refl) apply assumption apply assumption apply assumption done moreover have frs'2: "frs' = [] \<Longrightarrow> correct_frames G hp ihp phi rT0 sig0 ?z' ?r' frs'" by simp moreover { fix f'' frs'' assume cons: "frs' = f'' # frs''" assume sig0_in: "fst sig0 = init" { assume eq: "oX = fst r0" with corr0 sig0_in have "corresponds stk0 loc0 (rev apTs @ T0 # ST0, LT0) ihp oX (PartInit C0)" by simp with stk0' have "corresponds (oX#stk0') loc0 (T0#ST0, LT0) ihp oX (PartInit C0)" apply simp apply (rule corresponds_append) apply assumption apply simp done with a ihp_a eq corr0 sig0_in T0 have "ihp a = PartInit C0" by (clarsimp simp add: corresponds_stk_cons corr_val_def) with a T0 a_val have z0: "T0 = PartInit C0 \<and> ¬z0" by (auto simp add: approx_val_def iconf_def) from c_frs sig0_in z0 cons have "snd r0 = Null" apply - apply (drule correct_frames_ctor_ok) apply clarsimp apply (simp add: constructor_ok_def split_beta) done moreover have "r0 = (fst r0, snd r0)" by simp ultimately have eq_r0: "r0 = (oX, Null)" by (simp add: eq) with apTs oX_pos ctor_ok c_frs z cons have "correct_frames G hp ihp phi rT0 sig0 True (oX, ?c) frs'" apply (clarsimp split del: split_if) apply (intro exI conjI) apply assumption apply (rule refl) apply assumption apply assumption apply assumption apply (rule impI, erule impE, assumption) apply (rule constructor_ok_pass_val) apply assumption apply simp apply simp done with oX_pos apTs z0 eq_r0 have "correct_frames G hp ihp phi rT0 sig0 ?z' ?r' frs'" by simp } moreover { assume neq: "oX \<noteq> fst r0" with T0 stk0' corr0 sig0_in have "\<exists>pc'. T0 = UnInit C' pc'" apply simp apply (erule disjE) apply simp apply clarify apply (drule corresponds_append) apply simp apply (simp add: corresponds_stk_cons) done with c_frs apTs oX_pos neq have "correct_frames G hp ihp phi rT0 sig0 ?z' ?r' frs'" by clarsimp } ultimately have "correct_frames G hp ihp phi rT0 sig0 ?z' ?r' frs'" by blast } ultimately have "correct_frames G hp ihp phi rT0 sig0 ?z' ?r' frs'" by (cases frs', blast+) with state' heap_ok init_ok c_frs class_C0 methd_C0 phi_Suc_pc0 c_fr' prealloc have ?thesis by (unfold correct_state_def) simp } ultimately show "G,phi \<turnstile>JVM state'\<surd>" by (cases frs, blast+) qed lemma Return_correct: "\<lbrakk> wt_jvm_prog G phi; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Return; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (cases "fst sig = init") apply (rule Return_correct_init) apply assumption+ apply (rule Return_correct_not_init) apply simp apply assumption+ done lemmas [simp] = map_append lemma Goto_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Goto branch; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs2) apply (fast intro: approx_loc_imp_approx_loc_sup approx_stk_imp_approx_stk_sup consistent_init_widen_split corresponds_widen_split) done lemma Ifcmpeq_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Ifcmpeq branch; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs2) apply (rule conjI) apply (rule impI) apply simp apply (rule conjI) apply (rule approx_stk_imp_approx_stk_sup, assumption+) apply (rule conjI) apply (erule approx_loc_imp_approx_loc_sup, assumption+) apply (rule conjI) apply (drule consistent_init_pop)+ apply (erule consistent_init_widen_split, assumption+) apply (rule impI, erule impE, assumption, erule conjE) apply (drule corresponds_pop)+ apply (fast elim!: corresponds_widen_split) apply (rule impI) apply (rule conjI) apply (rule approx_stk_imp_approx_stk_sup, assumption+) apply (rule conjI) apply (erule approx_loc_imp_approx_loc_sup, assumption+) apply (rule conjI) apply (drule consistent_init_pop)+ apply (erule consistent_init_widen_split, assumption+) apply (rule impI, erule impE, assumption, erule conjE) apply (drule corresponds_pop)+ apply (fast elim!: corresponds_widen_split) done lemma Pop_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Pop; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs2) apply (fast intro: approx_loc_imp_approx_loc_sup approx_stk_imp_approx_stk_sup elim: consistent_init_widen_split corresponds_widen_split dest: consistent_init_pop corresponds_pop) done lemma Dup_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Dup; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs2 map_eq_Cons) apply (rule conjI) apply (erule approx_val_imp_approx_val_sup, assumption+) apply simp apply (rule conjI) apply (erule approx_val_imp_approx_val_sup, assumption+) apply simp apply (rule conjI) apply (blast intro: approx_stk_imp_approx_stk_sup) apply (rule conjI) apply (blast intro: approx_loc_imp_approx_loc_sup) apply (rule conjI) apply (drule consistent_init_Dup) apply (rule consistent_init_widen_split) apply assumption prefer 2 apply assumption apply simp apply (rule impI, erule impE, assumption, erule conjE) apply (drule corresponds_Dup) apply (erule corresponds_widen_split) prefer 2 apply assumption apply simp apply blast done lemma Dup_x1_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Dup_x1; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs2 map_eq_Cons) apply (rule conjI) apply (erule approx_val_imp_approx_val_sup, assumption+) apply simp apply (rule conjI) apply (erule approx_val_imp_approx_val_sup, assumption+) apply simp apply (rule conjI) apply (erule approx_val_imp_approx_val_sup, assumption+) apply simp apply (rule conjI) apply (blast intro: approx_stk_imp_approx_stk_sup) apply (rule conjI) apply (blast intro: approx_loc_imp_approx_loc_sup) apply (rule conjI) apply (drule consistent_init_Dup_x1) apply (rule consistent_init_widen_split) apply assumption prefer 2 apply assumption apply simp apply (rule impI, erule impE, assumption, erule conjE) apply (drule corresponds_Dup_x1) apply (erule corresponds_widen_split) prefer 2 apply assumption apply simp apply blast done lemma Dup_x2_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Dup_x2; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs2 map_eq_Cons) apply (rule conjI) apply (erule approx_val_imp_approx_val_sup, assumption+) apply simp apply (rule conjI) apply (erule approx_val_imp_approx_val_sup, assumption+) apply simp apply (rule conjI) apply (erule approx_val_imp_approx_val_sup, assumption+) apply simp apply (rule conjI) apply (erule approx_val_imp_approx_val_sup, assumption+) apply simp apply (rule conjI) apply (blast intro: approx_stk_imp_approx_stk_sup) apply (rule conjI) apply (blast intro: approx_loc_imp_approx_loc_sup) apply (rule conjI) apply (drule consistent_init_Dup_x2) apply (rule consistent_init_widen_split) apply assumption prefer 2 apply assumption apply simp apply (rule impI, erule impE, assumption, erule conjE) apply (drule corresponds_Dup_x2) apply (erule corresponds_widen_split) prefer 2 apply assumption apply simp apply blast done lemma Swap_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Swap; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs2 map_eq_Cons) apply (rule conjI) apply (erule approx_val_imp_approx_val_sup, assumption+) apply simp apply (rule conjI) apply (erule approx_val_imp_approx_val_sup, assumption+) apply simp apply (rule conjI) apply (blast intro: approx_stk_imp_approx_stk_sup) apply (rule conjI) apply (blast intro: approx_loc_imp_approx_loc_sup) apply (rule conjI) apply (drule consistent_init_Swap) apply (rule consistent_init_widen_split) apply assumption prefer 2 apply assumption apply simp apply (rule impI, erule impE, assumption, erule conjE) apply (drule corresponds_Swap) apply (erule corresponds_widen_split) prefer 2 apply assumption apply simp apply blast done lemma IAdd_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = IAdd; wt_instr (ins!pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (elim correctE, assumption) apply (clarsimp simp add: defs2 map_eq_Cons approx_val_def) apply (clarsimp simp add: iconf_def init_le_Init conf_def) apply (simp add: is_init_def) apply (drule consistent_init_pop)+ apply (simp add: corresponds_stk_cons) apply (blast intro: approx_stk_imp_approx_stk_sup approx_val_imp_approx_val_sup approx_loc_imp_approx_loc_sup corresponds_widen_split consistent_init_Init_stk consistent_init_widen_split) done lemma Throw_correct: "\<lbrakk> wf_prog wt G; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); ins ! pc = Throw; Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs) ; G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd>; fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs) = None \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" by simp text {* The next theorem collects the results of the sections above, i.e.~exception handling and the execution step for each instruction. It states type safety for single step execution: in welltyped programs, a conforming state is transformed into another conforming state when one instruction is executed. *} theorem instr_correct: "\<lbrakk> wt_jvm_prog G phi; method (G,C) sig = Some (C,rT,maxs,maxl,ins,et); Some state' = exec (G, None, hp, ihp, (stk,loc,C,sig,pc,r)#frs); G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (frule wt_jvm_prog_impl_wt_instr_cor) apply assumption+ apply (cases "fst (exec_instr (ins!pc) G hp ihp stk loc C sig pc r frs)") defer apply (erule xcpt_correct, assumption+) apply (cases "ins!pc") prefer 8 apply (rule Invoke_correct, assumption+) prefer 8 apply (rule Invoke_special_correct, assumption+) prefer 8 apply (rule Return_correct, assumption+) prefer 5 apply (rule Getfield_correct, assumption+) prefer 6 apply (rule Checkcast_correct, assumption+) apply (unfold wt_jvm_prog_def) apply (rule Load_correct, assumption+) apply (rule Store_correct, assumption+) apply (rule LitPush_correct, assumption+) apply (rule New_correct, assumption+) apply (rule Putfield_correct, assumption+) apply (rule Pop_correct, assumption+) apply (rule Dup_correct, assumption+) apply (rule Dup_x1_correct, assumption+) apply (rule Dup_x2_correct, assumption+) apply (rule Swap_correct, assumption+) apply (rule IAdd_correct, assumption+) apply (rule Goto_correct, assumption+) apply (rule Ifcmpeq_correct, assumption+) apply (rule Throw_correct, assumption+) done section {* Main *} lemma correct_state_impl_Some_method: "G,phi \<turnstile>JVM (None, hp, ihp, (stk,loc,C,sig,pc,r)#frs)\<surd> \<Longrightarrow> \<exists>meth. method (G,C) sig = Some(C,meth)" by (auto simp add: correct_state_def Let_def) lemma BV_correct_1 [rule_format]: "\<And>state. \<lbrakk> wt_jvm_prog G phi; G,phi \<turnstile>JVM state\<surd>\<rbrakk> \<Longrightarrow> exec (G,state) = Some state' \<longrightarrow> G,phi \<turnstile>JVM state'\<surd>" apply (simp only: split_tupled_all) apply (rename_tac xp hp ihp frs) apply (case_tac xp) apply (case_tac frs) apply simp apply (simp only: split_tupled_all) apply hypsubst apply (frule correct_state_impl_Some_method) apply (force intro: instr_correct) apply (case_tac frs) apply simp_all done lemma L0: "\<lbrakk> xp=None; frs\<noteq>[] \<rbrakk> \<Longrightarrow> (\<exists>state'. exec (G,xp,hp,ihp,frs) = Some state')" by (clarsimp simp add: neq_Nil_conv split_beta) lemma L1: "\<lbrakk>wt_jvm_prog G phi; G,phi \<turnstile>JVM (xp,hp,ihp,frs)\<surd>; xp=None; frs\<noteq>[]\<rbrakk> \<Longrightarrow> \<exists>state'. exec(G,xp,hp,ihp,frs) = Some state' \<and> G,phi \<turnstile>JVM state'\<surd>" apply (drule L0) apply assumption apply (fast intro: BV_correct_1) done theorem BV_correct [rule_format]: "\<lbrakk> wt_jvm_prog G phi; G \<turnstile> s -jvm\<rightarrow> t \<rbrakk> \<Longrightarrow> G,phi \<turnstile>JVM s\<surd> \<longrightarrow> G,phi \<turnstile>JVM t\<surd>" apply (unfold exec_all_def) apply (erule rtrancl_induct) apply simp apply (auto intro: BV_correct_1) done theorem BV_correct_implies_approx: "\<lbrakk> wt_jvm_prog G phi; G \<turnstile> s0 -jvm\<rightarrow> (None,hp,ihp,(stk,loc,C,sig,pc,r)#frs); G,phi \<turnstile>JVM s0 \<surd>\<rbrakk> \<Longrightarrow> \<exists>ST LT z. (phi C sig) ! pc = Some ((ST,LT),z) \<and> approx_stk G hp ihp stk ST \<and> approx_loc G hp ihp loc LT" apply (drule BV_correct) apply assumption+ apply (simp add: correct_state_def correct_frame_def split_def split: option.splits) apply (case_tac s) apply simp apply (case_tac s) apply simp done lemma fixes G :: jvm_prog ("\<Gamma>") assumes wf: "wf_prog wf_mb \<Gamma>" shows hconf_start: "\<Gamma> \<turnstile>h (start_heap \<Gamma>) \<surd>" apply (unfold hconf_def start_heap_def) apply (auto simp add: blank_def oconf_def split: split_if_asm) apply (simp add: fields_is_type [OF _ wf is_class_xcpt [OF wf]])+ done lemma fixes G :: jvm_prog ("\<Gamma>") assumes wf: "wf_prog wf_mb \<Gamma>" shows hinit_start: "h_init \<Gamma> (start_heap \<Gamma>) start_iheap" apply (unfold h_init_def start_heap_def start_iheap_def) apply (auto simp add: blank_def o_init_def l_init_def is_init_def split: split_if_asm) apply (auto simp add: init_vars_def map_of_map) done lemma consistent_init_start: "G \<turnstile> OK (Init (Class C)) <=o X \<Longrightarrow> consistent_init [] (Null#replicate n arbitrary) ([], X#replicate n Err) hp" apply (induct n) apply (auto simp add: consistent_init_def corresponds_def corr_stk_def corr_loc_def) done lemma fixes G :: jvm_prog ("\<Gamma>") and Phi :: prog_type ("\<Phi>") shows BV_correct_initial: "wt_jvm_prog \<Gamma> \<Phi> \<Longrightarrow> is_class \<Gamma> C \<Longrightarrow> method (\<Gamma>,C) (m,[]) = Some (C, b) \<Longrightarrow> m \<noteq> init \<Longrightarrow> \<Gamma>,\<Phi> \<turnstile>JVM start_state G C m \<surd>" apply (cases b) apply (unfold start_state_def) apply (unfold correct_state_def) apply (auto simp add: preallocated_start) apply (simp add: wt_jvm_prog_def hconf_start) apply (simp add: wt_jvm_prog_def hinit_start) apply (drule wt_jvm_prog_impl_wt_start, assumption+) apply (clarsimp simp add: wt_start_def) apply (auto simp add: correct_frame_def) apply (simp add: approx_stk_def sup_state_conv) defer apply (clarsimp simp add: sup_state_conv dest!: loc_widen_Err) apply (simp add: consistent_init_start) apply (auto simp add: sup_state_conv approx_val_def iconf_def is_init_def subtype_def dest!: widen_RefT split: err.splits split_if_asm init_ty.split) done theorem fixes G :: jvm_prog ("\<Gamma>") and Phi :: prog_type ("\<Phi>") assumes welltyped: "wt_jvm_prog \<Gamma> \<Phi>" and main: "is_class \<Gamma> C" "method (\<Gamma>,C) (m,[]) = Some (C, b)" "m \<noteq> init" shows typesafe: "G \<turnstile> start_state \<Gamma> C m -jvm\<rightarrow> s \<Longrightarrow> \<Gamma>,\<Phi> \<turnstile>JVM s \<surd>" proof - from welltyped main have "\<Gamma>,\<Phi> \<turnstile>JVM start_state \<Gamma> C m \<surd>" by (rule BV_correct_initial) moreover assume "G \<turnstile> start_state \<Gamma> C m -jvm\<rightarrow> s" ultimately show "\<Gamma>,\<Phi> \<turnstile>JVM s \<surd>" using welltyped by - (rule BV_correct) qed end
lemmas defs1:
correct_state G phi == %(xp, hp, ihp, frs). case xp of None => case frs of [] => True | f # fs => G |-h hp [ok] & h_init G hp ihp & preallocated hp ihp & (let (stk, loc, C, sig, pc, r) = f in EX rT maxs maxl ins et s z. is_class G C & method (G, C) sig = Some (C, rT, maxs, maxl, ins, et) & phi C sig ! pc = Some (s, z) & correct_frame G hp ihp s maxl ins f & correct_frames G hp ihp phi rT sig z r fs) | Some x => frs = []
correct_frame G hp i == %(ST, LT) maxl ins (stk, loc, C, sig, pc, r). approx_stk G hp i stk ST & approx_loc G hp i loc LT & consistent_init stk loc (ST, LT) i & (fst sig = init --> corresponds stk loc (ST, LT) i (fst r) (PartInit C) & (EX l. fst r = Addr l & hp l ~= None & (i l = PartInit C | (EX C'. i l = Init (Class C'))))) & pc < length ins & length loc = length (snd sig) + maxl + 1
G |- s1 <=s s2 == G |- map OK (fst s1) <=l map OK (fst s2) & G |- snd s1 <=l snd s2
wt_instr i G C rT phi mxs ini max_pc et pc == app i G C pc mxs rT ini et (phi ! pc) & (ALL (pc', s'):set (eff i G pc et (phi ! pc)). pc' < max_pc & G |- s' <=' phi ! pc')
eff i G pc et s == map (%pc'. (pc', norm_eff i G pc s)) (succs i pc) @ xcpt_eff i G pc s et
norm_eff i G pc == option_map (eff_bool i G pc)
eff_bool i G pc == %((ST, LT), z). (eff' (i, G, pc, ST, LT), if EX C p D. i = Invoke_special C init p & ST ! length p = PartInit D then True else z)
lemmas correctE:
[| G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok]; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); !!ST LT z. [| G |-h hp [ok]; h_init G hp ihp; preallocated hp ihp; is_class G C; phi C sig ! pc = Some ((ST, LT), z); correct_frame G hp ihp (ST, LT) maxl ins (stk, loc, C, sig, pc, r); correct_frames G hp ihp phi rT sig z r frs |] ==> P |] ==> P
[| correct_frame G hp ihp (ST, LT) maxl ins (stk, loc, C, sig, pc, r); [| approx_stk G hp ihp stk ST; approx_loc G hp ihp loc LT; consistent_init stk loc (ST, LT) ihp; fst sig = init --> corresponds stk loc (ST, LT) ihp (fst r) (PartInit C) & (EX l. fst r = Addr l & hp l ~= None & (ihp l = PartInit C | (EX C'. ihp l = Init (Class C')))); pc < length ins; length loc = length (snd sig) + maxl + 1 |] ==> P |] ==> P
lemmas widen_rules:
[| wf_prog wt G; approx_val G hp ihp v (OK T); G |- T <=i T' |] ==> approx_val G hp ihp v (OK T')
[| wf_prog wt G; approx_loc G hp ihp lvars lt; G |- lt <=l lt' |] ==> approx_loc G hp ihp lvars lt'
[| wf_prog wt G; approx_stk G hp ihp lvars st; G |- map OK st <=l map OK st' |] ==> approx_stk G hp ihp lvars st'
lemmas
(ALL x. P x) = (ALL a b. P (a, b))
lemma wt_jvm_prog_impl_wt_instr_cor:
[| wt_jvm_prog G phi; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc
lemma exec_instr_xcpt:
(fst (exec_instr i G hp ihp stk vars Cl sig pc z frs) = Some xcp) = (EX stk'. exec_instr i G hp ihp stk vars Cl sig pc z frs = (Some xcp, hp, ihp, (stk', vars, Cl, sig, pc, z) # frs))
lemma in_match_any:
match_exception_table G xcpt pc et = Some pc' ==> EX C. C : set (match_any G pc et) & G |- xcpt <=C C & match_exception_table G C pc et = Some pc'
lemma match_et_imp_match:
match_exception_table G X pc et = Some handler ==> match G X pc et = [X]
lemma uncaught_xcpt_correct:
[| wt_jvm_prog G phi; xcp = Addr adr; hp adr = Some T; is_init hp ihp xcp; G,phi |-JVM Norm (hp, ihp, f # frs) [ok] |] ==> G,phi |-JVM find_handler G (Some xcp) hp ihp frs [ok]
lemma exec_instr_xcpt_hp:
[| fst (exec_instr (ins ! pc) G hp ihp stk vars Cl sig pc r frs) = Some xcp; wt_instr (ins ! pc) G Cl rT (phi C sig) maxs (fst sig = init) (length ins) et pc; G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> EX adr T. xcp = Addr adr & hp adr = Some T & is_init hp ihp xcp
lemma cname_of_xcp:
[| preallocated hp ihp; xcp = Addr (XcptRef x) |] ==> cname_of hp xcp = Xcpt x
lemma prealloc_is_init:
preallocated hp ihp ==> is_init hp ihp (Addr (XcptRef x))
lemma xcpt_correct:
[| wt_jvm_prog G phi; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; fst (exec_instr (ins ! pc) G hp ihp stk loc C sig pc r frs) = Some xcp; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemmas
(x ~= Err) = (EX a. x = OK a)
lemma Load_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Load idx; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma Store_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Store idx; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma LitPush_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = LitPush v; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma Cast_conf2:
[| wf_prog ok G; G,h |- v ::<= RefT rt; cast_ok G C h v; G |- Class C <= T; is_class G C |] ==> G,h |- v ::<= T
lemmas defs2:
correct_state G phi == %(xp, hp, ihp, frs). case xp of None => case frs of [] => True | f # fs => G |-h hp [ok] & h_init G hp ihp & preallocated hp ihp & (let (stk, loc, C, sig, pc, r) = f in EX rT maxs maxl ins et s z. is_class G C & method (G, C) sig = Some (C, rT, maxs, maxl, ins, et) & phi C sig ! pc = Some (s, z) & correct_frame G hp ihp s maxl ins f & correct_frames G hp ihp phi rT sig z r fs) | Some x => frs = []
correct_frame G hp i == %(ST, LT) maxl ins (stk, loc, C, sig, pc, r). approx_stk G hp i stk ST & approx_loc G hp i loc LT & consistent_init stk loc (ST, LT) i & (fst sig = init --> corresponds stk loc (ST, LT) i (fst r) (PartInit C) & (EX l. fst r = Addr l & hp l ~= None & (i l = PartInit C | (EX C'. i l = Init (Class C'))))) & pc < length ins & length loc = length (snd sig) + maxl + 1
G |- s1 <=s s2 == G |- map OK (fst s1) <=l map OK (fst s2) & G |- snd s1 <=l snd s2
wt_instr i G C rT phi mxs ini max_pc et pc == app i G C pc mxs rT ini et (phi ! pc) & (ALL (pc', s'):set (eff i G pc et (phi ! pc)). pc' < max_pc & G |- s' <=' phi ! pc')
eff i G pc et s == map (%pc'. (pc', norm_eff i G pc s)) (succs i pc) @ xcpt_eff i G pc s et
norm_eff i G pc == option_map (eff_bool i G pc)
eff_bool i G pc == %((ST, LT), z). (eff' (i, G, pc, ST, LT), if EX C p D. i = Invoke_special C init p & ST ! length p = PartInit D then True else z)
raise_system_xcpt b x == if b then Some (Addr (XcptRef x)) else None
lemma Checkcast_correct:
[| wt_jvm_prog G phi; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Checkcast D; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok]; fst (exec_instr (ins ! pc) G hp ihp stk loc C sig pc r frs) = None |] ==> G,phi |-JVM state' [ok]
lemma Getfield_correct:
[| wt_jvm_prog G phi; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Getfield F D; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok]; fst (exec_instr (ins ! pc) G hp ihp stk loc C sig pc r frs) = None |] ==> G,phi |-JVM state' [ok]
lemma Putfield_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Putfield F D; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok]; fst (exec_instr (ins ! pc) G hp ihp stk loc C sig pc r frs) = None |] ==> G,phi |-JVM state' [ok]
lemma New_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = New X; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok]; fst (exec_instr (ins ! pc) G hp ihp stk loc C sig pc r frs) = None |] ==> G,phi |-JVM state' [ok]
lemmas
(EX x. P x) = (EX a b. P (a, b))
lemma Invoke_correct:
[| wt_jvm_prog G phi; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Invoke C' mn pTs; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok]; fst (exec_instr (ins ! pc) G hp ihp stk loc C sig pc r frs) = None |] ==> G,phi |-JVM state' [ok]
lemma Invoke_special_correct:
[| wt_jvm_prog G phi; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Invoke_special C' mn pTs; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok]; fst (exec_instr (ins ! pc) G hp ihp stk loc C sig pc r frs) = None |] ==> G,phi |-JVM state' [ok]
lemmas
map f (xs @ ys) = map f xs @ map f ys
lemma Return_correct_not_init:
[| fst sig ~= init; wt_jvm_prog G phi; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Return; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma Return_correct_init:
[| fst sig = init; wt_jvm_prog G phi; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Return; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma Return_correct:
[| wt_jvm_prog G phi; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Return; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemmas
map f (xs @ ys) = map f xs @ map f ys
lemma Goto_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Goto branch; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma Ifcmpeq_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Ifcmpeq branch; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma Pop_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Pop; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma Dup_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Dup; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma Dup_x1_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Dup_x1; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma Dup_x2_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Dup_x2; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma Swap_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Swap; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma IAdd_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = IAdd; wt_instr (ins ! pc) G C rT (phi C sig) maxs (fst sig = init) (length ins) et pc; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma Throw_correct:
[| wf_prog wt G; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); ins ! pc = Throw; Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok]; fst (exec_instr (ins ! pc) G hp ihp stk loc C sig pc r frs) = None |] ==> G,phi |-JVM state' [ok]
theorem instr_correct:
[| wt_jvm_prog G phi; method (G, C) sig = Some (C, rT, maxs, maxl, ins, et); Some state' = exec (G, Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs)); G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] |] ==> G,phi |-JVM state' [ok]
lemma correct_state_impl_Some_method:
G,phi |-JVM Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs) [ok] ==> EX meth. method (G, C) sig = Some (C, meth)
lemma BV_correct_1:
[| wt_jvm_prog G phi; G,phi |-JVM state [ok]; exec (G, state) = Some state' |] ==> G,phi |-JVM state' [ok]
lemma L0:
[| xp = None; frs ~= [] |] ==> EX state'. exec (G, xp, hp, ihp, frs) = Some state'
lemma L1:
[| wt_jvm_prog G phi; G,phi |-JVM (xp, hp, ihp, frs) [ok]; xp = None; frs ~= [] |] ==> EX state'. exec (G, xp, hp, ihp, frs) = Some state' & G,phi |-JVM state' [ok]
theorem BV_correct:
[| wt_jvm_prog G phi; G |- s -jvm-> t; G,phi |-JVM s [ok] |] ==> G,phi |-JVM t [ok]
theorem BV_correct_implies_approx:
[| wt_jvm_prog G phi; G |- s0 -jvm-> Norm (hp, ihp, (stk, loc, C, sig, pc, r) # frs); G,phi |-JVM s0 [ok] |] ==> EX ST LT z. phi C sig ! pc = Some ((ST, LT), z) & approx_stk G hp ihp stk ST & approx_loc G hp ihp loc LT
lemma hconf_start:
wf_prog wf_mb G ==> G |-h start_heap G [ok]
lemma hinit_start:
wf_prog wf_mb G ==> h_init G (start_heap G) start_iheap
lemma consistent_init_start:
G |- OK (Init (Class C)) <=o X ==> consistent_init [] (Null # replicate n arbitrary) ([], X # replicate n Err) hp
lemma BV_correct_initial:
[| wt_jvm_prog G Phi; is_class G C; method (G, C) (m, []) = Some (C, b); m ~= init |] ==> G,Phi |-JVM start_state G C m [ok]
theorem typesafe:
[| wt_jvm_prog G Phi; is_class G C; method (G, C) (m, []) = Some (C, b); m ~= init; G |- start_state G C m -jvm-> s |] ==> G,Phi |-JVM s [ok]