diff --git a/thys/JinjaDCI/BV/BVExec.thy b/thys/JinjaDCI/BV/BVExec.thy --- a/thys/JinjaDCI/BV/BVExec.thy +++ b/thys/JinjaDCI/BV/BVExec.thy @@ -1,253 +1,506 @@ (* Title: JinjaDCI/BV/BVExec.thy Author: Tobias Nipkow, Gerwin Klein, Susannah Mansky Copyright 2000 TUM, 2020 UIUC Based on the Jinja theory BV/BVExec.thy by Tobias Nipkow and Gerwin Klein *) section \ Kildall for the JVM \label{sec:JVM} \ theory BVExec -imports Jinja.Abstract_BV TF_JVM +imports Jinja.Abstract_BV TF_JVM Jinja.Typing_Framework_2 begin definition kiljvm :: "jvm_prog \ nat \ nat \ ty \ instr list \ ex_table \ ty\<^sub>i' err list \ ty\<^sub>i' err list" where "kiljvm P mxs mxl T\<^sub>r is xt \ kildall (JVM_SemiType.le P mxs mxl) (JVM_SemiType.sup P mxs mxl) (exec P mxs T\<^sub>r xt is)" definition wt_kildall :: "jvm_prog \ cname \ staticb \ ty list \ ty \ nat \ nat \ instr list \ ex_table \ bool" where - "wt_kildall P C' b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \ - 0 < size is \ + "wt_kildall P C' b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \ (b = Static \ b = NonStatic) \ + 0 < size is \ (let first = Some ([],(case b of Static \ [] | NonStatic \ [OK (Class C')]) @(map OK Ts)@(replicate mxl\<^sub>0 Err)); start = (OK first)#(replicate (size is - 1) (OK None)); result = kiljvm P mxs ((case b of Static \ 0 | NonStatic \ 1)+size Ts+mxl\<^sub>0) T\<^sub>r is xt start in \n < size is. result!n \ Err)" definition wf_jvm_prog\<^sub>k :: "jvm_prog \ bool" where "wf_jvm_prog\<^sub>k P \ wf_prog (\P C' (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). wt_kildall P C' b Ts T\<^sub>r mxs mxl\<^sub>0 is xt) P" +context start_context +begin + +lemma Cons_less_Conss3 [simp]: + "x#xs [\\<^bsub>r\<^esub>] y#ys = (x \\<^bsub>r\<^esub> y \ xs [\\<^bsub>r\<^esub>] ys \ x = y \ xs [\\<^bsub>r\<^esub>] ys)" + apply (unfold lesssub_def ) + apply auto + apply (insert sup_state_opt_err) + apply (unfold lesssub_def lesub_def sup_state_opt_def sup_state_def sup_ty_opt_def) + apply (simp only: JVM_le_unfold ) + apply fastforce + done + +lemma acc_le_listI3 [intro!]: + " acc r \ acc (Listn.le r)" +apply (unfold acc_def) +apply (subgoal_tac + "wf(UN n. {(ys,xs). size xs = n \ size ys = n \ xs <_(Listn.le r) ys})") + apply (erule wf_subset) + apply (blast intro: lesssub_lengthD) +apply (rule wf_UN) + prefer 2 + apply (rename_tac m n) + apply (case_tac "m=n") + apply simp + apply (fast intro!: equals0I dest: not_sym) +apply (rename_tac n) +apply (induct_tac n) + apply (simp add: lesssub_def cong: conj_cong) +apply (rename_tac k) +apply (simp add: wf_eq_minimal del: r_def f_def step_def A_def) +apply (simp (no_asm) add: length_Suc_conv cong: conj_cong del: r_def f_def step_def A_def) +apply clarify +apply (rename_tac M m) +apply (case_tac "\x xs. size xs = k \ x#xs \ M") + prefer 2 + apply (erule thin_rl) + apply (erule thin_rl) + apply blast +apply (erule_tac x = "{a. \xs. size xs = k \ a#xs:M}" in allE) +apply (erule impE) + apply blast +apply (thin_tac "\x xs. P x xs" for P) +apply clarify +apply (rename_tac maxA xs) +apply (erule_tac x = "{ys. size ys = size xs \ maxA#ys \ M}" in allE) +apply (erule impE) + apply blast +apply clarify +apply (thin_tac "m \ M") +apply (thin_tac "maxA#xs \ M") +apply (rule bexI) + prefer 2 + apply assumption +apply clarify +apply (simp del: r_def f_def step_def A_def) +apply blast + done + + +lemma wf_jvm: " wf {(ss', ss). ss [\\<^bsub>r\<^esub>] ss'}" + apply (insert acc_le_listI3 acc_JVM [OF wf]) + by (simp add: acc_def r_def) + +lemma iter_properties_bv[rule_format]: +shows "\ \p\w0. p < n; ss0 \ list n A; \p w0 \ stable r step ss0 p \ \ + iter f step ss0 w0 = (ss',w') \ + ss' \ list n A \ stables r step ss' \ ss0 [\\<^sub>r] ss' \ + (\ts\list n A. ss0 [\\<^sub>r] ts \ stables r step ts \ ss' [\\<^sub>r] ts)" +(*<*) (is "PROP ?P") + +proof - + show "PROP ?P" + apply (insert semi bounded_step exec_pres_type step_mono[OF wf]) + apply (unfold iter_def stables_def) + + apply (rule_tac P = "\(ss,w). + ss \ list n A \ (\p w \ stable r step ss p) \ ss0 [\\<^sub>r] ss \ + (\ts\list n A. ss0 [\\<^sub>r] ts \ stables r step ts \ ss [\\<^sub>r] ts) \ + (\p\w. p < n)" and + r = "{(ss',ss) . ss [\\<^sub>r] ss'} <*lex*> finite_psubset" + in while_rule) + + \ \Invariant holds initially:\ + apply (simp add:stables_def semilat_Def del: n_def A_def r_def f_def step_def) + apply (blast intro:le_list_refl') + + \ \Invariant is preserved:\ + apply(simp add: stables_def split_paired_all del: A_def r_def f_def step_def n_def) + apply(rename_tac ss w) + apply(subgoal_tac "(SOME p. p \ w) \ w") + prefer 2 apply (fast intro: someI) + apply(subgoal_tac "\(q,t) \ set (step (SOME p. p \ w) (ss ! (SOME p. p \ w))). q < length ss \ t \ A") + prefer 2 + apply clarify + apply (rule conjI) + apply(clarsimp, blast dest!: boundedD) + apply (subgoal_tac "(SOME p. p \ w) < n") + apply (subgoal_tac "(ss ! (SOME p. p \ w)) \ A") + apply (fastforce simp only:n_def dest:pres_typeD ) + apply simp + apply simp + apply (subst decomp_propa) + apply blast + apply (simp del:A_def r_def f_def step_def n_def) + apply (rule conjI) + apply (rule Semilat.merges_preserves_type[OF Semilat.intro, OF semi]) + apply blast + apply clarify + apply (rule conjI) + apply(clarsimp, blast dest!: boundedD) + apply (erule pres_typeD) + prefer 3 + apply assumption + apply (erule listE_nth_in) + apply blast + apply (simp only:n_def) + apply (rule conjI) + apply clarify + apply (subgoal_tac "ss \ list (length is) A" "\p\w. p < (length is) " "\p<(length is). p \ w \ stable r step ss p " + "p < length is") + apply (blast intro!: Semilat.stable_pres_lemma[OF Semilat.intro, OF semi]) + apply (simp only:n_def) + apply (simp only:n_def) + apply (simp only:n_def) + apply (simp only:n_def) + apply (rule conjI) + apply (subgoal_tac "ss \ list (length is) A" + "\(q,t)\set (step (SOME p. p \ w) (ss ! (SOME p. p \ w))). q < length is \ t \ A" + "ss [\\<^bsub>r\<^esub>] merges f (step (SOME p. p \ w) (ss ! (SOME p. p \ w))) ss" "ss0\ list (size is) A" + "merges f (step (SOME p. p \ w) (ss ! (SOME p. p \ w))) ss \ list (size is) A" + "ss \list (size is) A" "order r A" "ss0 [\\<^bsub>r\<^esub>] ss ") + apply (blast dest: le_list_trans) + apply simp + apply (simp only:semilat_Def) + apply (simp only:n_def) + apply (fastforce simp only: n_def dest:Semilat.merges_preserves_type[OF Semilat.intro, OF semi] ) + apply (simp only:n_def) + apply (blast intro:Semilat.merges_incr[OF Semilat.intro, OF semi]) + apply (subgoal_tac "length ss = n") + apply (simp only:n_def) + apply (subgoal_tac "ss \list n A") + defer + apply simp + apply (simp only:n_def) + prefer 5 + apply (simp only:listE_length n_def) + apply(rule conjI) + apply (clarsimp simp del: A_def r_def f_def step_def) + apply (blast intro!: Semilat.merges_bounded_lemma[OF Semilat.intro, OF semi]) + apply (subgoal_tac "bounded step n") + apply (blast dest!: boundedD) + apply (simp only:n_def) + + \ \Postcondition holds upon termination:\ + apply(clarsimp simp add: stables_def split_paired_all) + + \ \Well-foundedness of the termination relation:\ + apply (rule wf_lex_prod) + apply (simp only:wf_jvm) + apply (rule wf_finite_psubset) + + \ \Loop decreases along termination relation:\ + apply(simp add: stables_def split_paired_all del: A_def r_def f_def step_def) + apply(rename_tac ss w) + apply(subgoal_tac "(SOME p. p \ w) \ w") + prefer 2 apply (fast intro: someI) + apply(subgoal_tac "\(q,t) \ set (step (SOME p. p \ w) (ss ! (SOME p. p \ w))). q < length ss \ t \ A") + prefer 2 + apply clarify + apply (rule conjI) + apply(clarsimp, blast dest!: boundedD) + apply (erule pres_typeD) + prefer 3 + apply assumption + apply (erule listE_nth_in) + apply blast + apply blast + apply (subst decomp_propa) + apply blast + apply clarify + apply (simp del: listE_length A_def r_def f_def step_def + add: lex_prod_def finite_psubset_def + bounded_nat_set_is_finite) + apply (rule termination_lemma) + apply (insert Semilat.intro) + apply assumption+ + defer + apply assumption + defer + apply clarsimp + done +qed + +(*>*) + + +lemma kildall_properties_bv: +shows "\ ss0 \ list n A \ \ + kildall r f step ss0 \ list n A \ + stables r step (kildall r f step ss0) \ + ss0 [\\<^sub>r] kildall r f step ss0 \ + (\ts\list n A. ss0 [\\<^sub>r] ts \ stables r step ts \ + kildall r f step ss0 [\\<^sub>r] ts)" +(*<*) (is "PROP ?P") +proof - + show "PROP ?P" + apply (unfold kildall_def) + apply(case_tac "iter f step ss0 (unstables r step ss0)") + apply (simp del:r_def f_def n_def step_def A_def) + apply (rule iter_properties_bv) + apply (simp_all add: unstables_def stable_def) + done +qed + +end + theorem (in start_context) is_bcv_kiljvm: "is_bcv r Err step (size is) A (kiljvm P mxs mxl T\<^sub>r is xt)" (*<*) + apply (insert wf) + apply (unfold kiljvm_def) + apply (fold r_def f_def step_def_exec n_def) + apply(unfold is_bcv_def wt_step_def) + apply(insert semi kildall_properties_bv) + apply(simp only:stables_def) + apply clarify + apply(subgoal_tac "kildall r f step \s\<^sub>0 \ list n A") + prefer 2 + apply (fastforce intro: kildall_properties_bv) + apply (rule iffI) + apply (rule_tac x = "kildall r f step \s\<^sub>0" in bexI) + apply (rule conjI) + apply (fastforce intro: kildall_properties_bv) + apply (force intro: kildall_properties_bv) + apply simp + apply clarify + apply(subgoal_tac "kildall r f step \s\<^sub>0!pa <=_r \s!pa") + defer + apply (blast intro!: le_listD less_lengthI) + apply (subgoal_tac "\s!pa \ Err") + defer + apply simp + apply (rule ccontr) + apply (simp only:top_def r_def JVM_le_unfold) + apply fastforce + done +(* proof - let ?n = "length is" have "Semilat A r f" using semilat_JVM[OF wf] by (simp add: Semilat.intro sl_def2) moreover have "acc r" using wf by simp blast moreover have "top r Err" by (simp add: JVM_le_unfold) moreover have "pres_type step ?n A" by (rule exec_pres_type) moreover have "bounded step ?n" by (rule bounded_step) moreover have "mono r step ?n A" using step_mono[OF wf] by simp ultimately have "is_bcv r Err step ?n A (kildall r f step)" by(rule is_bcv_kildall) moreover have kileq: "kiljvm P mxs mxl T\<^sub>r is xt = kildall r f step" using f_def kiljvm_def r_def step_def_exec by blast ultimately show ?thesis by simp qed +*) (*>*) (* FIXME: move? *) lemma subset_replicate [intro?]: "set (replicate n x) \ {x}" by (induct n) auto lemma in_set_replicate: assumes "x \ set (replicate n y)" shows "x = y" (*<*) proof - note assms also have "set (replicate n y) \ {y}" .. finally show ?thesis by simp qed (*>*) lemma (in start_context) start_in_A [intro?]: "0 < size is \ start \ list (size is) A" using Ts C (*<*) proof(cases b) qed (force simp: JVM_states_unfold intro!: listI list_appendI dest!: in_set_replicate)+ (*>*) theorem (in start_context) wt_kil_correct: assumes wtk: "wt_kildall P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt" shows "\\s. wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" (*<*) proof - from wtk obtain res where result: "res = kiljvm P mxs mxl T\<^sub>r is xt start" and success: "\n < size is. res!n \ Err" and - instrs: "0 < size is" + instrs: "0 < size is" and + stab: "b = Static \ b = NonStatic" by (unfold wt_kildall_def) simp have bcv: "is_bcv r Err step (size is) A (kiljvm P mxs mxl T\<^sub>r is xt)" by (rule is_bcv_kiljvm) from instrs have "start \ list (size is) A" .. with bcv success result have "\ts\list (size is) A. start [\\<^sub>r] ts \ wt_step r Err step ts" by (unfold is_bcv_def) blast then obtain \s' where in_A: "\s' \ list (size is) A" and s: "start [\\<^sub>r] \s'" and w: "wt_step r Err step \s'" by blast hence wt_err_step: "wt_err_step (sup_state_opt P) step \s'" by (simp add: wt_err_step_def JVM_le_Err_conv) from in_A have l: "size \s' = size is" by simp moreover { from in_A have "check_types P mxs mxl \s'" by (simp add: check_types_def) also from w have "\x \ set \s'. x \ Err" by (auto simp add: wt_step_def all_set_conv_all_nth) hence [symmetric]: "map OK (map ok_val \s') = \s'" by (auto intro!: map_idI simp add: wt_step_def) finally have "check_types P mxs mxl (map OK (map ok_val \s'))" . } moreover { from s have "start!0 \\<^sub>r \s'!0" by (rule le_listD) simp moreover from instrs w l have "\s'!0 \ Err" by (unfold wt_step_def) simp then obtain \s0 where "\s'!0 = OK \s0" by auto ultimately have "wt_start P C b Ts mxl\<^sub>0 (map ok_val \s')" using l instrs by (unfold wt_start_def) (cases b; simp add: lesub_def JVM_le_Err_conv Err.le_def) } moreover from in_A have "set \s' \ A" by simp with wt_err_step bounded_step have "wt_app_eff (sup_state_opt P) app eff (map ok_val \s')" by (auto intro: wt_err_imp_wt_app_eff simp add: l) ultimately have "wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (map ok_val \s')" - using instrs by (simp add: wt_method_def2 check_types_def del: map_map) + using instrs stab by (simp add: wt_method_def2 check_types_def del: map_map) thus ?thesis by blast qed (*>*) theorem (in start_context) wt_kil_complete: assumes wtm: "wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" shows "wt_kildall P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt" (*<*) proof - from wtm obtain instrs: "0 < size is" and length: "length \s = length is" and ck_type: "check_types P mxs mxl (map OK \s)" and wt_start: "wt_start P C b Ts mxl\<^sub>0 \s" and - app_eff: "wt_app_eff (sup_state_opt P) app eff \s" - by (simp add: wt_method_def2 check_types_def) + app_eff: "wt_app_eff (sup_state_opt P) app eff \s" and + stab: "b = Static \ b = NonStatic" + by (simp add: wt_method_def2 check_types_def ) from ck_type have in_A: "set (map OK \s) \ A" by (simp add: check_types_def) with app_eff in_A bounded_step have "wt_err_step (sup_state_opt P) (err_step (size \s) app eff) (map OK \s)" by - (erule wt_app_eff_imp_wt_err, auto simp add: exec_def length states_def) hence wt_err: "wt_err_step (sup_state_opt P) step (map OK \s)" by (simp add: length) have is_bcv: "is_bcv r Err step (size is) A (kiljvm P mxs mxl T\<^sub>r is xt)" by (rule is_bcv_kiljvm) moreover from instrs have "start \ list (size is) A" .. moreover let ?\s = "map OK \s" have less_\s: "start [\\<^sub>r] ?\s" proof (rule le_listI) from length instrs show "length start = length (map OK \s)" by simp next fix n from wt_start have "P \ ok_val (start!0) \' \s!0" by (cases b; simp add: wt_start_def) moreover from instrs length have "0 < length \s" by simp ultimately have "start!0 \\<^sub>r ?\s!0" by (simp add: JVM_le_Err_conv lesub_def) moreover { fix n' have "OK None \\<^sub>r ?\s!n" by (auto simp add: JVM_le_Err_conv Err.le_def lesub_def split: err.splits) hence "\n = Suc n'; n < size start\ \ start!n \\<^sub>r ?\s!n" by simp } ultimately show "n < size start \ start!n \\<^sub>r ?\s!n" by (cases n, blast+) qed moreover from ck_type length have "?\s \ list (size is) A" by (auto intro!: listI simp add: check_types_def) moreover from wt_err have "wt_step r Err step ?\s" by (simp add: wt_err_step_def JVM_le_Err_conv) ultimately have "\p. p < size is \ kiljvm P mxs mxl T\<^sub>r is xt start ! p \ Err" by (unfold is_bcv_def) blast with instrs - show "wt_kildall P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt" by (unfold wt_kildall_def) simp + show "wt_kildall P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt" + using start_context_intro_auxi[OF staticb] using stab by (unfold wt_kildall_def) simp qed (*>*) theorem jvm_kildall_correct: "wf_jvm_prog\<^sub>k P = wf_jvm_prog P" (*<*) proof - let ?\ = "\C M. let (C,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)) = method P C M in SOME \s. wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" let ?A = "\P C' (M, b, Ts, T\<^sub>r, mxs, mxl\<^sub>0, is, xt). wt_kildall P C' b Ts T\<^sub>r mxs mxl\<^sub>0 is xt" let ?B\<^sub>\ = "\\. (\P C (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C M))" show ?thesis proof(rule iffI) \ \soundness\ assume wt: "wf_jvm_prog\<^sub>k P" - then have "wf_prog ?A P" by(simp add: wf_jvm_prog\<^sub>k_def) + then have wt': "wf_prog ?A P" by(simp add: wf_jvm_prog\<^sub>k_def) moreover { fix wf_md C M b Ts Ca T m bd - assume "wf_prog wf_md P" and sees: "P \ Ca sees M, b : Ts\T = m in Ca" and - "set Ts \ types P" and "bd = (M, b, Ts, T, m)" and - "?A P Ca bd" - then have "(?B\<^sub>\ ?\) P Ca bd" using sees_method_is_class[OF sees] - by (auto dest!: start_context.wt_kil_correct [OF start_context.intro] + + assume ass1: "wf_prog wf_md P" and sees: "P \ Ca sees M, b : Ts\T = m in Ca" and + ass2: "set Ts \ types P" and ass3: "bd = (M, b, Ts, T, m)" and + ass4: "?A P Ca bd" + from ass3 ass4 have stab: "b = Static \ b = NonStatic" by (simp add:wt_kildall_def) + from ass1 sees ass2 ass3 ass4 have "(?B\<^sub>\ ?\) P Ca bd" using sees_method_is_class[OF sees] + by (auto dest!: start_context.wt_kil_correct[OF start_context_intro_auxi[OF stab]] intro: someI) } ultimately have "wf_prog (?B\<^sub>\ ?\) P" by(rule wf_prog_lift) then have "wf_jvm_prog\<^bsub>?\\<^esub> P" by (simp add: wf_jvm_prog_phi_def) thus "wf_jvm_prog P" by (unfold wf_jvm_prog_def) fast next \ \completeness\ - assume wt: "wf_jvm_prog P" + + assume wt: "wf_jvm_prog P" then obtain \ where "wf_prog (?B\<^sub>\ \) P" by(clarsimp simp: wf_jvm_prog_def wf_jvm_prog_phi_def) moreover { fix wf_md C M b Ts Ca T m bd - assume "wf_prog wf_md P" and sees: "P \ Ca sees M, b : Ts\T = m in Ca" and - "set Ts \ types P" and "bd = (M, b, Ts, T, m)" and - "(?B\<^sub>\ \) P Ca bd" - then have "?A P Ca bd" using sees_method_is_class[OF sees] - by (auto intro!: start_context.wt_kil_complete start_context.intro) + assume ass1: "wf_prog wf_md P" and sees: "P \ Ca sees M, b : Ts\T = m in Ca" and + ass2: "set Ts \ types P" and ass3: "bd = (M, b, Ts, T, m)" and + ass4: "(?B\<^sub>\ \) P Ca bd" + from ass3 ass4 have stab: "b = Static \ b = NonStatic" by (simp add:wt_method_def) + from ass1 sees ass2 ass3 ass4 have "?A P Ca bd" using sees_method_is_class[OF sees] using JVM_sl.staticb + by (auto intro!: start_context.wt_kil_complete start_context_intro_auxi[OF stab]) } ultimately have "wf_prog ?A P" by(rule wf_prog_lift) thus "wf_jvm_prog\<^sub>k P" by (simp add: wf_jvm_prog\<^sub>k_def) qed qed (*>*) end diff --git a/thys/JinjaDCI/BV/BVSpec.thy b/thys/JinjaDCI/BV/BVSpec.thy --- a/thys/JinjaDCI/BV/BVSpec.thy +++ b/thys/JinjaDCI/BV/BVSpec.thy @@ -1,113 +1,113 @@ (* Title: JinjaDCI/BV/BVSpec.thy Author: Cornelia Pusch, Gerwin Klein, Susannah Mansky Copyright 1999 Technische Universitaet Muenchen, 2019-20 UIUC Based on the Jinja theory BV/BVSpec.thy by Tobias Nipkow *) section \ The Bytecode Verifier \label{sec:BVSpec} \ theory BVSpec imports Effect begin text \ This theory contains a specification of the BV. The specification describes correct typings of method bodies; it corresponds to type \emph{checking}. \ definition \ \The method type only contains declared classes:\ check_types :: "'m prog \ nat \ nat \ ty\<^sub>i' err list \ bool" where "check_types P mxs mxl \s \ set \s \ states P mxs mxl" \ \An instruction is welltyped if it is applicable and its effect\ \ \is compatible with the type at all successor instructions:\ definition wt_instr :: "['m prog,ty,nat,pc,ex_table,instr,pc,ty\<^sub>m] \ bool" ("_,_,_,_,_ \ _,_ :: _" [60,0,0,0,0,0,0,61] 60) where "P,T,mxs,mpc,xt \ i,pc :: \s \ app i P mxs T pc mpc xt (\s!pc) \ (\(pc',\') \ set (eff i P pc xt (\s!pc)). P \ \' \' \s!pc')" \ \The type at @{text "pc=0"} conforms to the method calling convention:\ definition wt_start :: "['m prog,cname,staticb,ty list,nat,ty\<^sub>m] \ bool" where "wt_start P C b Ts mxl\<^sub>0 \s \ case b of NonStatic \ P \ Some ([],OK (Class C)#map OK Ts@replicate mxl\<^sub>0 Err) \' \s!0 | Static \ P \ Some ([],map OK Ts@replicate mxl\<^sub>0 Err) \' \s!0" \ \A method is welltyped if the body is not empty,\ \ \if the method type covers all instructions and mentions\ \ \declared classes only, if the method calling convention is respected, and\ \ \if all instructions are welltyped.\ definition wt_method :: "['m prog,cname,staticb,ty list,ty,nat,nat,instr list, ex_table,ty\<^sub>m] \ bool" where - "wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s \ + "wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s \ (b = Static \ b = NonStatic) \ 0 < size is \ size \s = size is \ check_types P mxs ((case b of Static \ 0 | NonStatic \ 1)+size Ts+mxl\<^sub>0) (map OK \s) \ wt_start P C b Ts mxl\<^sub>0 \s \ (\pc < size is. P,T\<^sub>r,mxs,size is,xt \ is!pc,pc :: \s)" \ \A program is welltyped if it is wellformed and all methods are welltyped\ definition wf_jvm_prog_phi :: "ty\<^sub>P \ jvm_prog \ bool" ("wf'_jvm'_prog\<^bsub>_\<^esub>") where "wf_jvm_prog\<^bsub>\\<^esub> \ wf_prog (\P C (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C M))" definition wf_jvm_prog :: "jvm_prog \ bool" where "wf_jvm_prog P \ \\. wf_jvm_prog\<^bsub>\\<^esub> P" lemma wt_jvm_progD: "wf_jvm_prog\<^bsub>\\<^esub> P \ \wt. wf_prog wt P" (*<*) by (unfold wf_jvm_prog_phi_def, blast) (*>*) lemma wt_jvm_prog_impl_wt_instr: assumes wf: "wf_jvm_prog\<^bsub>\\<^esub> P" and sees: "P \ C sees M,b:Ts \ T = (mxs,mxl\<^sub>0,ins,xt) in C" and pc: "pc < size ins" shows "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" (*<*) proof - have wfm: "wf_prog (\P C (M, b, Ts, T\<^sub>r, mxs, mxl\<^sub>0, is, xt). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C M)) P" using wf by (unfold wf_jvm_prog_phi_def) show ?thesis using sees_wf_mdecl[OF wfm sees] pc by (simp add: wf_mdecl_def wt_method_def) qed (*>*) lemma wt_jvm_prog_impl_wt_start: assumes wf: "wf_jvm_prog\<^bsub>\\<^esub> P" and sees: "P \ C sees M,b:Ts \ T = (mxs,mxl\<^sub>0,ins,xt) in C" shows "0 < size ins \ wt_start P C b Ts mxl\<^sub>0 (\ C M)" (*<*) proof - have wfm: "wf_prog (\P C (M, b, Ts, T\<^sub>r, mxs, mxl\<^sub>0, is, xt). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C M)) P" using wf by (unfold wf_jvm_prog_phi_def) show ?thesis using sees_wf_mdecl[OF wfm sees] by (simp add: wf_mdecl_def wt_method_def) qed (*>*) lemma wf_jvm_prog_nclinit: assumes wtp: "wf_jvm_prog\<^bsub>\\<^esub> P" and meth: "P \ C sees M, b : Ts\T = (mxs, mxl\<^sub>0, ins, xt) in D" and wt: "P,T,mxs,size ins,xt \ ins!pc,pc :: \ C M" and pc: "pc < length ins" and \: "\ C M ! pc = Some(ST,LT)" and ins: "ins ! pc = Invokestatic C\<^sub>0 M\<^sub>0 n" shows "M\<^sub>0 \ clinit" using assms by(simp add: wf_jvm_prog_phi_def wt_instr_def app_def) end diff --git a/thys/JinjaDCI/BV/JVM_SemiType.thy b/thys/JinjaDCI/BV/JVM_SemiType.thy --- a/thys/JinjaDCI/BV/JVM_SemiType.thy +++ b/thys/JinjaDCI/BV/JVM_SemiType.thy @@ -1,256 +1,388 @@ (* Title: HOL/MicroJava/BV/JVM.thy Author: Gerwin Klein Copyright 2000 TUM *) section \ The JVM Type System as Semilattice \ theory JVM_SemiType imports SemiType begin type_synonym ty\<^sub>l = "ty err list" type_synonym ty\<^sub>s = "ty list" type_synonym ty\<^sub>i = "ty\<^sub>s \ ty\<^sub>l" type_synonym ty\<^sub>i' = "ty\<^sub>i option" type_synonym ty\<^sub>m = "ty\<^sub>i' list" type_synonym ty\<^sub>P = "mname \ cname \ ty\<^sub>m" definition stk_esl :: "'c prog \ nat \ ty\<^sub>s esl" where "stk_esl P mxs \ upto_esl mxs (SemiType.esl P)" definition loc_sl :: "'c prog \ nat \ ty\<^sub>l sl" where "loc_sl P mxl \ Listn.sl mxl (Err.sl (SemiType.esl P))" definition sl :: "'c prog \ nat \ nat \ ty\<^sub>i' err sl" where "sl P mxs mxl \ Err.sl(Opt.esl(Product.esl (stk_esl P mxs) (Err.esl(loc_sl P mxl))))" definition states :: "'c prog \ nat \ nat \ ty\<^sub>i' err set" where "states P mxs mxl \ fst(sl P mxs mxl)" definition le :: "'c prog \ nat \ nat \ ty\<^sub>i' err ord" where "le P mxs mxl \ fst(snd(sl P mxs mxl))" definition sup :: "'c prog \ nat \ nat \ ty\<^sub>i' err binop" where "sup P mxs mxl \ snd(snd(sl P mxs mxl))" definition sup_ty_opt :: "['c prog,ty err,ty err] \ bool" ("_ \ _ \\<^sub>\ _" [71,71,71] 70) where "sup_ty_opt P \ Err.le (subtype P)" definition sup_state :: "['c prog,ty\<^sub>i,ty\<^sub>i] \ bool" ("_ \ _ \\<^sub>i _" [71,71,71] 70) where "sup_state P \ Product.le (Listn.le (subtype P)) (Listn.le (sup_ty_opt P))" definition sup_state_opt :: "['c prog,ty\<^sub>i',ty\<^sub>i'] \ bool" ("_ \ _ \'' _" [71,71,71] 70) where "sup_state_opt P \ Opt.le (sup_state P)" abbreviation sup_loc :: "['c prog,ty\<^sub>l,ty\<^sub>l] \ bool" ("_ \ _ [\\<^sub>\] _" [71,71,71] 70) where "P \ LT [\\<^sub>\] LT' \ list_all2 (sup_ty_opt P) LT LT'" notation (ASCII) sup_ty_opt ("_ |- _ <=T _" [71,71,71] 70) and sup_state ("_ |- _ <=i _" [71,71,71] 70) and sup_state_opt ("_ |- _ <=' _" [71,71,71] 70) and sup_loc ("_ |- _ [<=T] _" [71,71,71] 70) subsection "Unfolding" lemma JVM_states_unfold: "states P mxs mxl \ err(opt((Union {list n (types P) |n. n <= mxs}) \ list mxl (err(types P))))" (*<*) apply (unfold states_def sl_def Opt.esl_def Err.sl_def stk_esl_def loc_sl_def Product.esl_def Listn.sl_def upto_esl_def SemiType.esl_def Err.esl_def) apply simp done (*>*) lemma JVM_le_unfold: "le P m n \ Err.le(Opt.le(Product.le(Listn.le(subtype P))(Listn.le(Err.le(subtype P)))))" (*<*) apply (unfold le_def sl_def Opt.esl_def Err.sl_def stk_esl_def loc_sl_def Product.esl_def Listn.sl_def upto_esl_def SemiType.esl_def Err.esl_def) apply simp done (*>*) lemma sl_def2: "JVM_SemiType.sl P mxs mxl \ (states P mxs mxl, JVM_SemiType.le P mxs mxl, JVM_SemiType.sup P mxs mxl)" (*<*) by (unfold JVM_SemiType.sup_def states_def JVM_SemiType.le_def) simp (*>*) lemma JVM_le_conv: "le P m n (OK t1) (OK t2) = P \ t1 \' t2" (*<*) by (simp add: JVM_le_unfold Err.le_def lesub_def sup_state_opt_def sup_state_def sup_ty_opt_def) (*>*) lemma JVM_le_Err_conv: "le P m n = Err.le (sup_state_opt P)" (*<*) by (unfold sup_state_opt_def sup_state_def sup_ty_opt_def JVM_le_unfold) simp (*>*) lemma err_le_unfold [iff]: "Err.le r (OK a) (OK b) = r a b" (*<*) by (simp add: Err.le_def lesub_def) (*>*) subsection \ Semilattice \ - +lemma order_sup_state_opt' [intro, simp]: + "wf_prog wf_mb P \ + order (sup_state_opt P) (opt ((\ {list n (types P) |n. n \ mxs} ) \ list (Suc (length Ts + mxl\<^sub>0)) (err (types P))))" +(*<*) + apply (unfold sup_state_opt_def sup_state_def sup_ty_opt_def ) + apply (blast intro:order_le_prodI) \\ use Listn.thy.order_listI2 \ + done +(*<*) +lemma order_sup_state_opt'' [intro, simp]: + "wf_prog wf_mb P \ + order (sup_state_opt P) (opt ((\ {list n (types P) |n. n \ mxs} ) \ list ((length Ts + mxl\<^sub>0)) (err (types P))))" +(*<*) + apply (unfold sup_state_opt_def sup_state_def sup_ty_opt_def ) + apply (blast intro:order_le_prodI) \\ use Listn.thy.order_listI2 \ + done +(*<*) +(* lemma order_sup_state_opt [intro, simp]: "wf_prog wf_mb P \ order (sup_state_opt P)" (*<*) by (unfold sup_state_opt_def sup_state_def sup_ty_opt_def) blast (*>*) +*) lemma semilat_JVM [intro?]: "wf_prog wf_mb P \ semilat (JVM_SemiType.sl P mxs mxl)" (*<*) apply (unfold JVM_SemiType.sl_def stk_esl_def loc_sl_def) apply (blast intro: err_semilat_Product_esl err_semilat_upto_esl Listn_sl err_semilat_JType_esl) done (*>*) -lemma acc_JVM [intro]: - "wf_prog wf_mb P \ acc (JVM_SemiType.le P mxs mxl)" -(*<*) by (unfold JVM_le_unfold) blast (*>*) - - subsection \ Widening with @{text "\"} \ lemma subtype_refl[iff]: "subtype P t t" (*<*) by (simp add: fun_of_def) (*>*) lemma sup_ty_opt_refl [iff]: "P \ T \\<^sub>\ T" (*<*) apply (unfold sup_ty_opt_def) apply (fold lesub_def) apply (rule le_err_refl) apply (simp add: lesub_def) done (*>*) lemma Err_any_conv [iff]: "P \ Err \\<^sub>\ T = (T = Err)" (*<*) by (unfold sup_ty_opt_def) (rule Err_le_conv [simplified lesub_def]) (*>*) lemma any_Err [iff]: "P \ T \\<^sub>\ Err" (*<*) by (unfold sup_ty_opt_def) (rule le_Err [simplified lesub_def]) (*>*) lemma OK_OK_conv [iff]: "P \ OK T \\<^sub>\ OK T' = P \ T \ T'" (*<*) by (simp add: sup_ty_opt_def fun_of_def) (*>*) lemma any_OK_conv [iff]: "P \ X \\<^sub>\ OK T' = (\T. X = OK T \ P \ T \ T')" (*<*) apply (unfold sup_ty_opt_def) apply (rule le_OK_conv [simplified lesub_def]) done (*>*) lemma OK_any_conv: "P \ OK T \\<^sub>\ X = (X = Err \ (\T'. X = OK T' \ P \ T \ T'))" (*<*) apply (unfold sup_ty_opt_def) apply (rule OK_le_conv [simplified lesub_def]) done (*>*) lemma sup_ty_opt_trans [intro?, trans]: "\P \ a \\<^sub>\ b; P \ b \\<^sub>\ c\ \ P \ a \\<^sub>\ c" (*<*) by (auto intro: widen_trans simp add: sup_ty_opt_def Err.le_def lesub_def fun_of_def split: err.splits) (*>*) subsection "Stack and Registers" lemma stk_convert: "P \ ST [\] ST' = Listn.le (subtype P) ST ST'" (*<*) by (simp add: Listn.le_def lesub_def) (*>*) lemma sup_loc_refl [iff]: "P \ LT [\\<^sub>\] LT" (*<*) by (rule list_all2_refl) simp (*>*) lemmas sup_loc_Cons1 [iff] = list_all2_Cons1 [of "sup_ty_opt P"] for P lemma sup_loc_def: "P \ LT [\\<^sub>\] LT' \ Listn.le (sup_ty_opt P) LT LT'" (*<*) by (simp add: Listn.le_def lesub_def) (*>*) lemma sup_loc_widens_conv [iff]: "P \ map OK Ts [\\<^sub>\] map OK Ts' = P \ Ts [\] Ts'" (*<*) by (simp add: list_all2_map1 list_all2_map2) (*>*) lemma sup_loc_trans [intro?, trans]: "\P \ a [\\<^sub>\] b; P \ b [\\<^sub>\] c\ \ P \ a [\\<^sub>\] c" (*<*) by (rule list_all2_trans, rule sup_ty_opt_trans) (*>*) subsection "State Type" lemma sup_state_conv [iff]: "P \ (ST,LT) \\<^sub>i (ST',LT') = (P \ ST [\] ST' \ P \ LT [\\<^sub>\] LT')" (*<*) by (auto simp add: sup_state_def stk_convert lesub_def Product.le_def sup_loc_def) (*>*) lemma sup_state_conv2: "P \ s1 \\<^sub>i s2 = (P \ fst s1 [\] fst s2 \ P \ snd s1 [\\<^sub>\] snd s2)" (*<*) by (cases s1, cases s2) simp (*>*) lemma sup_state_refl [iff]: "P \ s \\<^sub>i s" (*<*) by (auto simp add: sup_state_conv2) (*>*) lemma sup_state_trans [intro?, trans]: "\P \ a \\<^sub>i b; P \ b \\<^sub>i c\ \ P \ a \\<^sub>i c" (*<*) by (auto intro: sup_loc_trans widens_trans simp add: sup_state_conv2) (*>*) lemma sup_state_opt_None_any [iff]: "P \ None \' s" (*<*) by (simp add: sup_state_opt_def Opt.le_def) (*>*) lemma sup_state_opt_any_None [iff]: "P \ s \' None = (s = None)" (*<*) by (simp add: sup_state_opt_def Opt.le_def) (*>*) lemma sup_state_opt_Some_Some [iff]: "P \ Some a \' Some b = P \ a \\<^sub>i b" (*<*) by (simp add: sup_state_opt_def Opt.le_def lesub_def) (*>*) lemma sup_state_opt_any_Some: "P \ (Some s) \' X = (\s'. X = Some s' \ P \ s \\<^sub>i s')" (*<*) by (simp add: sup_state_opt_def Opt.le_def lesub_def) (*>*) lemma sup_state_opt_refl [iff]: "P \ s \' s" (*<*) by (simp add: sup_state_opt_def Opt.le_def lesub_def) (*>*) lemma sup_state_opt_trans [intro?, trans]: "\P \ a \' b; P \ b \' c\ \ P \ a \' c" (*<*) apply (unfold sup_state_opt_def Opt.le_def lesub_def) apply (simp del: split_paired_All) apply (rule sup_state_trans, assumption+) done (*>*) + +lemma sup_state_opt_err : "(Err.le (sup_state_opt P)) s s" + apply (unfold JVM_le_unfold Product.le_def Opt.le_def Err.le_def lesssub_def lesub_def Listn.le_def) + apply (auto split: err.splits) + done + +lemma Cons_less_Conss1 [simp]: + "x#xs [\\<^bsub>subtype P\<^esub>] y#ys = (x \\<^bsub>subtype P\<^esub> y \ xs [\\<^bsub>subtype P\<^esub>] ys \ x = y \ xs [\\<^bsub>subtype P\<^esub>] ys)" + apply (unfold lesssub_def ) + apply auto + apply (simp add:lesssub_def lesub_def) \\widen_refl, subtype_refl \ + done + +lemma Cons_less_Conss2 [simp]: + "x#xs [\\<^bsub>Err.le (subtype P)\<^esub>] y#ys = (x \\<^bsub>Err.le (subtype P)\<^esub> y \ xs [\\<^bsub>Err.le (subtype P)\<^esub>] ys \ x = y \ xs [\\<^bsub>Err.le (subtype P)\<^esub>] ys)" + apply (unfold lesssub_def ) + apply auto + apply (simp add:lesssub_def lesub_def Err.le_def split: err.splits) + done + +lemma acc_le_listI1 [intro!]: + " acc (subtype P) \ acc (Listn.le (subtype P))" + (*<*) +apply (unfold acc_def) +apply (subgoal_tac + "wf(UN n. {(ys,xs). size xs = n \ size ys = n \ xs <_(Listn.le (subtype P)) ys})") + apply (erule wf_subset) + + apply (blast intro: lesssub_lengthD) +apply (rule wf_UN) + prefer 2 + apply (rename_tac m n) + apply (case_tac "m=n") + apply simp + apply (fast intro!: equals0I dest: not_sym) +apply (rename_tac n) +apply (induct_tac n) + apply (simp add: lesssub_def cong: conj_cong) +apply (rename_tac k) +apply (simp add: wf_eq_minimal) +apply (simp (no_asm) add: length_Suc_conv cong: conj_cong) +apply clarify +apply (rename_tac M m) +apply (case_tac "\x xs. size xs = k \ x#xs \ M") + prefer 2 + apply (erule thin_rl) + apply (erule thin_rl) + apply blast +apply (erule_tac x = "{a. \xs. size xs = k \ a#xs:M}" in allE) +apply (erule impE) + apply blast +apply (thin_tac "\x xs. P x xs" for P) +apply clarify +apply (rename_tac maxA xs) +apply (erule_tac x = "{ys. size ys = size xs \ maxA#ys \ M}" in allE) +apply (erule impE) + apply blast +apply clarify +apply (thin_tac "m \ M") +apply (thin_tac "maxA#xs \ M") +apply (rule bexI) + prefer 2 + apply assumption +apply clarify +apply simp +apply blast + done + +lemma acc_le_listI2 [intro!]: + " acc (Err.le (subtype P)) \ acc (Listn.le (Err.le (subtype P)))" + (*<*) +apply (unfold acc_def) +apply (subgoal_tac + "wf(UN n. {(ys,xs). size xs = n \ size ys = n \ xs <_(Listn.le (Err.le (subtype P))) ys})") + apply (erule wf_subset) + + apply (blast intro: lesssub_lengthD) +apply (rule wf_UN) + prefer 2 + apply (rename_tac m n) + apply (case_tac "m=n") + apply simp + apply (fast intro!: equals0I dest: not_sym) +apply (rename_tac n) +apply (induct_tac n) + apply (simp add: lesssub_def cong: conj_cong) +apply (rename_tac k) +apply (simp add: wf_eq_minimal) +apply (simp (no_asm) add: length_Suc_conv cong: conj_cong) +apply clarify +apply (rename_tac M m) +apply (case_tac "\x xs. size xs = k \ x#xs \ M") + prefer 2 + apply (erule thin_rl) + apply (erule thin_rl) + apply blast +apply (erule_tac x = "{a. \xs. size xs = k \ a#xs:M}" in allE) +apply (erule impE) + apply blast +apply (thin_tac "\x xs. P x xs" for P) +apply clarify +apply (rename_tac maxA xs) +apply (erule_tac x = "{ys. size ys = size xs \ maxA#ys \ M}" in allE) +apply (erule impE) + apply blast +apply clarify +apply (thin_tac "m \ M") +apply (thin_tac "maxA#xs \ M") +apply (rule bexI) + prefer 2 + apply assumption +apply clarify +apply simp +apply blast + done + +lemma acc_JVM [intro]: + "wf_prog wf_mb P \ acc (JVM_SemiType.le P mxs mxl)" +(*<*) by (unfold JVM_le_unfold) blast (*>*) \\ use acc_listI1, acc_listI2 \ + end diff --git a/thys/JinjaDCI/BV/LBVJVM.thy b/thys/JinjaDCI/BV/LBVJVM.thy --- a/thys/JinjaDCI/BV/LBVJVM.thy +++ b/thys/JinjaDCI/BV/LBVJVM.thy @@ -1,245 +1,250 @@ (* Title: JinjaDCI/BV/LBVJVM.thy Author: Tobias Nipkow, Gerwin Klein, Susannah Mansky Copyright 2000 TUM, 2020 UIUC Based on the Jinja theory BV/LBVJVM.thy by Tobias Nipkow and Gerwin Klein *) section \ LBV for the JVM \label{sec:JVM} \ theory LBVJVM imports Jinja.Abstract_BV TF_JVM begin type_synonym prog_cert = "cname \ mname \ ty\<^sub>i' err list" definition check_cert :: "jvm_prog \ nat \ nat \ nat \ ty\<^sub>i' err list \ bool" where "check_cert P mxs mxl n cert \ check_types P mxs mxl cert \ size cert = n+1 \ (\i Err) \ cert!n = OK None" definition lbvjvm :: "jvm_prog \ nat \ nat \ ty \ ex_table \ ty\<^sub>i' err list \ instr list \ ty\<^sub>i' err \ ty\<^sub>i' err" where "lbvjvm P mxs maxr T\<^sub>r et cert bs \ wtl_inst_list bs cert (JVM_SemiType.sup P mxs maxr) (JVM_SemiType.le P mxs maxr) Err (OK None) (exec P mxs T\<^sub>r et bs) 0" definition wt_lbv :: "jvm_prog \ cname \ staticb \ ty list \ ty \ nat \ nat \ ex_table \ ty\<^sub>i' err list \ instr list \ bool" where - "wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 et cert ins \ + "wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 et cert ins \ (b = Static \ b = NonStatic) \ check_cert P mxs ((case b of Static \ 0 | NonStatic \ 1)+size Ts+mxl\<^sub>0) (size ins) cert \ 0 < size ins \ (let start = Some ([],(case b of Static \ [] | NonStatic \ [OK (Class C)]) @((map OK Ts))@(replicate mxl\<^sub>0 Err)); result = lbvjvm P mxs ((case b of Static \ 0 | NonStatic \ 1)+size Ts+mxl\<^sub>0) T\<^sub>r et cert ins (OK start) in result \ Err)" definition wt_jvm_prog_lbv :: "jvm_prog \ prog_cert \ bool" where "wt_jvm_prog_lbv P cert \ wf_prog (\P C (mn,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,ins,et)). wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 et (cert C mn) ins) P" definition mk_cert :: "jvm_prog \ nat \ ty \ ex_table \ instr list \ ty\<^sub>m \ ty\<^sub>i' err list" where "mk_cert P mxs T\<^sub>r et bs phi \ make_cert (exec P mxs T\<^sub>r et bs) (map OK phi) (OK None)" definition prg_cert :: "jvm_prog \ ty\<^sub>P \ prog_cert" where "prg_cert P phi C mn \ let (C,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,ins,et)) = method P C mn in mk_cert P mxs T\<^sub>r et ins (phi C mn)" lemma check_certD [intro?]: "check_cert P mxs mxl n cert \ cert_ok cert n Err (OK None) (states P mxs mxl)" by (unfold cert_ok_def check_cert_def check_types_def) auto lemma (in start_context) wt_lbv_wt_step: assumes lbv: "wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 xt cert is" shows "\\s \ list (size is) A. wt_step r Err step \s \ OK first \\<^sub>r \s!0" (*<*) proof - from wf have "semilat (JVM_SemiType.sl P mxs mxl)" .. hence "semilat (A, r, f)" by (simp add: sl_def2) moreover have "top r Err" by (simp add: JVM_le_Err_conv) moreover have "Err \ A" by (simp add: JVM_states_unfold) moreover have "bottom r (OK None)" by (simp add: JVM_le_Err_conv bottom_def lesub_def Err.le_def split: err.split) moreover have "OK None \ A" by (simp add: JVM_states_unfold) moreover note bounded_step moreover from lbv have "cert_ok cert (size is) Err (OK None) A" by (unfold wt_lbv_def) (auto dest: check_certD) moreover note exec_pres_type moreover from lbv have "wtl_inst_list is cert f r Err (OK None) step 0 (OK first) \ Err" by (cases b; simp add: wt_lbv_def lbvjvm_def step_def_exec [symmetric]) moreover note first_in_A moreover from lbv have "0 < size is" by (simp add: wt_lbv_def) ultimately show ?thesis by (rule lbvs.wtl_sound_strong [OF lbvs.intro, OF lbv.intro lbvs_axioms.intro, OF Semilat.intro lbv_axioms.intro]) qed (*>*) lemma (in start_context) wt_lbv_wt_method: assumes lbv: "wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 xt cert is" shows "\\s. wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" (*<*) proof - - from lbv have l: "is \ []" by (simp add: wt_lbv_def) + from lbv have l: "is \ []" and + stab: "b = Static \ b = NonStatic" by (auto simp add: wt_lbv_def) moreover from wf lbv C Ts obtain \s where list: "\s \ list (size is) A" and step: "wt_step r Err step \s" and start: "OK first \\<^sub>r \s!0" by (blast dest: wt_lbv_wt_step) from list have [simp]: "size \s = size is" by simp have "size (map ok_val \s) = size is" by simp moreover from l have 0: "0 < size \s" by simp with step obtain \s0 where "\s!0 = OK \s0" by (unfold wt_step_def) blast with start 0 have "wt_start P C b Ts mxl\<^sub>0 (map ok_val \s)" by (cases b; simp add: wt_start_def JVM_le_Err_conv lesub_def Err.le_def) moreover { from list have "check_types P mxs mxl \s" by (simp add: check_types_def) also from step have "\x \ set \s. x \ Err" by (auto simp add: all_set_conv_all_nth wt_step_def) hence [symmetric]: "map OK (map ok_val \s) = \s" by (auto intro!: map_idI) finally have "check_types P mxs mxl (map OK (map ok_val \s))" . } moreover { note bounded_step moreover from list have "set \s \ A" by simp moreover from step have "wt_err_step (sup_state_opt P) step \s" by (simp add: wt_err_step_def JVM_le_Err_conv) ultimately have "wt_app_eff (sup_state_opt P) app eff (map ok_val \s)" by (auto intro: wt_err_imp_wt_app_eff simp add: exec_def states_def) } ultimately have "wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (map ok_val \s)" by (simp add: wt_method_def2 check_types_def del: map_map) thus ?thesis .. qed (*>*) lemma (in start_context) wt_method_wt_lbv: assumes wt: "wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" defines [simp]: "cert \ mk_cert P mxs T\<^sub>r xt is \s" shows "wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 xt cert is" (*<*) proof - let ?\s = "map OK \s" let ?cert = "make_cert step ?\s (OK None)" from wt obtain 0: "0 < size is" and size: "size is = size ?\s" and ck_types: "check_types P mxs mxl ?\s" and wt_start: "wt_start P C b Ts mxl\<^sub>0 \s" and app_eff: "wt_app_eff (sup_state_opt P) app eff \s" by (force simp add: wt_method_def2 check_types_def) from wf have "semilat (JVM_SemiType.sl P mxs mxl)" .. hence "semilat (A, r, f)" by (simp add: sl_def2) moreover have "top r Err" by (simp add: JVM_le_Err_conv) moreover have "Err \ A" by (simp add: JVM_states_unfold) moreover have "bottom r (OK None)" by (simp add: JVM_le_Err_conv bottom_def lesub_def Err.le_def split: err.split) moreover have "OK None \ A" by (simp add: JVM_states_unfold) moreover from wf have "mono r step (size is) A" by (rule step_mono) hence "mono r step (size ?\s) A" by (simp add: size) moreover from exec_pres_type have "pres_type step (size ?\s) A" by (simp add: size) moreover from ck_types have \s_in_A: "set ?\s \ A" by (simp add: check_types_def) hence "\pc. pc < size ?\s \ ?\s!pc \ A \ ?\s!pc \ Err" by auto moreover from bounded_step have "bounded step (size ?\s)" by (simp add: size) moreover have "OK None \ Err" by simp moreover from bounded_step size \s_in_A app_eff have "wt_err_step (sup_state_opt P) step ?\s" by (auto intro: wt_app_eff_imp_wt_err simp add: exec_def states_def) hence "wt_step r Err step ?\s" by (simp add: wt_err_step_def JVM_le_Err_conv) moreover from 0 size have "0 < size \s" by auto hence "?\s!0 = OK (\s!0)" by simp with wt_start have "OK first \\<^sub>r ?\s!0" by (cases b; clarsimp simp add: wt_start_def lesub_def Err.le_def JVM_le_Err_conv) moreover note first_in_A moreover have "OK first \ Err" by simp moreover note size ultimately have "wtl_inst_list is ?cert f r Err (OK None) step 0 (OK first) \ Err" by (rule lbvc.wtl_complete [OF lbvc.intro, OF lbv.intro lbvc_axioms.intro, OF Semilat.intro lbv_axioms.intro]) moreover from 0 size have "\s \ []" by auto moreover from ck_types have "check_types P mxs mxl ?cert" by (fastforce simp: make_cert_def check_types_def JVM_states_unfold dest!: nth_mem) moreover note 0 size - ultimately show ?thesis + ultimately show ?thesis using staticb by (simp add: wt_lbv_def lbvjvm_def mk_cert_def step_def_exec [symmetric] check_cert_def make_cert_def nth_append) qed (*>*) + theorem jvm_lbv_correct: "wt_jvm_prog_lbv P Cert \ wf_jvm_prog P" (*<*) proof - let ?\ = "\C mn. let (C,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)) = method P C mn in SOME \s. wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s" let ?A = "\P C (mn,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,ins,et)). wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 et (Cert C mn) ins" let ?B = "\P C (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (?\ C M)" assume wt: "wt_jvm_prog_lbv P Cert" then have "wf_prog ?A P" by(simp add: wt_jvm_prog_lbv_def) moreover { fix wf_md C M b Ts Ca T m bd - assume "wf_prog wf_md P" and sees: "P \ Ca sees M, b : Ts\T = m in Ca" and - "set Ts \ types P" and "bd = (M, b, Ts, T, m)" and - "?A P Ca bd" - then have "?B P Ca bd" using sees_method_is_class[OF sees] - by (auto dest!: start_context.wt_lbv_wt_method [OF start_context.intro] - intro: someI) + + assume ass1: "wf_prog wf_md P" and sees: "P \ Ca sees M, b : Ts\T = m in Ca" and + ass2: "set Ts \ types P" and ass3: "bd = (M, b, Ts, T, m)" and + ass4: "?A P Ca bd" + from ass3 ass4 have stab: "b = Static \ b = NonStatic" by (simp add:wt_lbv_def) + from ass1 sees ass2 ass3 ass4 have "?B P Ca bd" using sees_method_is_class[OF sees] + by (auto dest!: start_context.wt_lbv_wt_method [OF start_context_intro_auxi[OF stab]] + intro: someI) } ultimately have "wf_prog ?B P" by(rule wf_prog_lift) hence "wf_jvm_prog\<^bsub>?\\<^esub> P" by (simp add: wf_jvm_prog_phi_def) thus ?thesis by (unfold wf_jvm_prog_def) blast qed (*>*) theorem jvm_lbv_complete: assumes wt: "wf_jvm_prog\<^bsub>\\<^esub> P" shows "wt_jvm_prog_lbv P (prg_cert P \)" (*<*) proof - let ?cert = "prg_cert P \" let ?A = "\P C (M,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,is,xt)). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (\ C M)" let ?B = "\P C (mn,b,Ts,T\<^sub>r,(mxs,mxl\<^sub>0,ins,et)). wt_lbv P C b Ts T\<^sub>r mxs mxl\<^sub>0 et (?cert C mn) ins" from wt have "wf_prog ?A P" by(clarsimp simp: wf_jvm_prog_def wf_jvm_prog_phi_def) moreover { fix wf_md C M b Ts Ca T m bd - assume "wf_prog wf_md P" and sees: "P \ Ca sees M, b : Ts\T = m in Ca" and - "set Ts \ types P" and "bd = (M, b, Ts, T, m)" and - "?A P Ca bd" - then have "?B P Ca bd" using sees_method_is_class[OF sees] + assume ass1: "wf_prog wf_md P" and sees: "P \ Ca sees M, b : Ts\T = m in Ca" and + ass2: "set Ts \ types P" and ass3: "bd = (M, b, Ts, T, m)" and + ass4: "?A P Ca bd" + from ass3 ass4 have stab: "b = Static \ b = NonStatic" by (simp add:wt_method_def) + from ass1 sees ass2 ass3 ass4 have "?B P Ca bd" using sees_method_is_class[OF sees] by (auto simp add: prg_cert_def - intro!: start_context.wt_method_wt_lbv start_context.intro) + intro!: start_context.wt_method_wt_lbv start_context_intro_auxi[OF stab]) } ultimately have "wf_prog ?B P" by(rule wf_prog_lift) thus "wt_jvm_prog_lbv P (prg_cert P \)" by (simp add: wt_jvm_prog_lbv_def) qed (*>*) end diff --git a/thys/JinjaDCI/BV/SemiType.thy b/thys/JinjaDCI/BV/SemiType.thy --- a/thys/JinjaDCI/BV/SemiType.thy +++ b/thys/JinjaDCI/BV/SemiType.thy @@ -1,280 +1,280 @@ (* Title: Jinja/BV/SemiType.thy Author: Tobias Nipkow, Gerwin Klein Copyright 2000 TUM *) section \ The Jinja Type System as a Semilattice \ theory SemiType imports "../Common/WellForm" Jinja.Semilattices begin definition super :: "'a prog \ cname \ cname" where "super P C \ fst (the (class P C))" lemma superI: "(C,D) \ subcls1 P \ super P C = D" by (unfold super_def) (auto dest: subcls1D) primrec the_Class :: "ty \ cname" where "the_Class (Class C) = C" definition sup :: "'c prog \ ty \ ty \ ty err" where "sup P T\<^sub>1 T\<^sub>2 \ if is_refT T\<^sub>1 \ is_refT T\<^sub>2 then OK (if T\<^sub>1 = NT then T\<^sub>2 else if T\<^sub>2 = NT then T\<^sub>1 else (Class (exec_lub (subcls1 P) (super P) (the_Class T\<^sub>1) (the_Class T\<^sub>2)))) else (if T\<^sub>1 = T\<^sub>2 then OK T\<^sub>1 else Err)" lemma sup_def': "sup P = (\T\<^sub>1 T\<^sub>2. if is_refT T\<^sub>1 \ is_refT T\<^sub>2 then OK (if T\<^sub>1 = NT then T\<^sub>2 else if T\<^sub>2 = NT then T\<^sub>1 else (Class (exec_lub (subcls1 P) (super P) (the_Class T\<^sub>1) (the_Class T\<^sub>2)))) else (if T\<^sub>1 = T\<^sub>2 then OK T\<^sub>1 else Err))" by (simp add: sup_def fun_eq_iff) abbreviation subtype :: "'c prog \ ty \ ty \ bool" where "subtype P \ widen P" definition esl :: "'c prog \ ty esl" where "esl P \ (types P, subtype P, sup P)" (* FIXME: move to wellform *) lemma is_class_is_subcls: "wf_prog m P \ is_class P C = P \ C \\<^sup>* Object" (*<*)by (fastforce simp:is_class_def elim: subcls_C_Object converse_rtranclE subcls1I dest: subcls1D) (*>*) (* FIXME: move to wellform *) lemma subcls_antisym: "\wf_prog m P; P \ C \\<^sup>* D; P \ D \\<^sup>* C\ \ C = D" (*<*) by (auto dest: acyclic_subcls1 acyclic_impl_antisym_rtrancl antisymD) (*>*) (* FIXME: move to wellform *) lemma widen_antisym: "\ wf_prog m P; P \ T \ U; P \ U \ T \ \ T = U" (*<*) apply (cases T) apply (cases U) apply auto apply (cases U) apply (auto elim!: subcls_antisym) done (*>*) lemma order_widen [intro,simp]: - "wf_prog m P \ order (subtype P)" + "wf_prog m P \ order (subtype P) (types P)" (*<*) apply (unfold Semilat.order_def lesub_def) apply (auto intro: widen_trans widen_antisym) done (*>*) (* FIXME: move to TypeRel *) lemma NT_widen: "P \ NT \ T = (T = NT \ (\C. T = Class C))" (*<*) by (cases T) auto (*>*) (* FIXME: move to TypeRel *) lemma Class_widen2: "P \ Class C \ T = (\D. T = Class D \ P \ C \\<^sup>* D)" (*<*) by (cases T) auto (*>*) lemma wf_converse_subcls1_impl_acc_subtype: "wf ((subcls1 P)^-1) \ acc (subtype P)" (*<*) apply (unfold Semilat.acc_def lesssub_def) apply (drule_tac p = "(subcls1 P)^-1 - Id" in wf_subset) apply blast apply (drule wf_trancl) apply (simp add: wf_eq_minimal) apply clarify apply (unfold lesub_def) apply (rename_tac M T) apply (case_tac "\C. Class C \ M") prefer 2 apply (case_tac T) apply fastforce apply fastforce apply fastforce apply simp apply (rule_tac x = NT in bexI) apply (rule allI) apply (rule impI, erule conjE) apply (clarsimp simp add: NT_widen) apply simp apply clarsimp apply (erule_tac x = "{C. Class C : M}" in allE) apply auto apply (rename_tac D) apply (rule_tac x = "Class D" in bexI) prefer 2 apply assumption apply clarify apply (clarsimp simp: Class_widen2) apply (insert rtrancl_r_diff_Id [symmetric, of "subcls1 P"]) apply simp apply (erule rtranclE) apply blast apply (drule rtrancl_converseI) apply (subgoal_tac "((subcls1 P)-Id)^-1 = ((subcls1 P)^-1 - Id)") prefer 2 apply blast apply simp apply (blast intro: rtrancl_into_trancl2) done (*>*) lemma wf_subtype_acc [intro, simp]: "wf_prog wf_mb P \ acc (subtype P)" (*<*) by (rule wf_converse_subcls1_impl_acc_subtype, rule wf_subcls1) (*>*) lemma exec_lub_refl [simp]: "exec_lub r f T T = T" (*<*) by (simp add: exec_lub_def while_unfold) (*>*) lemma closed_err_types: "wf_prog wf_mb P \ closed (err (types P)) (lift2 (sup P))" (*<*) apply (unfold closed_def plussub_def lift2_def sup_def') apply (frule acyclic_subcls1) apply (frule single_valued_subcls1) apply (auto simp: is_type_def is_refT_def is_class_is_subcls split: err.split ty.splits) apply (blast dest!: is_lub_exec_lub is_lubD is_ubD intro!: is_ubI superI) done (*>*) lemma sup_subtype_greater: "\ wf_prog wf_mb P; is_type P t1; is_type P t2; sup P t1 t2 = OK s \ \ subtype P t1 s \ subtype P t2 s" (*<*) proof - assume wf_prog: "wf_prog wf_mb P" { fix c1 c2 assume is_class: "is_class P c1" "is_class P c2" with wf_prog obtain "P \ c1 \\<^sup>* Object" "P \ c2 \\<^sup>* Object" by (blast intro: subcls_C_Object) with single_valued_subcls1[OF wf_prog] obtain u where "is_lub ((subcls1 P)^* ) c1 c2 u" by (blast dest: single_valued_has_lubs) moreover note acyclic_subcls1[OF wf_prog] moreover have "\x y. (x, y) \ subcls1 P \ super P x = y" by (blast intro: superI) ultimately have "P \ c1 \\<^sup>* exec_lub (subcls1 P) (super P) c1 c2 \ P \ c2 \\<^sup>* exec_lub (subcls1 P) (super P) c1 c2" by (simp add: exec_lub_conv) (blast dest: is_lubD is_ubD) } note this [simp] assume "is_type P t1" "is_type P t2" "sup P t1 t2 = OK s" thus ?thesis apply (unfold sup_def) apply (cases s) apply (auto simp add: is_refT_def split: if_split_asm) done qed (*>*) lemma sup_subtype_smallest: "\ wf_prog wf_mb P; is_type P a; is_type P b; is_type P c; subtype P a c; subtype P b c; sup P a b = OK d \ \ subtype P d c" (*<*) proof - assume wf_prog: "wf_prog wf_mb P" { fix c1 c2 D assume is_class: "is_class P c1" "is_class P c2" assume le: "P \ c1 \\<^sup>* D" "P \ c2 \\<^sup>* D" from wf_prog is_class obtain "P \ c1 \\<^sup>* Object" "P \ c2 \\<^sup>* Object" by (blast intro: subcls_C_Object) with single_valued_subcls1[OF wf_prog] obtain u where lub: "is_lub ((subcls1 P)^* ) c1 c2 u" by (blast dest: single_valued_has_lubs) with acyclic_subcls1[OF wf_prog] have "exec_lub (subcls1 P) (super P) c1 c2 = u" by (blast intro: superI exec_lub_conv) moreover from lub le have "P \ u \\<^sup>* D" by (simp add: is_lub_def is_ub_def) ultimately have "P \ exec_lub (subcls1 P) (super P) c1 c2 \\<^sup>* D" by blast } note this [intro] have [dest!]: "\C T. P \ Class C \ T \ \D. T=Class D \ P \ C \\<^sup>* D" by (frule Class_widen, auto) assume "is_type P a" "is_type P b" "is_type P c" "subtype P a c" "subtype P b c" "sup P a b = OK d" thus ?thesis by (auto simp add: sup_def is_refT_def split: if_split_asm) qed (*>*) lemma sup_exists: "\ subtype P a c; subtype P b c \ \ \T. sup P a b = OK T" (*<*) apply (unfold sup_def) apply (cases b) apply auto apply (cases a) apply auto apply (cases a) apply auto done (*>*) lemma err_semilat_JType_esl: "wf_prog wf_mb P \ err_semilat (esl P)" (*<*) proof - assume wf_prog: "wf_prog wf_mb P" - hence "order (subtype P)".. + hence "order (subtype P) (types P)".. moreover from wf_prog have "closed (err (types P)) (lift2 (sup P))" by (rule closed_err_types) moreover from wf_prog have "(\x\err (types P). \y\err (types P). x \\<^bsub>Err.le (subtype P)\<^esub> x \\<^bsub>lift2 (sup P)\<^esub> y) \ (\x\err (types P). \y\err (types P). y \\<^bsub>Err.le (subtype P)\<^esub> x \\<^bsub>lift2 (sup P)\<^esub> y)" by (auto simp add: lesub_def plussub_def Err.le_def lift2_def sup_subtype_greater split: err.split) moreover from wf_prog have "\x\err (types P). \y\err (types P). \z\err (types P). x \\<^bsub>Err.le (subtype P)\<^esub> z \ y \\<^bsub>Err.le (subtype P)\<^esub> z \ x \\<^bsub>lift2 (sup P)\<^esub> y \\<^bsub>Err.le (subtype P)\<^esub> z" by (unfold lift2_def plussub_def lesub_def Err.le_def) (auto intro: sup_subtype_smallest dest:sup_exists split: err.split) ultimately show ?thesis by (simp add: esl_def semilat_def sl_def Err.sl_def) qed (*>*) end diff --git a/thys/JinjaDCI/BV/TF_JVM.thy b/thys/JinjaDCI/BV/TF_JVM.thy --- a/thys/JinjaDCI/BV/TF_JVM.thy +++ b/thys/JinjaDCI/BV/TF_JVM.thy @@ -1,319 +1,355 @@ (* Title: JinjaDCI/BV/TF_JVM.thy Author: Tobias Nipkow, Gerwin Klein, Susannah Mansky Copyright 2000 TUM, 2019-20 UIUC Based on the Jinja theory BV/TF_JVM.thy by Tobias Nipkow and Gerwin Klein *) section \ The Typing Framework for the JVM \label{sec:JVM} \ theory TF_JVM imports Jinja.Typing_Framework_err EffectMono BVSpec begin definition exec :: "jvm_prog \ nat \ ty \ ex_table \ instr list \ ty\<^sub>i' err step_type" where "exec G maxs rT et bs \ err_step (size bs) (\pc. app (bs!pc) G maxs rT pc (size bs) et) (\pc. eff (bs!pc) G pc et)" locale JVM_sl = - fixes P :: jvm_prog and mxs and mxl\<^sub>0 + fixes P :: jvm_prog and mxs and mxl\<^sub>0 and n fixes b and Ts :: "ty list" and "is" and xt and T\<^sub>r fixes mxl and A and r and f and app and eff and step defines [simp]: "mxl \ (case b of Static \ 0 | NonStatic \ 1)+size Ts+mxl\<^sub>0" defines [simp]: "A \ states P mxs mxl" defines [simp]: "r \ JVM_SemiType.le P mxs mxl" defines [simp]: "f \ JVM_SemiType.sup P mxs mxl" defines [simp]: "app \ \pc. Effect.app (is!pc) P mxs T\<^sub>r pc (size is) xt" defines [simp]: "eff \ \pc. Effect.eff (is!pc) P pc xt" defines [simp]: "step \ err_step (size is) app eff" + defines [simp]: "n \ size is" + assumes staticb: "b = Static \ b = NonStatic" locale start_context = JVM_sl + fixes p and C + assumes wf: "wf_prog p P" assumes C: "is_class P C" assumes Ts: "set Ts \ types P" + fixes first :: ty\<^sub>i' and start defines [simp]: "first \ Some ([],(case b of Static \ [] | NonStatic \ [OK (Class C)]) @ map OK Ts @ replicate mxl\<^sub>0 Err)" defines [simp]: "start \ (OK first) # replicate (size is - 1) (OK None)" +thm start_context.intro - +lemma start_context_intro_auxi: + fixes P b Ts p C + assumes "b = Static \ b = NonStatic " + and "wf_prog p P" + and "is_class P C" + and "set Ts \ types P" + shows " start_context P b Ts p C" + using start_context.intro[OF JVM_sl.intro] start_context_axioms_def assms by auto subsection \ Connecting JVM and Framework \ +lemma (in start_context) semi: "semilat (A, r, f)" + apply (insert semilat_JVM[OF wf]) + apply (unfold A_def r_def f_def JVM_SemiType.le_def JVM_SemiType.sup_def states_def) + apply auto + done + lemma (in JVM_sl) step_def_exec: "step \ exec P mxs T\<^sub>r xt is" by (simp add: exec_def) lemma special_ex_swap_lemma [iff]: "(? X. (? n. X = A n & P n) & Q X) = (? n. Q(A n) & P n)" by blast lemma ex_in_list [iff]: "(\n. ST \ list n A \ n \ mxs) = (set ST \ A \ size ST \ mxs)" by (unfold list_def) auto lemma singleton_list: "(\n. [Class C] \ list n (types P) \ n \ mxs) = (is_class P C \ 0 < mxs)" by auto lemma set_drop_subset: "set xs \ A \ set (drop n xs) \ A" by (auto dest: in_set_dropD) lemma Suc_minus_minus_le: "n < mxs \ Suc (n - (n - b)) \ mxs" by arith lemma in_listE: "\ xs \ list n A; \size xs = n; set xs \ A\ \ P \ \ P" by (unfold list_def) blast declare is_relevant_entry_def [simp] declare set_drop_subset [simp] theorem (in start_context) exec_pres_type: "pres_type step (size is) A" (*<*) proof - let ?n = "size is" and ?app = app and ?step = eff let ?mxl = "(case b of Static \ 0 | NonStatic \ 1) + length Ts + mxl\<^sub>0" let ?A = "opt((Union {list n (types P) |n. n <= mxs}) \ list ?mxl (err(types P)))" have "pres_type (err_step ?n ?app ?step) ?n (err ?A)" proof(rule pres_type_lift) have "\s pc pc' s'. s\?A \ pc < ?n \ ?app pc s \ (pc', s')\set (?step pc s) \ s' \ ?A" proof - fix s pc pc' s' assume asms: "s\?A" "pc < ?n" "?app pc s" "(pc', s')\set (?step pc s)" show "s' \ ?A" proof(cases s) case None then show ?thesis using asms by (fastforce dest: effNone) next case (Some ab) then show ?thesis using asms proof(cases "is!pc") case Load then show ?thesis using asms by (fastforce simp: Effect.app_def xcpt_app_def Effect.eff_def xcpt_eff_def norm_eff_def dest: listE_nth_in) next case Push then show ?thesis using asms Some by (fastforce simp: Effect.app_def xcpt_app_def Effect.eff_def xcpt_eff_def norm_eff_def typeof_lit_is_type) next case Getfield then show ?thesis using asms wf by (fastforce simp: Effect.app_def xcpt_app_def Effect.eff_def xcpt_eff_def norm_eff_def dest: sees_field_is_type) next case Getstatic then show ?thesis using asms wf by (fastforce simp: Effect.app_def xcpt_app_def Effect.eff_def xcpt_eff_def norm_eff_def dest: sees_field_is_type) next case (Invoke M n) obtain a b where [simp]: "s = \(a,b)\" using Some asms(1) by blast show ?thesis proof(cases "a!n = NT") case True then show ?thesis using Invoke asms wf by (fastforce simp: Effect.app_def xcpt_app_def Effect.eff_def xcpt_eff_def norm_eff_def) next case False have "(pc', s') \ set (norm_eff (Invoke M n) P pc (a, b)) \ (pc', s') \ set (xcpt_eff (Invoke M n) P pc (a, b) xt)" using Invoke asms(4) by (simp add: Effect.eff_def) then show ?thesis proof(rule disjE) assume "(pc', s') \ set (xcpt_eff (Invoke M n) P pc (a, b) xt)" then show ?thesis using Invoke asms(1-3) by (fastforce simp: Effect.app_def xcpt_app_def xcpt_eff_def) next assume norm: "(pc', s') \ set (norm_eff (Invoke M n) P pc (a, b))" also have "Suc (length a - Suc n) \ mxs" using Invoke asms(1,3) by (simp add: Effect.app_def xcpt_app_def) arith ultimately show ?thesis using False Invoke asms(1-3) wf by (auto simp: Effect.app_def xcpt_app_def norm_eff_def wf_mdecl_def dest!: sees_wf_mdecl) qed qed next case (Invokestatic C M n) obtain a b where [simp]: "s = \(a,b)\" using Some asms(1) by blast have "(pc', s') \ set (norm_eff (Invokestatic C M n) P pc (a, b)) \ (pc', s') \ set (xcpt_eff (Invokestatic C M n) P pc (a, b) xt)" using Invokestatic asms(4) by (simp add: Effect.eff_def) then show ?thesis proof(rule disjE) assume "(pc', s') \ set (xcpt_eff (Invokestatic C M n) P pc (a, b) xt)" then show ?thesis using Invokestatic asms(1-3) by (fastforce simp: Effect.app_def xcpt_app_def xcpt_eff_def) next assume norm: "(pc', s') \ set (norm_eff (Invokestatic C M n) P pc (a, b))" also have "Suc (length a - Suc n) \ mxs" using Invokestatic asms(1,3) by (simp add: Effect.app_def xcpt_app_def) arith ultimately show ?thesis using Invokestatic asms(1-3) wf by (auto simp: Effect.app_def xcpt_app_def norm_eff_def wf_mdecl_def dest!: sees_wf_mdecl) qed qed (fastforce simp: Effect.app_def xcpt_app_def Effect.eff_def xcpt_eff_def norm_eff_def)+ qed qed then show "\s\?A. \p. p < ?n \ ?app p s \ (\(q, s')\set (?step p s). s' \ ?A)" by clarsimp qed then show ?thesis by (simp add: JVM_states_unfold) qed (*>*) declare is_relevant_entry_def [simp del] declare set_drop_subset [simp del] lemma lesubstep_type_simple: "xs [\\<^bsub>Product.le (=) r\<^esub>] ys \ set xs {\\<^bsub>r\<^esub>} set ys" (*<*) proof - assume assm: "xs [\\<^bsub>Product.le (=) r\<^esub>] ys" have "\a b i y. (a, b) = xs ! i \ i < length xs \ \\'. (\i. (a, \') = ys ! i \ i < length xs) \ b \\<^bsub>r\<^esub> \'" proof - fix a b i assume ith: "(a, b) = xs ! i" and len: "i < length xs" obtain \ where "ys ! i = (a, \) \ r b \" using le_listD[OF assm len] ith by (clarsimp simp: lesub_def Product.le_def) then have "(a, \) = ys ! i \ b \\<^bsub>r\<^esub> \" by (clarsimp simp: lesub_def) with len show "\\'. (\i. (a, \') = ys ! i \ i < length xs) \ b \\<^bsub>r\<^esub> \'" by fastforce qed then show "set xs {\\<^bsub>r\<^esub>} set ys" using assm by (clarsimp simp: lesubstep_type_def set_conv_nth) qed (*>*) declare is_relevant_entry_def [simp del] lemma conjI2: "\ A; A \ B \ \ A \ B" by blast lemma (in JVM_sl) eff_mono: assumes wf: "wf_prog p P" and "pc < length is" and lesub: "s \\<^bsub>sup_state_opt P\<^esub> t" and app: "app pc t" shows "set (eff pc s) {\\<^bsub>sup_state_opt P\<^esub>} set (eff pc t)" (*<*) proof(cases t) case None then show ?thesis using lesub by (simp add: Effect.eff_def lesub_def) next case tSome: (Some a) show ?thesis proof(cases s) case None then show ?thesis using lesub by (simp add: Effect.eff_def lesub_def) next case (Some b) let ?norm = "\x. norm_eff (is ! pc) P pc x" let ?xcpt = "\x. xcpt_eff (is ! pc) P pc x xt" let ?r = "Product.le (=) (sup_state_opt P)" let ?\' = "\eff\<^sub>i (is ! pc, P, a)\" { fix x assume xb: "x \ set (succs (is ! pc) b pc)" then have appi: "app\<^sub>i (is ! pc, P, pc, mxs, T\<^sub>r, a)" and bia: "P \ b \\<^sub>i a" and appa: "app pc \a\" using lesub app tSome Some by (auto simp add: lesub_def Effect.app_def) have xa: "x \ set (succs (is ! pc) a pc)" using xb succs_mono[OF wf appi bia] by auto then have "(x, ?\') \ (\pc'. (pc', ?\')) ` set (succs (is ! pc) a pc)" by (rule imageI) moreover have "P \ \eff\<^sub>i (is ! pc, P, b)\ \' ?\'" using xb xa eff\<^sub>i_mono[OF wf bia] appa by fastforce ultimately have "\\'. (x, \') \ (\pc'. (pc', \eff\<^sub>i (is ! pc, P, a)\)) ` set (succs (is ! pc) a pc) \ P \ \eff\<^sub>i (is ! pc, P, b)\ \' \'" by blast } then have norm: "set (?norm b) {\\<^bsub>sup_state_opt P\<^esub>} set (?norm a)" using tSome Some by (clarsimp simp: norm_eff_def lesubstep_type_def lesub_def) obtain a1 b1 a2 b2 where a: "a = (a1, b1)" and b: "b = (a2, b2)" using tSome Some by fastforce then have a12: "size a2 = size a1" using lesub tSome Some by (clarsimp simp: lesub_def list_all2_lengthD) have "length (?xcpt b) = length (?xcpt a)" by (simp add: xcpt_eff_def split_beta) moreover have "\n. n < length (?xcpt b) \ (?xcpt b) ! n \\<^bsub>?r\<^esub> (?xcpt a) ! n" using lesub tSome Some a b a12 by (simp add: xcpt_eff_def split_beta fun_of_def) (simp add: lesub_def) ultimately have "?xcpt b [\\<^bsub>?r\<^esub>] ?xcpt a" by(rule le_listI) then have "set (?xcpt b) {\\<^bsub>sup_state_opt P\<^esub>} set (?xcpt a)" by (rule lesubstep_type_simple) moreover note norm ultimately have "set (?norm b) \ set (?xcpt b) {\\<^bsub>sup_state_opt P\<^esub>} set (?norm a) \ set (?xcpt a)" by(intro lesubstep_union) then show ?thesis using tSome Some by(simp add: Effect.eff_def) qed qed (*>*) lemma (in JVM_sl) bounded_step: "bounded step (size is)" (*<*) by (auto simp: bounded_def err_step_def Effect.app_def Effect.eff_def error_def map_snd_def split: err.splits option.splits) (*>*) theorem (in JVM_sl) step_mono: "wf_prog wf_mb P \ mono r step (size is) A" (*<*) + apply (simp add: JVM_le_Err_conv) + apply (insert bounded_step) + apply (unfold JVM_states_unfold) + apply (rule mono_lift) + apply (subgoal_tac "b = Static \ b = NonStatic") + apply (fastforce split:if_splits)\\ order_sup_state_opt' order_sup_state_opt'' \ + apply (simp only:staticb) + apply (unfold app_mono_def lesub_def) + apply clarsimp + apply (erule (2) app_mono) + apply simp + apply clarify + apply (drule eff_mono) + apply (auto simp add: lesub_def) + done +(* proof - assume wf: "wf_prog wf_mb P" let ?r = "sup_state_opt P" and ?n = "length is" and ?app = app and ?step = eff let ?A = "opt (\ {list n (types P) |n. n \ mxs} \ list ((case b of Static \ 0 | NonStatic \ 1) + length Ts + mxl\<^sub>0) (err (types P)))" - have "order ?r" using wf by simp + have "order ?r ?A" using wf by simp moreover have "app_mono ?r ?app ?n ?A" using app_mono[OF wf] by (clarsimp simp: app_mono_def lesub_def) moreover have "bounded (err_step ?n ?app ?step) ?n" using bounded_step by simp moreover have "\s p t. s \ ?A \ p < ?n \ s \\<^bsub>?r\<^esub> t \ ?app p t \ set (?step p s) {\\<^bsub>?r\<^esub>} set (?step p t)" using eff_mono[OF wf] by simp ultimately have "mono (Err.le ?r) (err_step ?n ?app ?step) ?n (err ?A)" by(rule mono_lift) then show "mono r step (size is) A" using bounded_step by (simp add: JVM_le_Err_conv JVM_states_unfold) qed +*) (*>*) lemma (in start_context) first_in_A [iff]: "OK first \ A" using Ts C by (cases b; force intro!: list_appendI simp add: JVM_states_unfold) lemma (in JVM_sl) wt_method_def2: "wt_method P C' b Ts T\<^sub>r mxs mxl\<^sub>0 is xt \s = (is \ [] \ + (b = Static \ b = NonStatic) \ size \s = size is \ OK ` set \s \ states P mxs mxl \ wt_start P C' b Ts mxl\<^sub>0 \s \ wt_app_eff (sup_state_opt P) app eff \s)" -(*<*) +(*<*)using staticb by (unfold wt_method_def wt_app_eff_def wt_instr_def lesub_def check_types_def) auto (*>*) end diff --git a/thys/JinjaDCI/Compiler/TypeComp.thy b/thys/JinjaDCI/Compiler/TypeComp.thy --- a/thys/JinjaDCI/Compiler/TypeComp.thy +++ b/thys/JinjaDCI/Compiler/TypeComp.thy @@ -1,1619 +1,1686 @@ (* Title: JinjaDCI/Compiler/TypeComp.thy Author: Tobias Nipkow, Susannah Mansky Copyright TUM 2003, UIUC 2019-20 Based on the Jinja theory Compiler/TypeComp.thy by Tobias Nipkow *) section \ Preservation of Well-Typedness \ theory TypeComp imports Compiler "../BV/BVSpec" begin (*<*) declare nth_append[simp] (*>*) lemma max_stack1: "P,E \\<^sub>1 e :: T \ 1 \ max_stack e" (*<*)using max_stack1'[OF WT\<^sub>1_nsub_RI] by simp(*>*) locale TC0 = fixes P :: "J\<^sub>1_prog" and mxl :: nat begin definition "ty E e = (THE T. P,E \\<^sub>1 e :: T)" definition "ty\<^sub>l E A' = map (\i. if i \ A' \ i < size E then OK(E!i) else Err) [0..i' ST E A = (case A of None \ None | \A'\ \ Some(ST, ty\<^sub>l E A'))" definition "after E A ST e = ty\<^sub>i' (ty E e # ST) E (A \ \ e)" end lemma (in TC0) ty_def2 [simp]: "P,E \\<^sub>1 e :: T \ ty E e = T" (*<*)by(unfold ty_def) (blast intro: the_equality WT\<^sub>1_unique)(*>*) lemma (in TC0) [simp]: "ty\<^sub>i' ST E None = None" (*<*)by (simp add: ty\<^sub>i'_def)(*>*) lemma (in TC0) ty\<^sub>l_app_diff[simp]: "ty\<^sub>l (E@[T]) (A - {size E}) = ty\<^sub>l E A" (*<*)by(auto simp add:ty\<^sub>l_def hyperset_defs)(*>*) lemma (in TC0) ty\<^sub>i'_app_diff[simp]: "ty\<^sub>i' ST (E @ [T]) (A \ size E) = ty\<^sub>i' ST E A" (*<*)by(auto simp add:ty\<^sub>i'_def hyperset_defs)(*>*) lemma (in TC0) ty\<^sub>l_antimono: "A \ A' \ P \ ty\<^sub>l E A' [\\<^sub>\] ty\<^sub>l E A" (*<*)by(auto simp:ty\<^sub>l_def list_all2_conv_all_nth)(*>*) lemma (in TC0) ty\<^sub>i'_antimono: "A \ A' \ P \ ty\<^sub>i' ST E \A'\ \' ty\<^sub>i' ST E \A\" (*<*)by(auto simp:ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth)(*>*) lemma (in TC0) ty\<^sub>l_env_antimono: "P \ ty\<^sub>l (E@[T]) A [\\<^sub>\] ty\<^sub>l E A" (*<*)by(auto simp:ty\<^sub>l_def list_all2_conv_all_nth)(*>*) lemma (in TC0) ty\<^sub>i'_env_antimono: "P \ ty\<^sub>i' ST (E@[T]) A \' ty\<^sub>i' ST E A" (*<*)by(auto simp:ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth)(*>*) lemma (in TC0) ty\<^sub>i'_incr: "P \ ty\<^sub>i' ST (E @ [T]) \insert (size E) A\ \' ty\<^sub>i' ST E \A\" (*<*)by(auto simp:ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth)(*>*) lemma (in TC0) ty\<^sub>l_incr: "P \ ty\<^sub>l (E @ [T]) (insert (size E) A) [\\<^sub>\] ty\<^sub>l E A" (*<*)by(auto simp: hyperset_defs ty\<^sub>l_def list_all2_conv_all_nth)(*>*) lemma (in TC0) ty\<^sub>l_in_types: "set E \ types P \ ty\<^sub>l E A \ list mxl (err (types P))" (*<*)by(auto simp add:ty\<^sub>l_def intro!:listI dest!: nth_mem)(*>*) locale TC1 = TC0 begin primrec compT :: "ty list \ nat hyperset \ ty list \ expr\<^sub>1 \ ty\<^sub>i' list" and compTs :: "ty list \ nat hyperset \ ty list \ expr\<^sub>1 list \ ty\<^sub>i' list" where "compT E A ST (new C) = []" | "compT E A ST (Cast C e) = compT E A ST e @ [after E A ST e]" | "compT E A ST (Val v) = []" | "compT E A ST (e\<^sub>1 \bop\ e\<^sub>2) = (let ST\<^sub>1 = ty E e\<^sub>1#ST; A\<^sub>1 = A \ \ e\<^sub>1 in compT E A ST e\<^sub>1 @ [after E A ST e\<^sub>1] @ compT E A\<^sub>1 ST\<^sub>1 e\<^sub>2 @ [after E A\<^sub>1 ST\<^sub>1 e\<^sub>2])" | "compT E A ST (Var i) = []" | "compT E A ST (i := e) = compT E A ST e @ [after E A ST e, ty\<^sub>i' ST E (A \ \ e \ \{i}\)]" | "compT E A ST (e\F{D}) = compT E A ST e @ [after E A ST e]" | "compT E A ST (C\\<^sub>sF{D}) = []" | "compT E A ST (e\<^sub>1\F{D} := e\<^sub>2) = (let ST\<^sub>1 = ty E e\<^sub>1#ST; A\<^sub>1 = A \ \ e\<^sub>1; A\<^sub>2 = A\<^sub>1 \ \ e\<^sub>2 in compT E A ST e\<^sub>1 @ [after E A ST e\<^sub>1] @ compT E A\<^sub>1 ST\<^sub>1 e\<^sub>2 @ [after E A\<^sub>1 ST\<^sub>1 e\<^sub>2] @ [ty\<^sub>i' ST E A\<^sub>2])" | "compT E A ST (C\\<^sub>sF{D} := e\<^sub>2) = compT E A ST e\<^sub>2 @ [after E A ST e\<^sub>2] @ [ty\<^sub>i' ST E (A \ \ e\<^sub>2)]" | "compT E A ST {i:T; e} = compT (E@[T]) (A\i) ST e" | "compT E A ST (e\<^sub>1;;e\<^sub>2) = (let A\<^sub>1 = A \ \ e\<^sub>1 in compT E A ST e\<^sub>1 @ [after E A ST e\<^sub>1, ty\<^sub>i' ST E A\<^sub>1] @ compT E A\<^sub>1 ST e\<^sub>2)" | "compT E A ST (if (e) e\<^sub>1 else e\<^sub>2) = (let A\<^sub>0 = A \ \ e; \ = ty\<^sub>i' ST E A\<^sub>0 in compT E A ST e @ [after E A ST e, \] @ compT E A\<^sub>0 ST e\<^sub>1 @ [after E A\<^sub>0 ST e\<^sub>1, \] @ compT E A\<^sub>0 ST e\<^sub>2)" | "compT E A ST (while (e) c) = (let A\<^sub>0 = A \ \ e; A\<^sub>1 = A\<^sub>0 \ \ c; \ = ty\<^sub>i' ST E A\<^sub>0 in compT E A ST e @ [after E A ST e, \] @ compT E A\<^sub>0 ST c @ [after E A\<^sub>0 ST c, ty\<^sub>i' ST E A\<^sub>1, ty\<^sub>i' ST E A\<^sub>0])" | "compT E A ST (throw e) = compT E A ST e @ [after E A ST e]" | "compT E A ST (e\M(es)) = compT E A ST e @ [after E A ST e] @ compTs E (A \ \ e) (ty E e # ST) es" | "compT E A ST (C\\<^sub>sM(es)) = compTs E A ST es" | "compT E A ST (try e\<^sub>1 catch(C i) e\<^sub>2) = compT E A ST e\<^sub>1 @ [after E A ST e\<^sub>1] @ [ty\<^sub>i' (Class C#ST) E A, ty\<^sub>i' ST (E@[Class C]) (A \ \{i}\)] @ compT (E@[Class C]) (A \ \{i}\) ST e\<^sub>2" | "compT E A ST (INIT C (Cs,b) \ e) = []" | "compT E A ST (RI(C,e');Cs \ e) = []" | "compTs E A ST [] = []" | "compTs E A ST (e#es) = compT E A ST e @ [after E A ST e] @ compTs E (A \ (\ e)) (ty E e # ST) es" definition compT\<^sub>a :: "ty list \ nat hyperset \ ty list \ expr\<^sub>1 \ ty\<^sub>i' list" where "compT\<^sub>a E A ST e = compT E A ST e @ [after E A ST e]" end lemma compE\<^sub>2_not_Nil[simp]: "P,E \\<^sub>1 e :: T \ compE\<^sub>2 e \ []" (*<*)by(simp add: compE\<^sub>2_not_Nil' WT\<^sub>1_nsub_RI)(*>*) lemma (in TC1) compT_sizes': shows "\E A ST. \sub_RI e \ size(compT E A ST e) = size(compE\<^sub>2 e) - 1" and "\E A ST. \sub_RIs es \ size(compTs E A ST es) = size(compEs\<^sub>2 es)" (*<*) by(induct e and es rule: compE\<^sub>2.induct compEs\<^sub>2.induct) (auto split:bop.splits nat_diff_split simp: compE\<^sub>2_not_Nil') (*>*) lemma (in TC1) compT_sizes[simp]: shows "\E A ST. P,E \\<^sub>1 e :: T \ size(compT E A ST e) = size(compE\<^sub>2 e) - 1" and "\E A ST. P,E \\<^sub>1 es [::] Ts \ size(compTs E A ST es) = size(compEs\<^sub>2 es)" (*<*)using compT_sizes' WT\<^sub>1_nsub_RI WTs\<^sub>1_nsub_RIs by auto(*>*) lemma (in TC1) [simp]: "\ST E. \\\ \ set (compT E None ST e)" and [simp]: "\ST E. \\\ \ set (compTs E None ST es)" (*<*)by(induct e and es rule: compT.induct compTs.induct) (simp_all add:after_def)(*>*) lemma (in TC0) pair_eq_ty\<^sub>i'_conv: "(\(ST, LT)\ = ty\<^sub>i' ST\<^sub>0 E A) = (case A of None \ False | Some A \ (ST = ST\<^sub>0 \ LT = ty\<^sub>l E A))" (*<*)by(simp add:ty\<^sub>i'_def)(*>*) lemma (in TC0) pair_conv_ty\<^sub>i': "\(ST, ty\<^sub>l E A)\ = ty\<^sub>i' ST E \A\" (*<*)by(simp add:ty\<^sub>i'_def)(*>*) (*<*) declare (in TC0) ty\<^sub>i'_antimono [intro!] after_def[simp] pair_conv_ty\<^sub>i'[simp] pair_eq_ty\<^sub>i'_conv[simp] (*>*) lemma (in TC1) compT_LT_prefix: "\E A ST\<^sub>0. \ \(ST,LT)\ \ set(compT E A ST\<^sub>0 e); \ e (size E) \ \ P \ \(ST,LT)\ \' ty\<^sub>i' ST E A" and "\E A ST\<^sub>0. \ \(ST,LT)\ \ set(compTs E A ST\<^sub>0 es); \s es (size E) \ \ P \ \(ST,LT)\ \' ty\<^sub>i' ST E A" (*<*) proof(induct e and es rule: compT.induct compTs.induct) case FAss thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) next case BinOp thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans split:bop.splits) next case Seq thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) next case While thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) next case Cond thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) next case Block thus ?case by(force simp add:hyperset_defs ty\<^sub>i'_def simp del:pair_conv_ty\<^sub>i' elim!:sup_state_opt_trans) next case Call thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) next case Cons_exp thus ?case by(fastforce simp:hyperset_defs elim!:sup_state_opt_trans) next case TryCatch thus ?case by(fastforce simp:hyperset_defs intro!: ty\<^sub>i'_incr elim!:sup_state_opt_trans) qed (auto simp:hyperset_defs) declare (in TC0) ty\<^sub>i'_antimono [rule del] after_def[simp del] pair_conv_ty\<^sub>i'[simp del] pair_eq_ty\<^sub>i'_conv[simp del] (*>*) lemma [iff]: "OK None \ states P mxs mxl" (*<*)by(simp add: JVM_states_unfold)(*>*) lemma (in TC0) after_in_states: assumes wf: "wf_prog p P" and wt: "P,E \\<^sub>1 e :: T" and Etypes: "set E \ types P" and STtypes: "set ST \ types P" and stack: "size ST + max_stack e \ mxs" shows "OK (after E A ST e) \ states P mxs mxl" (*<*) proof - have "size ST + 1 \ mxs" using max_stack1[where e=e] wt stack by fastforce then show ?thesis using assms by(simp add: after_def ty\<^sub>i'_def JVM_states_unfold ty\<^sub>l_in_types) (blast intro!:listI WT\<^sub>1_is_type) qed (*>*) lemma (in TC0) OK_ty\<^sub>i'_in_statesI[simp]: "\ set E \ types P; set ST \ types P; size ST \ mxs \ \ OK (ty\<^sub>i' ST E A) \ states P mxs mxl" (*<*) by(simp add:ty\<^sub>i'_def JVM_states_unfold ty\<^sub>l_in_types) (blast intro!:listI) (*>*) lemma is_class_type_aux: "is_class P C \ is_type P (Class C)" (*<*)by(simp)(*>*) (*<*) declare is_type_simps[simp del] subsetI[rule del] (*>*) theorem (in TC1) compT_states: assumes wf: "wf_prog p P" shows "\E T A ST. \ P,E \\<^sub>1 e :: T; set E \ types P; set ST \ types P; size ST + max_stack e \ mxs; size E + max_vars e \ mxl \ \ OK ` set(compT E A ST e) \ states P mxs mxl" (*<*)(is "\E T A ST. PROP ?P e E T A ST")(*>*) and "\E Ts A ST. \ P,E \\<^sub>1 es[::]Ts; set E \ types P; set ST \ types P; size ST + max_stacks es \ mxs; size E + max_varss es \ mxl \ \ OK ` set(compTs E A ST es) \ states P mxs mxl" (*<*)(is "\E Ts A ST. PROP ?Ps es E Ts A ST") proof(induct e and es rule: compT.induct compTs.induct) case new thus ?case by(simp) next case (Cast C e) thus ?case by (auto simp:after_in_states[OF wf]) next case Val thus ?case by(simp) next case Var thus ?case by(simp) next case LAss thus ?case by(auto simp:after_in_states[OF wf]) next case FAcc thus ?case by(auto simp:after_in_states[OF wf]) next case SFAcc thus ?case by(auto simp:after_in_states[OF wf]) next case FAss thus ?case by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) next case SFAss thus ?case by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) next case Seq thus ?case by(auto simp:image_Un after_in_states[OF wf]) next case BinOp thus ?case by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) next case Cond thus ?case by(force simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) next case While thus ?case by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) next case Block thus ?case by(auto) next case (TryCatch e\<^sub>1 C i e\<^sub>2) moreover have "size ST + 1 \ mxs" using TryCatch.prems max_stack1[where e=e\<^sub>1] by fastforce ultimately show ?case by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf] is_class_type_aux) next case Nil_exp thus ?case by simp next case Cons_exp thus ?case by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) next case throw thus ?case by(auto simp: WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) next case Call thus ?case by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) next case SCall thus ?case by(auto simp:image_Un WT\<^sub>1_is_type[OF wf] after_in_states[OF wf]) next case INIT thus ?case by simp next case RI thus ?case by simp qed declare is_type_simps[simp] subsetI[intro!] (*>*) definition shift :: "nat \ ex_table \ ex_table" where "shift n xt \ map (\(from,to,C,handler,depth). (from+n,to+n,C,handler+n,depth)) xt" lemma [simp]: "shift 0 xt = xt" (*<*)by(induct xt)(auto simp:shift_def)(*>*) lemma [simp]: "shift n [] = []" (*<*)by(simp add:shift_def)(*>*) lemma [simp]: "shift n (xt\<^sub>1 @ xt\<^sub>2) = shift n xt\<^sub>1 @ shift n xt\<^sub>2" (*<*)by(simp add:shift_def)(*>*) lemma [simp]: "shift m (shift n xt) = shift (m+n) xt" (*<*)by(induct xt)(auto simp:shift_def)(*>*) lemma [simp]: "pcs (shift n xt) = {pc+n|pc. pc \ pcs xt}" (*<*) proof - { fix x f t C h d assume "(f,t,C,h,d) \ set xt" and "f + n \ x" and "x < t + n" then have "\pc. x = pc + n \ (\x\set xt. pc \ (case x of (f, t, C, h, d) \ {f..*) lemma shift_compxE\<^sub>2: shows "\pc pc' d. shift pc (compxE\<^sub>2 e pc' d) = compxE\<^sub>2 e (pc' + pc) d" and "\pc pc' d. shift pc (compxEs\<^sub>2 es pc' d) = compxEs\<^sub>2 es (pc' + pc) d" (*<*) by(induct e and es rule: compxE\<^sub>2.induct compxEs\<^sub>2.induct) (auto simp:shift_def ac_simps) (*>*) lemma compxE\<^sub>2_size_convs[simp]: shows "n \ 0 \ compxE\<^sub>2 e n d = shift n (compxE\<^sub>2 e 0 d)" and "n \ 0 \ compxEs\<^sub>2 es n d = shift n (compxEs\<^sub>2 es 0 d)" (*<*)by(simp_all add:shift_compxE\<^sub>2)(*>*) locale TC2 = TC1 + fixes T\<^sub>r :: ty and mxs :: pc begin definition wt_instrs :: "instr list \ ex_table \ ty\<^sub>i' list \ bool" ("(\ _, _ /[::]/ _)" [0,0,51] 50) where "\ is,xt [::] \s \ size is < size \s \ pcs xt \ {0.. (\pc< size is. P,T\<^sub>r,mxs,size \s,xt \ is!pc,pc :: \s)" end notation TC2.wt_instrs ("(_,_,_ \/ _, _ /[::]/ _)" [50,50,50,50,50,51] 50) (*<*) lemmas (in TC2) wt_defs = wt_instrs_def wt_instr_def app_def eff_def norm_eff_def (*>*) lemma (in TC2) [simp]: "\s \ [] \ \ [],[] [::] \s" (*<*) by (simp add: wt_defs) (*>*) lemma [simp]: "eff i P pc et None = []" (*<*)by (simp add: Effect.eff_def)(*>*) (*<*) declare split_comp_eq[simp del] (*>*) lemma wt_instr_appR: "\ P,T,m,mpc,xt \ is!pc,pc :: \s; pc < size is; size is < size \s; mpc \ size \s; mpc \ mpc' \ \ P,T,m,mpc',xt \ is!pc,pc :: \s@\s'" (*<*)by (fastforce simp:wt_instr_def app_def)(*>*) lemma relevant_entries_shift [simp]: "relevant_entries P i (pc+n) (shift n xt) = shift n (relevant_entries P i pc xt)" (*<*) proof(induct xt) case Nil then show ?case by (simp add: relevant_entries_def shift_def) next case (Cons a xt) then show ?case by (auto simp add: relevant_entries_def shift_def is_relevant_entry_def) qed (*>*) lemma [simp]: "xcpt_eff i P (pc+n) \ (shift n xt) = map (\(pc,\). (pc + n, \)) (xcpt_eff i P pc \ xt)" (*<*) proof - obtain ST LT where "\ = (ST, LT)" by(cases \) simp then show ?thesis by(simp add: xcpt_eff_def) (auto simp add: shift_def) qed (*>*) lemma [simp]: "app\<^sub>i (i, P, pc, m, T, \) \ eff i P (pc+n) (shift n xt) (Some \) = map (\(pc,\). (pc+n,\)) (eff i P pc xt (Some \))" (*<*)by(cases "i") (auto simp add:eff_def norm_eff_def)(*>*) lemma [simp]: "xcpt_app i P (pc+n) mxs (shift n xt) \ = xcpt_app i P pc mxs xt \" (*<*)by (simp add: xcpt_app_def) (auto simp add: shift_def)(*>*) lemma wt_instr_appL: assumes "P,T,m,mpc,xt \ i,pc :: \s" and "pc < size \s" and "mpc \ size \s" shows "P,T,m,mpc + size \s',shift (size \s') xt \ i,pc+size \s' :: \s'@\s" (*<*) proof - let ?t = "(\s'@\s)!(pc+size \s')" show ?thesis proof(cases ?t) case (Some \) obtain ST LT where [simp]: "\ = (ST, LT)" by(cases \) simp have "app\<^sub>i (i, P, pc + length \s', m, T, \)" using Some assms by(cases "i") (auto simp:wt_instr_def app_def) moreover { fix pc' \' assume "(pc',\') \ set (eff i P pc xt ?t)" then have "P \ \' \' \s!pc'" and "pc' < mpc" using Some assms by(auto simp:wt_instr_def app_def) } ultimately show ?thesis using Some assms by(fastforce simp:wt_instr_def app_def) qed (auto simp:wt_instr_def app_def) qed (*>*) lemma wt_instr_Cons: assumes wti: "P,T,m,mpc - 1,[] \ i,pc - 1 :: \s" and pcl: "0 < pc" and mpcl: "0 < mpc" and pcu: "pc < size \s + 1" and mpcu: "mpc \ size \s + 1" shows "P,T,m,mpc,[] \ i,pc :: \#\s" (*<*) proof - have "pc - 1 < length \s" using pcl pcu by arith moreover have "mpc - 1 \ length \s" using mpcl mpcu by arith ultimately have "P,T,m,mpc - 1 + length [\],shift (length [\]) [] \ i,pc - 1 + length [\] :: [\] @ \s" by(rule wt_instr_appL[where \s' = "[\]", OF wti]) then show ?thesis using pcl mpcl by (simp split:nat_diff_split_asm) qed (*>*) lemma wt_instr_append: assumes wti: "P,T,m,mpc - size \s',[] \ i,pc - size \s' :: \s" and pcl: "size \s' \ pc" and mpcl: "size \s' \ mpc" and pcu: "pc < size \s + size \s'" and mpcu: "mpc \ size \s + size \s'" shows "P,T,m,mpc,[] \ i,pc :: \s'@\s" (*<*) proof - have "pc - length \s' < length \s" using pcl pcu by arith moreover have "mpc - length \s' \ length \s" using mpcl mpcu by arith thm wt_instr_appL[where \s' = "\s'", OF wti] ultimately have "P,T,m,mpc - length \s' + length \s',shift (length \s') [] \ i,pc - length \s' + length \s' :: \s' @ \s" by(rule wt_instr_appL[where \s' = "\s'", OF wti]) then show ?thesis using pcl mpcl by (simp split:nat_diff_split_asm) qed (*>*) lemma xcpt_app_pcs: "pc \ pcs xt \ xcpt_app i P pc mxs xt \" (*<*) by (auto simp add: xcpt_app_def relevant_entries_def is_relevant_entry_def pcs_def) (*>*) lemma xcpt_eff_pcs: "pc \ pcs xt \ xcpt_eff i P pc \ xt = []" (*<*) by (cases \) (auto simp add: is_relevant_entry_def xcpt_eff_def relevant_entries_def pcs_def intro!: filter_False) (*>*) lemma pcs_shift: "pc < n \ pc \ pcs (shift n xt)" (*<*)by (auto simp add: shift_def pcs_def)(*>*) lemma wt_instr_appRx: "\ P,T,m,mpc,xt \ is!pc,pc :: \s; pc < size is; size is < size \s; mpc \ size \s \ \ P,T,m,mpc,xt @ shift (size is) xt' \ is!pc,pc :: \s" (*<*)by (auto simp:wt_instr_def eff_def app_def xcpt_app_pcs xcpt_eff_pcs)(*>*) lemma wt_instr_appLx: "\ P,T,m,mpc,xt \ i,pc :: \s; pc \ pcs xt' \ \ P,T,m,mpc,xt'@xt \ i,pc :: \s" (*<*)by (auto simp:wt_instr_def app_def eff_def xcpt_app_pcs xcpt_eff_pcs)(*>*) lemma (in TC2) wt_instrs_extR: "\ is,xt [::] \s \ \ is,xt [::] \s @ \s'" (*<*)by(auto simp add:wt_instrs_def wt_instr_appR)(*>*) lemma (in TC2) wt_instrs_ext: assumes wt\<^sub>1: "\ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@\s\<^sub>2" and wt\<^sub>2: "\ is\<^sub>2,xt\<^sub>2 [::] \s\<^sub>2" and \s_size: "size \s\<^sub>1 = size is\<^sub>1" shows "\ is\<^sub>1@is\<^sub>2, xt\<^sub>1 @ shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\s\<^sub>2" (*<*) proof - let ?is = "is\<^sub>1@is\<^sub>2" and ?xt = "xt\<^sub>1 @ shift (size is\<^sub>1) xt\<^sub>2" and ?\s = "\s\<^sub>1@\s\<^sub>2" have "size ?is < size ?\s" using wt\<^sub>2 \s_size by(fastforce simp:wt_instrs_def) moreover have "pcs ?xt \ {0..1 wt\<^sub>2 by(fastforce simp:wt_instrs_def) moreover { fix pc assume pc: "pcr,mxs,size ?\s,?xt \ ?is!pc,pc :: ?\s" proof(cases "pc < length is\<^sub>1") case True then show ?thesis using wt\<^sub>1 pc by(fastforce simp: wt_instrs_def wt_instr_appRx) next case False then have "pc - length is\<^sub>1 < length is\<^sub>2" using pc by fastforce then have "P,T\<^sub>r,mxs,length \s\<^sub>2,xt\<^sub>2 \ is\<^sub>2 ! (pc - length is\<^sub>1),pc - length is\<^sub>1 :: \s\<^sub>2" using wt\<^sub>2 by(clarsimp simp: wt_instrs_def) moreover have "pc - length is\<^sub>1 < length \s\<^sub>2" using pc wt\<^sub>2 by(clarsimp simp: wt_instrs_def) arith moreover have "length \s\<^sub>2 \ length \s\<^sub>2" by simp moreover have "pc - length is\<^sub>1 + length \s\<^sub>1 \ pcs xt\<^sub>1" using wt\<^sub>1 \s_size by(fastforce simp: wt_instrs_def) ultimately have "P,T\<^sub>r,mxs,length \s\<^sub>2 + length \s\<^sub>1,xt\<^sub>1 @ shift (length \s\<^sub>1) xt\<^sub>2 \ is\<^sub>2 ! (pc - length is\<^sub>1),pc - length is\<^sub>1 + length \s\<^sub>1 :: \s\<^sub>1 @ \s\<^sub>2" by(rule wt_instr_appLx[OF wt_instr_appL[where \s' = "\s\<^sub>1"]]) then show ?thesis using False \s_size by(simp add:add.commute) qed } ultimately show ?thesis by(clarsimp simp:wt_instrs_def) qed (*>*) corollary (in TC2) wt_instrs_ext2: "\ \ is\<^sub>2,xt\<^sub>2 [::] \s\<^sub>2; \ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@\s\<^sub>2; size \s\<^sub>1 = size is\<^sub>1 \ \ \ is\<^sub>1@is\<^sub>2, xt\<^sub>1 @ shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\s\<^sub>2" (*<*)by(rule wt_instrs_ext)(*>*) corollary (in TC2) wt_instrs_ext_prefix [trans]: "\ \ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@\s\<^sub>2; \ is\<^sub>2,xt\<^sub>2 [::] \s\<^sub>3; size \s\<^sub>1 = size is\<^sub>1; prefix \s\<^sub>3 \s\<^sub>2 \ \ \ is\<^sub>1@is\<^sub>2, xt\<^sub>1 @ shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\s\<^sub>2" (*<*)by(bestsimp simp:prefix_def elim: wt_instrs_ext dest:wt_instrs_extR)(*>*) corollary (in TC2) wt_instrs_app: assumes is\<^sub>1: "\ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@[\]" assumes is\<^sub>2: "\ is\<^sub>2,xt\<^sub>2 [::] \#\s\<^sub>2" assumes s: "size \s\<^sub>1 = size is\<^sub>1" shows "\ is\<^sub>1@is\<^sub>2, xt\<^sub>1@shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\#\s\<^sub>2" (*<*) proof - from is\<^sub>1 have "\ is\<^sub>1,xt\<^sub>1 [::] (\s\<^sub>1@[\])@\s\<^sub>2" by (rule wt_instrs_extR) hence "\ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@\#\s\<^sub>2" by simp from this is\<^sub>2 s show ?thesis by (rule wt_instrs_ext) qed (*>*) corollary (in TC2) wt_instrs_app_last[trans]: assumes "\ is\<^sub>2,xt\<^sub>2 [::] \#\s\<^sub>2" "\ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1" "last \s\<^sub>1 = \" "size \s\<^sub>1 = size is\<^sub>1+1" shows "\ is\<^sub>1@is\<^sub>2, xt\<^sub>1@shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\s\<^sub>2" (*<*) using assms proof(cases \s\<^sub>1 rule:rev_cases) case (snoc ys y) then show ?thesis using assms by(simp add:wt_instrs_app) qed simp (*>*) corollary (in TC2) wt_instrs_append_last[trans]: assumes wtis: "\ is,xt [::] \s" and wti: "P,T\<^sub>r,mxs,mpc,[] \ i,pc :: \s" and pc: "pc = size is" and mpc: "mpc = size \s" and is_\s: "size is + 1 < size \s" shows "\ is@[i],xt [::] \s" (*<*) proof - have pc_xt: "pc \ pcs xt" using wtis pc by (fastforce simp:wt_instrs_def) have "pcs xt \ {.. pc' < length is" "pc' < Suc (length is)" have "P,T\<^sub>r,mxs,length \s,xt \ i,pc' :: \s" using wt_instr_appLx[where xt = "[]",simplified,OF wti pc_xt] less_antisym[OF pc'] pc mpc by simp } ultimately show ?thesis using wtis is_\s by(clarsimp simp add:wt_instrs_def) qed (*>*) corollary (in TC2) wt_instrs_app2: "\ \ is\<^sub>2,xt\<^sub>2 [::] \'#\s\<^sub>2; \ is\<^sub>1,xt\<^sub>1 [::] \#\s\<^sub>1@[\']; xt' = xt\<^sub>1 @ shift (size is\<^sub>1) xt\<^sub>2; size \s\<^sub>1+1 = size is\<^sub>1 \ \ \ is\<^sub>1@is\<^sub>2,xt' [::] \#\s\<^sub>1@\'#\s\<^sub>2" (*<*)using wt_instrs_app[where ?\s\<^sub>1.0 = "\ # \s\<^sub>1"] by simp (*>*) corollary (in TC2) wt_instrs_app2_simp[trans,simp]: "\ \ is\<^sub>2,xt\<^sub>2 [::] \'#\s\<^sub>2; \ is\<^sub>1,xt\<^sub>1 [::] \#\s\<^sub>1@[\']; size \s\<^sub>1+1 = size is\<^sub>1 \ \ \ is\<^sub>1@is\<^sub>2, xt\<^sub>1@shift (size is\<^sub>1) xt\<^sub>2 [::] \#\s\<^sub>1@\'#\s\<^sub>2" (*<*)using wt_instrs_app[where ?\s\<^sub>1.0 = "\ # \s\<^sub>1"] by simp(*>*) corollary (in TC2) wt_instrs_Cons[simp]: "\ \s \ []; \ [i],[] [::] [\,\']; \ is,xt [::] \'#\s \ \ \ i#is,shift 1 xt [::] \#\'#\s" (*<*) using wt_instrs_app2[where ?is\<^sub>1.0 = "[i]" and ?\s\<^sub>1.0 = "[]" and ?is\<^sub>2.0 = "is" and ?xt\<^sub>1.0 = "[]"] by simp corollary (in TC2) wt_instrs_Cons2[trans]: assumes \s: "\ is,xt [::] \s" assumes i: "P,T\<^sub>r,mxs,mpc,[] \ i,0 :: \#\s" assumes mpc: "mpc = size \s + 1" shows "\ i#is,shift 1 xt [::] \#\s" (*<*) proof - from \s have "\s \ []" by (auto simp: wt_instrs_def) with mpc i have "\ [i],[] [::] [\]@\s" by (simp add: wt_instrs_def) with \s show ?thesis by (fastforce dest: wt_instrs_ext) qed (*>*) lemma (in TC2) wt_instrs_last_incr[trans]: assumes wtis: "\ is,xt [::] \s@[\]" and ss: "P \ \ \' \'" shows "\ is,xt [::] \s@[\']" (*<*) proof - let ?\s = "\s@[\]" and ?\s' = "\s@[\']" { fix pc assume pc: "pc< size is" let ?i = "is!pc" have app_pc: "app (is ! pc) P mxs T\<^sub>r pc (length ?\s) xt (\s ! pc)" using wtis pc by(clarsimp simp add:wt_instrs_def wt_instr_def) then have Apc\': "\pc' \'. (pc',\') \ set (eff ?i P pc xt (?\s!pc)) \ pc' < length ?\s" using wtis pc by(fastforce simp add:wt_instrs_def app_def) have Aepc\': "\pc' \'. (pc',\') \ set (eff ?i P pc xt (?\s!pc)) \ P \ \' \' ?\s!pc'" using wtis pc by(fastforce simp add:wt_instrs_def wt_instr_def) { fix pc1 \1 assume pc\1: "(pc1,\1) \ set (eff ?i P pc xt (?\s'!pc))" then have epc\': "(pc1,\1) \ set (eff ?i P pc xt (?\s!pc))" using wtis pc by(simp add:wt_instrs_def) have "P \ \1 \' ?\s'!pc1" proof(cases "pc1 < length \s") case True then show ?thesis using wtis pc pc\1 by(fastforce simp add:wt_instrs_def wt_instr_def) next case False then have "pc1 < length ?\s" using Apc\'[OF epc\'] by simp then have [simp]: "pc1 = size \s" using False by clarsimp have "P \ \1 \' \" using Aepc\'[OF epc\'] by simp then have "P \ \1 \' \'" by(rule sup_state_opt_trans[OF _ ss]) then show ?thesis by simp qed } then have "P,T\<^sub>r,mxs,size ?\s',xt \ is!pc,pc :: ?\s'" using wtis pc by(clarsimp simp add:wt_instrs_def wt_instr_def) } then show ?thesis using wtis by(simp add:wt_instrs_def) qed (*>*) lemma [iff]: "xcpt_app i P pc mxs [] \" (*<*)by (simp add: xcpt_app_def relevant_entries_def)(*>*) lemma [simp]: "xcpt_eff i P pc \ [] = []" (*<*)by (simp add: xcpt_eff_def relevant_entries_def)(*>*) lemma (in TC2) wt_New: "\ is_class P C; size ST < mxs \ \ \ [New C],[] [::] [ty\<^sub>i' ST E A, ty\<^sub>i' (Class C#ST) E A]" (*<*)by(simp add:wt_defs ty\<^sub>i'_def)(*>*) lemma (in TC2) wt_Cast: "is_class P C \ \ [Checkcast C],[] [::] [ty\<^sub>i' (Class D # ST) E A, ty\<^sub>i' (Class C # ST) E A]" (*<*)by(simp add: ty\<^sub>i'_def wt_defs)(*>*) lemma (in TC2) wt_Push: "\ size ST < mxs; typeof v = Some T \ \ \ [Push v],[] [::] [ty\<^sub>i' ST E A, ty\<^sub>i' (T#ST) E A]" (*<*)by(simp add: ty\<^sub>i'_def wt_defs)(*>*) lemma (in TC2) wt_Pop: "\ [Pop],[] [::] (ty\<^sub>i' (T#ST) E A # ty\<^sub>i' ST E A # \s)" (*<*)by(simp add: ty\<^sub>i'_def wt_defs)(*>*) lemma (in TC2) wt_CmpEq: "\ P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1\ \ \ [CmpEq],[] [::] [ty\<^sub>i' (T\<^sub>2 # T\<^sub>1 # ST) E A, ty\<^sub>i' (Boolean # ST) E A]" (*<*) by(auto simp:ty\<^sub>i'_def wt_defs elim!: refTE not_refTE) (*>*) lemma (in TC2) wt_IAdd: "\ [IAdd],[] [::] [ty\<^sub>i' (Integer#Integer#ST) E A, ty\<^sub>i' (Integer#ST) E A]" (*<*)by(simp add:ty\<^sub>i'_def wt_defs)(*>*) lemma (in TC2) wt_Load: "\ size ST < mxs; size E \ mxl; i \\ A; i < size E \ \ \ [Load i],[] [::] [ty\<^sub>i' ST E A, ty\<^sub>i' (E!i # ST) E A]" (*<*)by(auto simp add:ty\<^sub>i'_def wt_defs ty\<^sub>l_def hyperset_defs)(*>*) lemma (in TC2) wt_Store: "\ P \ T \ E!i; i < size E; size E \ mxl \ \ \ [Store i],[] [::] [ty\<^sub>i' (T#ST) E A, ty\<^sub>i' ST E (\{i}\ \ A)]" (*<*) by(auto simp:hyperset_defs nth_list_update ty\<^sub>i'_def wt_defs ty\<^sub>l_def intro:list_all2_all_nthI) (*>*) lemma (in TC2) wt_Get: "\ P \ C sees F,NonStatic:T in D \ \ \ [Getfield F D],[] [::] [ty\<^sub>i' (Class C # ST) E A, ty\<^sub>i' (T # ST) E A]" (*<*)by(auto simp: ty\<^sub>i'_def wt_defs dest: sees_field_idemp sees_field_decl_above)(*>*) lemma (in TC2) wt_GetS: "\ size ST < mxs; P \ C sees F,Static:T in D \ \ \ [Getstatic C F D],[] [::] [ty\<^sub>i' ST E A, ty\<^sub>i' (T # ST) E A]" (*<*)by(auto simp: ty\<^sub>i'_def wt_defs dest: sees_field_idemp sees_field_decl_above)(*>*) lemma (in TC2) wt_Put: "\ P \ C sees F,NonStatic:T in D; P \ T' \ T \ \ \ [Putfield F D],[] [::] [ty\<^sub>i' (T' # Class C # ST) E A, ty\<^sub>i' ST E A]" (*<*)by(auto intro: sees_field_idemp sees_field_decl_above simp: ty\<^sub>i'_def wt_defs)(*>*) lemma (in TC2) wt_PutS: "\ P \ C sees F,Static:T in D; P \ T' \ T \ \ \ [Putstatic C F D],[] [::] [ty\<^sub>i' (T' # ST) E A, ty\<^sub>i' ST E A]" (*<*)by(auto intro: sees_field_idemp sees_field_decl_above simp: ty\<^sub>i'_def wt_defs)(*>*) lemma (in TC2) wt_Throw: "\ [Throw],[] [::] [ty\<^sub>i' (Class C # ST) E A, \']" (*<*)by(auto simp: ty\<^sub>i'_def wt_defs)(*>*) lemma (in TC2) wt_IfFalse: "\ 2 \ i; nat i < size \s + 2; P \ ty\<^sub>i' ST E A \' \s ! nat(i - 2) \ \ \ [IfFalse i],[] [::] ty\<^sub>i' (Boolean # ST) E A # ty\<^sub>i' ST E A # \s" (*<*) by(simp add: ty\<^sub>i'_def wt_defs eval_nat_numeral nat_diff_distrib) (*>*) lemma wt_Goto: "\ 0 \ int pc + i; nat (int pc + i) < size \s; size \s \ mpc; P \ \s!pc \' \s ! nat (int pc + i) \ \ P,T,mxs,mpc,[] \ Goto i,pc :: \s" (*<*)by(clarsimp simp add: TC2.wt_defs)(*>*) lemma (in TC2) wt_Invoke: "\ size es = size Ts'; P \ C sees M,NonStatic: Ts\T = m in D; P \ Ts' [\] Ts \ \ \ [Invoke M (size es)],[] [::] [ty\<^sub>i' (rev Ts' @ Class C # ST) E A, ty\<^sub>i' (T#ST) E A]" (*<*)by(fastforce simp add: ty\<^sub>i'_def wt_defs)(*>*) lemma (in TC2) wt_Invokestatic: "\ size ST < mxs; size es = size Ts'; M \ clinit; P \ C sees M,Static: Ts\T = m in D; P \ Ts' [\] Ts \ \ \ [Invokestatic C M (size es)],[] [::] [ty\<^sub>i' (rev Ts' @ ST) E A, ty\<^sub>i' (T#ST) E A]" (*<*)by(fastforce simp add: ty\<^sub>i'_def wt_defs)(*>*) corollary (in TC2) wt_instrs_app3[simp]: "\ \ is\<^sub>2,[] [::] (\' # \s\<^sub>2); \ is\<^sub>1,xt\<^sub>1 [::] \ # \s\<^sub>1 @ [\']; size \s\<^sub>1+1 = size is\<^sub>1\ \ \ (is\<^sub>1 @ is\<^sub>2),xt\<^sub>1 [::] \ # \s\<^sub>1 @ \' # \s\<^sub>2" (*<*)using wt_instrs_app2[where ?xt\<^sub>2.0 = "[]"] by (simp add:shift_def)(*>*) corollary (in TC2) wt_instrs_Cons3[simp]: "\ \s \ []; \ [i],[] [::] [\,\']; \ is,[] [::] \'#\s \ \ \ (i # is),[] [::] \ # \' # \s" (*<*) using wt_instrs_Cons[where ?xt = "[]"] by (simp add:shift_def) (*<*) declare nth_append[simp del] declare [[simproc del: list_to_set_comprehension]] (*>*) lemma (in TC2) wt_instrs_xapp[trans]: assumes wtis: "\ is\<^sub>1 @ is\<^sub>2, xt [::] \s\<^sub>1 @ ty\<^sub>i' (Class C # ST) E A # \s\<^sub>2" and P_\s\<^sub>1: "\\ \ set \s\<^sub>1. \ST' LT'. \ = Some(ST',LT') \ size ST \ size ST' \ P \ Some (drop (size ST' - size ST) ST',LT') \' ty\<^sub>i' ST E A" and is_\s: "size is\<^sub>1 = size \s\<^sub>1" and PC: "is_class P C" and ST_mxs: "size ST < mxs" shows "\ is\<^sub>1 @ is\<^sub>2, xt @ [(0,size is\<^sub>1 - 1,C,size is\<^sub>1,size ST)] [::] \s\<^sub>1 @ ty\<^sub>i' (Class C # ST) E A # \s\<^sub>2" (*<*)(is "\ ?is, xt@[?xte] [::] ?\s" is "\ ?is, ?xt' [::] ?\s") proof - have P_\s\<^sub>1': "\\. \ \ set \s\<^sub>1 \ (\ST' LT'. \ = Some(ST',LT') \ size ST \ size ST' \ P \ Some (drop (size ST' - size ST) ST',LT') \' ty\<^sub>i' ST E A)" using P_\s\<^sub>1 by fast have "size ?is < size ?\s" and "pcs ?xt' \ {0..pc. pc< size ?is \ P,T\<^sub>r,mxs,size ?\s,xt \ ?is!pc,pc :: ?\s" using wtis by(simp_all add:wt_instrs_def) moreover { fix pc let ?mpc = "size ?\s" and ?i = "?is!pc" and ?t = "?\s!pc" assume "pc< size ?is" then have wti: "P,T\<^sub>r,mxs,?mpc,xt \ ?i,pc :: ?\s" by(rule P_pc) then have app: "app ?i P mxs T\<^sub>r pc ?mpc xt ?t" and eff_ss: "\pc' \'. (pc',\') \ set (eff ?i P pc xt (?\s!pc)) \ P \ \' \' ?\s!pc'" by(fastforce simp add: wt_instr_def)+ have "app ?i P mxs T\<^sub>r pc ?mpc ?xt' ?t \ (\(pc',\') \ set (eff ?i P pc ?xt' ?t). P \ \' \' ?\s!pc')" proof (cases ?t) case (Some \) obtain ST' LT' where \: "\ = (ST', LT')" by(cases \) simp have app\<^sub>i: "app\<^sub>i (?i,P,pc,mxs,T\<^sub>r,\)" and xcpt_app: "xcpt_app ?i P pc mxs xt \" and eff_pc: "\pc' \'. (pc',\') \ set (eff ?i P pc xt ?t) \ pc' < ?mpc" using Some app by(fastforce simp add: app_def)+ have "xcpt_app ?i P pc mxs ?xt' \" proof(cases "pc < length \s\<^sub>1 - 1") case False then show ?thesis using Some \ is_\s xcpt_app by (clarsimp simp: xcpt_app_def relevant_entries_def is_relevant_entry_def) next case True then have True': "pc < length \s\<^sub>1" by simp then have "\s\<^sub>1 ! pc = ?t" by(fastforce simp: nth_append) moreover have \s\<^sub>1_pc: "\s\<^sub>1 ! pc \ set \s\<^sub>1" by(rule nth_mem[OF True']) ultimately show ?thesis using Some \ PC ST_mxs xcpt_app P_\s\<^sub>1'[OF \s\<^sub>1_pc] by (simp add: xcpt_app_def relevant_entries_def) qed moreover { fix pc' \' assume efft: "(pc',\') \ set (eff ?i P pc ?xt' ?t)" have "pc' < ?mpc \ P \ \' \' ?\s!pc'" (is "?P1 \ ?P2") proof(cases "(pc',\') \ set (eff ?i P pc xt ?t)") case True have ?P1 using True by(rule eff_pc) moreover have ?P2 using True by(rule eff_ss) ultimately show ?thesis by simp next case False then have xte: "(pc',\') \ set (xcpt_eff ?i P pc \ [?xte])" using efft Some by(clarsimp simp: eff_def) then have ?P1 using Some \ is_\s by(clarsimp simp: xcpt_eff_def relevant_entries_def split: if_split_asm) moreover have ?P2 proof(cases "pc < length \s\<^sub>1 - 1") case False': False then show ?thesis using False Some \ xte is_\s by(simp add: xcpt_eff_def relevant_entries_def is_relevant_entry_def) next case True then have True': "pc < length \s\<^sub>1" by simp have \s\<^sub>1_pc: "\s\<^sub>1 ! pc \ set \s\<^sub>1" by(rule nth_mem[OF True']) have "P \ \(Class C # drop (length ST' - length ST) ST', LT')\ \' ty\<^sub>i' (Class C # ST) E A" using True' Some \ P_\s\<^sub>1'[OF \s\<^sub>1_pc] by (fastforce simp: nth_append ty\<^sub>i'_def) then show ?thesis using \ xte is_\s by(simp add: xcpt_eff_def relevant_entries_def split: if_split_asm) qed ultimately show ?thesis by simp qed } ultimately show ?thesis using Some app\<^sub>i by(fastforce simp add: app_def) qed simp then have "P,T\<^sub>r,mxs,size ?\s,?xt' \ ?is!pc,pc :: ?\s" by(simp add: wt_instr_def) } ultimately show ?thesis by(simp add:wt_instrs_def) qed declare [[simproc add: list_to_set_comprehension]] declare nth_append[simp] (*>*) lemma drop_Cons_Suc: "\xs. drop n xs = y#ys \ drop (Suc n) xs = ys" proof(induct n) case (Suc n) then show ?case by(simp add: drop_Suc) qed simp lemma drop_mess: assumes "Suc (length xs\<^sub>0) \ length xs" and "drop (length xs - Suc (length xs\<^sub>0)) xs = x # xs\<^sub>0" shows "drop (length xs - length xs\<^sub>0) xs = xs\<^sub>0" using assms proof(cases xs) case (Cons a list) then show ?thesis using assms proof(cases "length list - length xs\<^sub>0") case Suc then show ?thesis using Cons assms by (simp add: Suc_diff_le drop_Cons_Suc) qed simp qed simp (*<*) declare (in TC0) after_def[simp] pair_eq_ty\<^sub>i'_conv[simp] (*>*) lemma (in TC1) compT_ST_prefix: "\E A ST\<^sub>0. \(ST,LT)\ \ set(compT E A ST\<^sub>0 e) \ size ST\<^sub>0 \ size ST \ drop (size ST - size ST\<^sub>0) ST = ST\<^sub>0" and "\E A ST\<^sub>0. \(ST,LT)\ \ set(compTs E A ST\<^sub>0 es) \ size ST\<^sub>0 \ size ST \ drop (size ST - size ST\<^sub>0) ST = ST\<^sub>0" (*<*) proof(induct e and es rule: compT.induct compTs.induct) case (FAss e\<^sub>1 F D e\<^sub>2) moreover { let ?ST\<^sub>0 = "ty E e\<^sub>1 # ST\<^sub>0" fix A assume "\(ST, LT)\ \ set (compT E A ?ST\<^sub>0 e\<^sub>2)" with FAss have "length ?ST\<^sub>0 \ length ST \ drop (size ST - size ?ST\<^sub>0) ST = ?ST\<^sub>0" by blast hence ?case by (clarsimp simp add: drop_mess) } ultimately show ?case by auto next case TryCatch thus ?case by auto next case Block thus ?case by auto next case Seq thus ?case by auto next case While thus ?case by auto next case Cond thus ?case by auto next case (Call e M es) moreover { let ?ST\<^sub>0 = "ty E e # ST\<^sub>0" fix A assume "\(ST, LT)\ \ set (compTs E A ?ST\<^sub>0 es)" with Call have "length ?ST\<^sub>0 \ length ST \ drop (size ST - size ?ST\<^sub>0) ST = ?ST\<^sub>0" by blast hence ?case by (clarsimp simp add: drop_mess) } ultimately show ?case by auto next case (Cons_exp e es) moreover { let ?ST\<^sub>0 = "ty E e # ST\<^sub>0" fix A assume "\(ST, LT)\ \ set (compTs E A ?ST\<^sub>0 es)" with Cons_exp have "length ?ST\<^sub>0 \ length ST \ drop (size ST - size ?ST\<^sub>0) ST = ?ST\<^sub>0" by blast hence ?case by (clarsimp simp add: drop_mess) } ultimately show ?case by auto next case (BinOp e\<^sub>1 bop e\<^sub>2) moreover { let ?ST\<^sub>0 = "ty E e\<^sub>1 # ST\<^sub>0" fix A assume "\(ST, LT)\ \ set (compT E A ?ST\<^sub>0 e\<^sub>2)" with BinOp have "length ?ST\<^sub>0 \ length ST \ drop (size ST - size ?ST\<^sub>0) ST = ?ST\<^sub>0" by blast hence ?case by (clarsimp simp add: drop_mess) } ultimately show ?case by auto next case new thus ?case by auto next case Val thus ?case by auto next case Cast thus ?case by auto next case Var thus ?case by auto next case LAss thus ?case by auto next case throw thus ?case by auto next case FAcc thus ?case by auto next case SFAcc thus ?case by auto next case SFAss thus ?case by auto next case (SCall C M es) thus ?case by auto next case INIT thus ?case by auto next case RI thus ?case by auto next case Nil_exp thus ?case by auto qed declare (in TC0) after_def[simp del] pair_eq_ty\<^sub>i'_conv[simp del] (*>*) (* FIXME *) lemma fun_of_simp [simp]: "fun_of S x y = ((x,y) \ S)" (*<*) by (simp add: fun_of_def)(*>*) theorem (in TC2) compT_wt_instrs: "\E T A ST. \ P,E \\<^sub>1 e :: T; \ e A; \ e (size E); size ST + max_stack e \ mxs; size E + max_vars e \ mxl \ \ \ compE\<^sub>2 e, compxE\<^sub>2 e 0 (size ST) [::] ty\<^sub>i' ST E A # compT E A ST e @ [after E A ST e]" (*<*)(is "\E T A ST. PROP ?P e E T A ST")(*>*) and "\E Ts A ST. \ P,E \\<^sub>1 es[::]Ts; \s es A; \s es (size E); size ST + max_stacks es \ mxs; size E + max_varss es \ mxl \ \ let \s = ty\<^sub>i' ST E A # compTs E A ST es in \ compEs\<^sub>2 es,compxEs\<^sub>2 es 0 (size ST) [::] \s \ last \s = ty\<^sub>i' (rev Ts @ ST) E (A \ \s es)" (*<*) (is "\E Ts A ST. PROP ?Ps es E Ts A ST") proof(induct e and es rule: compxE\<^sub>2.induct compxEs\<^sub>2.induct) case (TryCatch e\<^sub>1 C i e\<^sub>2) hence [simp]: "i = size E" by simp have wt\<^sub>1: "P,E \\<^sub>1 e\<^sub>1 :: T" and wt\<^sub>2: "P,E@[Class C] \\<^sub>1 e\<^sub>2 :: T" and "class": "is_class P C" using TryCatch by auto let ?A\<^sub>1 = "A \ \ e\<^sub>1" let ?A\<^sub>i = "A \ \{i}\" let ?E\<^sub>i = "E @ [Class C]" let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>1 = "compT E A ST e\<^sub>1" let ?\\<^sub>1 = "ty\<^sub>i' (T#ST) E ?A\<^sub>1" let ?\\<^sub>2 = "ty\<^sub>i' (Class C#ST) E A" let ?\\<^sub>3 = "ty\<^sub>i' ST ?E\<^sub>i ?A\<^sub>i" let ?\s\<^sub>2 = "compT ?E\<^sub>i ?A\<^sub>i ST e\<^sub>2" let ?\\<^sub>2' = "ty\<^sub>i' (T#ST) ?E\<^sub>i (?A\<^sub>i \ \ e\<^sub>2)" let ?\' = "ty\<^sub>i' (T#ST) E (A \ \ e\<^sub>1 \ (\ e\<^sub>2 \ i))" let ?go = "Goto (int(size(compE\<^sub>2 e\<^sub>2)) + 2)" have "PROP ?P e\<^sub>2 ?E\<^sub>i T ?A\<^sub>i ST" by fact hence "\ compE\<^sub>2 e\<^sub>2,compxE\<^sub>2 e\<^sub>2 0 (size ST) [::] (?\\<^sub>3 # ?\s\<^sub>2) @ [?\\<^sub>2']" using TryCatch.prems by(auto simp:after_def) also have "?A\<^sub>i \ \ e\<^sub>2 = (A \ \ e\<^sub>2) \ \{size E}\" by(fastforce simp:hyperset_defs) also have "P \ ty\<^sub>i' (T#ST) ?E\<^sub>i \ \' ty\<^sub>i' (T#ST) E (A \ \ e\<^sub>2)" by(simp add:hyperset_defs ty\<^sub>l_incr ty\<^sub>i'_def) also have "P \ \ \' ty\<^sub>i' (T#ST) E (A \ \ e\<^sub>1 \ (\ e\<^sub>2 \ i))" by(auto intro!: ty\<^sub>l_antimono simp:hyperset_defs ty\<^sub>i'_def) also have "(?\\<^sub>3 # ?\s\<^sub>2) @ [?\'] = ?\\<^sub>3 # ?\s\<^sub>2 @ [?\']" by simp also have "\ [Store i],[] [::] ?\\<^sub>2 # [] @ [?\\<^sub>3]" using TryCatch.prems by(auto simp:nth_list_update wt_defs ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth hyperset_defs) also have "[] @ (?\\<^sub>3 # ?\s\<^sub>2 @ [?\']) = (?\\<^sub>3 # ?\s\<^sub>2 @ [?\'])" by simp also have "P,T\<^sub>r,mxs,size(compE\<^sub>2 e\<^sub>2)+3,[] \ ?go,0 :: ?\\<^sub>1#?\\<^sub>2#?\\<^sub>3#?\s\<^sub>2 @ [?\']" using wt\<^sub>2 by (auto simp: hyperset_defs ty\<^sub>i'_def wt_defs nth_Cons nat_add_distrib fun_of_def intro: ty\<^sub>l_antimono list_all2_refl split:nat.split) also have "\ compE\<^sub>2 e\<^sub>1,compxE\<^sub>2 e\<^sub>1 0 (size ST) [::] ?\ # ?\s\<^sub>1 @ [?\\<^sub>1]" using TryCatch by(auto simp:after_def) also have "?\ # ?\s\<^sub>1 @ ?\\<^sub>1 # ?\\<^sub>2 # ?\\<^sub>3 # ?\s\<^sub>2 @ [?\'] = (?\ # ?\s\<^sub>1 @ [?\\<^sub>1]) @ ?\\<^sub>2 # ?\\<^sub>3 # ?\s\<^sub>2 @ [?\']" by simp also have "compE\<^sub>2 e\<^sub>1 @ ?go # [Store i] @ compE\<^sub>2 e\<^sub>2 = (compE\<^sub>2 e\<^sub>1 @ [?go]) @ (Store i # compE\<^sub>2 e\<^sub>2)" by simp also let "?Q \" = "\ST' LT'. \ = \(ST', LT')\ \ size ST \ size ST' \ P \ Some (drop (size ST' - size ST) ST',LT') \' ty\<^sub>i' ST E A" { have "?Q (ty\<^sub>i' ST E A)" by (clarsimp simp add: ty\<^sub>i'_def) moreover have "?Q (ty\<^sub>i' (T # ST) E ?A\<^sub>1)" by (fastforce simp add: ty\<^sub>i'_def hyperset_defs intro!: ty\<^sub>l_antimono) moreover have "\\. \ \ set (compT E A ST e\<^sub>1) \ ?Q \" using TryCatch.prems by clarsimp (frule compT_ST_prefix, fastforce dest!: compT_LT_prefix simp add: ty\<^sub>i'_def) ultimately have "\\\set (ty\<^sub>i' ST E A # compT E A ST e\<^sub>1 @ [ty\<^sub>i' (T # ST) E ?A\<^sub>1]). ?Q \" by auto } also from TryCatch.prems max_stack1[OF wt\<^sub>1] have "size ST + 1 \ mxs" by auto ultimately show ?case using wt\<^sub>1 wt\<^sub>2 TryCatch.prems "class" by (simp add:after_def) next case new thus ?case by(auto simp add:after_def wt_New) next case (BinOp e\<^sub>1 bop e\<^sub>2) let ?op = "case bop of Eq \ [CmpEq] | Add \ [IAdd]" have T: "P,E \\<^sub>1 e\<^sub>1 \bop\ e\<^sub>2 :: T" by fact then obtain T\<^sub>1 T\<^sub>2 where T\<^sub>1: "P,E \\<^sub>1 e\<^sub>1 :: T\<^sub>1" and T\<^sub>2: "P,E \\<^sub>1 e\<^sub>2 :: T\<^sub>2" and bopT: "case bop of Eq \ (P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1) \ T = Boolean | Add \ T\<^sub>1 = Integer \ T\<^sub>2 = Integer \ T = Integer" by auto let ?A\<^sub>1 = "A \ \ e\<^sub>1" let ?A\<^sub>2 = "?A\<^sub>1 \ \ e\<^sub>2" let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>1 = "compT E A ST e\<^sub>1" let ?\\<^sub>1 = "ty\<^sub>i' (T\<^sub>1#ST) E ?A\<^sub>1" let ?\s\<^sub>2 = "compT E ?A\<^sub>1 (T\<^sub>1#ST) e\<^sub>2" let ?\\<^sub>2 = "ty\<^sub>i' (T\<^sub>2#T\<^sub>1#ST) E ?A\<^sub>2" let ?\' = "ty\<^sub>i' (T#ST) E ?A\<^sub>2" from bopT have "\ ?op,[] [::] [?\\<^sub>2,?\']" by (cases bop) (auto simp add: wt_CmpEq wt_IAdd) also have "PROP ?P e\<^sub>2 E T\<^sub>2 ?A\<^sub>1 (T\<^sub>1#ST)" by fact with BinOp.prems T\<^sub>2 have "\ compE\<^sub>2 e\<^sub>2, compxE\<^sub>2 e\<^sub>2 0 (size (T\<^sub>1#ST)) [::] ?\\<^sub>1#?\s\<^sub>2@[?\\<^sub>2]" by (auto simp: after_def) also from BinOp T\<^sub>1 have "\ compE\<^sub>2 e\<^sub>1, compxE\<^sub>2 e\<^sub>1 0 (size ST) [::] ?\#?\s\<^sub>1@[?\\<^sub>1]" by (auto simp: after_def) finally show ?case using T T\<^sub>1 T\<^sub>2 by (simp add: after_def hyperUn_assoc) next case (Cons_exp e es) have "P,E \\<^sub>1 e # es [::] Ts" by fact then obtain T\<^sub>e Ts' where T\<^sub>e: "P,E \\<^sub>1 e :: T\<^sub>e" and Ts': "P,E \\<^sub>1 es [::] Ts'" and Ts: "Ts = T\<^sub>e#Ts'" by auto let ?A\<^sub>e = "A \ \ e" let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>e = "compT E A ST e" let ?\\<^sub>e = "ty\<^sub>i' (T\<^sub>e#ST) E ?A\<^sub>e" let ?\s' = "compTs E ?A\<^sub>e (T\<^sub>e#ST) es" let ?\s = "?\ # ?\s\<^sub>e @ (?\\<^sub>e # ?\s')" have Ps: "PROP ?Ps es E Ts' ?A\<^sub>e (T\<^sub>e#ST)" by fact with Cons_exp.prems T\<^sub>e Ts' have "\ compEs\<^sub>2 es, compxEs\<^sub>2 es 0 (size (T\<^sub>e#ST)) [::] ?\\<^sub>e#?\s'" by (simp add: after_def) also from Cons_exp T\<^sub>e have "\ compE\<^sub>2 e, compxE\<^sub>2 e 0 (size ST) [::] ?\#?\s\<^sub>e@[?\\<^sub>e]" by (auto simp: after_def) moreover from Ps Cons_exp.prems T\<^sub>e Ts' Ts have "last ?\s = ty\<^sub>i' (rev Ts@ST) E (?A\<^sub>e \ \s es)" by simp ultimately show ?case using T\<^sub>e by (simp add: after_def hyperUn_assoc) next case (FAss e\<^sub>1 F D e\<^sub>2) hence Void: "P,E \\<^sub>1 e\<^sub>1\F{D} := e\<^sub>2 :: Void" by auto then obtain C T T' where C: "P,E \\<^sub>1 e\<^sub>1 :: Class C" and sees: "P \ C sees F,NonStatic:T in D" and T': "P,E \\<^sub>1 e\<^sub>2 :: T'" and T'_T: "P \ T' \ T" by auto let ?A\<^sub>1 = "A \ \ e\<^sub>1" let ?A\<^sub>2 = "?A\<^sub>1 \ \ e\<^sub>2" let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>1 = "compT E A ST e\<^sub>1" let ?\\<^sub>1 = "ty\<^sub>i' (Class C#ST) E ?A\<^sub>1" let ?\s\<^sub>2 = "compT E ?A\<^sub>1 (Class C#ST) e\<^sub>2" let ?\\<^sub>2 = "ty\<^sub>i' (T'#Class C#ST) E ?A\<^sub>2" let ?\\<^sub>3 = "ty\<^sub>i' ST E ?A\<^sub>2" let ?\' = "ty\<^sub>i' (Void#ST) E ?A\<^sub>2" from FAss.prems sees T'_T have "\ [Putfield F D,Push Unit],[] [::] [?\\<^sub>2,?\\<^sub>3,?\']" by (fastforce simp add: wt_Push wt_Put) also have "PROP ?P e\<^sub>2 E T' ?A\<^sub>1 (Class C#ST)" by fact with FAss.prems T' have "\ compE\<^sub>2 e\<^sub>2, compxE\<^sub>2 e\<^sub>2 0 (size ST+1) [::] ?\\<^sub>1#?\s\<^sub>2@[?\\<^sub>2]" by (auto simp add: after_def hyperUn_assoc) also from FAss C have "\ compE\<^sub>2 e\<^sub>1, compxE\<^sub>2 e\<^sub>1 0 (size ST) [::] ?\#?\s\<^sub>1@[?\\<^sub>1]" by (auto simp add: after_def) finally show ?case using Void C T' by (simp add: after_def hyperUn_assoc) next case (SFAss C F D e\<^sub>2) hence Void: "P,E \\<^sub>1 C\\<^sub>sF{D} := e\<^sub>2 :: Void" by auto then obtain T T' where sees: "P \ C sees F,Static:T in D" and T': "P,E \\<^sub>1 e\<^sub>2 :: T'" and T'_T: "P \ T' \ T" by auto let ?A\<^sub>2 = "A \ \ e\<^sub>2" let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>2 = "compT E A ST e\<^sub>2" let ?\\<^sub>2 = "ty\<^sub>i' (T'#ST) E ?A\<^sub>2" let ?\\<^sub>3 = "ty\<^sub>i' ST E ?A\<^sub>2" let ?\' = "ty\<^sub>i' (Void#ST) E ?A\<^sub>2" from SFAss.prems sees T'_T max_stack1[OF T'] have "\ [Putstatic C F D,Push Unit],[] [::] [?\\<^sub>2,?\\<^sub>3,?\']" by (fastforce simp add: wt_Push wt_PutS) also have "PROP ?P e\<^sub>2 E T' A ST" by fact with SFAss.prems T' have "\ compE\<^sub>2 e\<^sub>2, compxE\<^sub>2 e\<^sub>2 0 (size ST) [::] ?\#?\s\<^sub>2@[?\\<^sub>2]" by (auto simp add: after_def hyperUn_assoc) finally show ?case using Void T' by (simp add: after_def hyperUn_assoc) next case Val thus ?case by(auto simp:after_def wt_Push) next case Cast thus ?case by (auto simp:after_def wt_Cast) next case (Block i T\<^sub>i e) let ?\s = "ty\<^sub>i' ST E A # compT (E @ [T\<^sub>i]) (A\i) ST e" have IH: "PROP ?P e (E@[T\<^sub>i]) T (A\i) ST" by fact hence "\ compE\<^sub>2 e, compxE\<^sub>2 e 0 (size ST) [::] ?\s @ [ty\<^sub>i' (T#ST) (E@[T\<^sub>i]) (A\(size E) \ \ e)]" using Block.prems by (auto simp add: after_def) also have "P \ ty\<^sub>i' (T # ST) (E@[T\<^sub>i]) (A \ size E \ \ e) \' ty\<^sub>i' (T # ST) (E@[T\<^sub>i]) ((A \ \ e) \ size E)" by(auto simp add:hyperset_defs intro: ty\<^sub>i'_antimono) also have "\ = ty\<^sub>i' (T # ST) E (A \ \ e)" by simp also have "P \ \ \' ty\<^sub>i' (T # ST) E (A \ (\ e \ i))" by(auto simp add:hyperset_defs intro: ty\<^sub>i'_antimono) finally show ?case using Block.prems by(simp add: after_def) next case Var thus ?case by(auto simp:after_def wt_Load) next case FAcc thus ?case by(auto simp:after_def wt_Get) next case SFAcc thus ?case by(auto simp: after_def wt_GetS) next case (LAss i e) then obtain T' where wt: "P,E \\<^sub>1 e :: T'" by auto show ?case using max_stack1[OF wt] LAss by(auto simp: hyper_insert_comm after_def wt_Store wt_Push) next case Nil_exp thus ?case by auto next case throw thus ?case by(auto simp add: after_def wt_Throw) next case (While e c) obtain Tc where wte: "P,E \\<^sub>1 e :: Boolean" and wtc: "P,E \\<^sub>1 c :: Tc" and [simp]: "T = Void" using While by auto have [simp]: "ty E (while (e) c) = Void" using While by simp let ?A\<^sub>0 = "A \ \ e" let ?A\<^sub>1 = "?A\<^sub>0 \ \ c" let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>e = "compT E A ST e" let ?\\<^sub>e = "ty\<^sub>i' (Boolean#ST) E ?A\<^sub>0" let ?\\<^sub>1 = "ty\<^sub>i' ST E ?A\<^sub>0" let ?\s\<^sub>c = "compT E ?A\<^sub>0 ST c" let ?\\<^sub>c = "ty\<^sub>i' (Tc#ST) E ?A\<^sub>1" let ?\\<^sub>2 = "ty\<^sub>i' ST E ?A\<^sub>1" let ?\' = "ty\<^sub>i' (Void#ST) E ?A\<^sub>0" let ?\s = "(?\ # ?\s\<^sub>e @ [?\\<^sub>e]) @ ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c, ?\\<^sub>2, ?\\<^sub>1, ?\']" have "\ [],[] [::] [] @ ?\s" by(simp add:wt_instrs_def) also have "PROP ?P e E Boolean A ST" by fact hence "\ compE\<^sub>2 e,compxE\<^sub>2 e 0 (size ST) [::] ?\ # ?\s\<^sub>e @ [?\\<^sub>e]" using While.prems by (auto simp:after_def) also have "[] @ ?\s = (?\ # ?\s\<^sub>e) @ ?\\<^sub>e # ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c,?\\<^sub>2,?\\<^sub>1,?\']" by simp also let ?n\<^sub>e = "size(compE\<^sub>2 e)" let ?n\<^sub>c = "size(compE\<^sub>2 c)" + thm compT_sizes(1) let ?if = "IfFalse (int ?n\<^sub>c + 3)" - have "\ [?if],[] [::] ?\\<^sub>e # ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c, ?\\<^sub>2, ?\\<^sub>1, ?\']" using wtc - by(simp add: wt_instr_Cons wt_instr_append wt_IfFalse - nat_add_distrib split: nat_diff_split) + from wtc wte have "compE\<^sub>2 c \ []" and "compE\<^sub>2 e \ []" using WT\<^sub>1_nsub_RI by auto + then have compe2c: "length (compE\<^sub>2 c) > 0" and compe2e: "length (compE\<^sub>2 e) > 0" by auto + have Suc_pred'_auxi: "\n. 0 < n \ n = Suc (n - Suc 0)" using Suc_pred'[OF compe2c] by auto + have "\ [?if],[] [::] ?\\<^sub>e # ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c, ?\\<^sub>2, ?\\<^sub>1, ?\']" + proof-{ + show ?thesis + apply (rule wt_IfFalse) + apply simp + apply simp + apply (subgoal_tac "length (compE\<^sub>2 c) = length (compT E (A \ \ e) ST c) + 1" + "nat (int (length (compE\<^sub>2 c)) + 3 - 2) > length (compT E (A \ \ e) ST c)") + apply (insert Suc_pred'_auxi[OF compe2c]) + apply (simp add:compT_sizes(1)[OF wtc] )+ + done + } + qed also have "(?\ # ?\s\<^sub>e) @ (?\\<^sub>e # ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c, ?\\<^sub>2, ?\\<^sub>1, ?\']) = ?\s" by simp also have "PROP ?P c E Tc ?A\<^sub>0 ST" by fact hence "\ compE\<^sub>2 c,compxE\<^sub>2 c 0 (size ST) [::] ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c]" using While.prems wtc by (auto simp:after_def) also have "?\s = (?\ # ?\s\<^sub>e @ [?\\<^sub>e,?\\<^sub>1] @ ?\s\<^sub>c) @ [?\\<^sub>c,?\\<^sub>2,?\\<^sub>1,?\']" by simp also have "\ [Pop],[] [::] [?\\<^sub>c, ?\\<^sub>2]" by(simp add:wt_Pop) also have "(?\ # ?\s\<^sub>e @ [?\\<^sub>e,?\\<^sub>1] @ ?\s\<^sub>c) @ [?\\<^sub>c,?\\<^sub>2,?\\<^sub>1,?\'] = ?\s" by simp also let ?go = "Goto (-int(?n\<^sub>c+?n\<^sub>e+2))" have "P \ ?\\<^sub>2 \' ?\" by(fastforce intro: ty\<^sub>i'_antimono simp: hyperset_defs) hence "P,T\<^sub>r,mxs,size ?\s,[] \ ?go,?n\<^sub>e+?n\<^sub>c+2 :: ?\s" using wte wtc - by(simp add: wt_Goto split: nat_diff_split) + proof-{ + let ?t1 = "ty\<^sub>i' ST E A" let ?t2 = "ty\<^sub>i' (Boolean # ST) E (A \ \ e)" let ?t3 = "ty\<^sub>i' ST E (A \ \ e)" + let ?t4 = "[ty\<^sub>i' (Tc # ST) E (A \ \ e \ \ c), ty\<^sub>i' ST E (A \ \ e \ \ c), ty\<^sub>i' ST E (A \ \ e), ty\<^sub>i' (Void # ST) E (A \ \ e)]" + let ?c = " compT E (A \ \ e) ST c" let ?e = "compT E A ST e" + + assume ass: "P \ ty\<^sub>i' ST E (A \ \ e \ \ c) \' ?t1" + show ?thesis + apply (rule wt_Goto) + apply simp + apply simp + apply simp + proof-{ + let ?s1 = "((?t1 # ?e @ [?t2]) @ ?t3 # ?c)" + have len1: "length ?c = length (compE\<^sub>2 c) - 1" using compT_sizes(1)[OF wtc] by simp + have len2: "length ?e = length (compE\<^sub>2 e) - 1" using compT_sizes(1)[OF wte] by simp + hence "length (compE\<^sub>2 e) + length (compE\<^sub>2 c) + 2 > length ?s1" + using len1 compe2c compe2e by auto + hence "(?s1 @ ?t4) ! (length (compE\<^sub>2 e) + length (compE\<^sub>2 c) + 2) = + ?t4 ! (length (compE\<^sub>2 e) + length (compE\<^sub>2 c) + 2 - length ?s1)" + by (auto simp only:nth_append split: if_splits) + hence "(?s1 @ ?t4) ! (length (compE\<^sub>2 e) + length (compE\<^sub>2 c) + 2) = ty\<^sub>i' ST E (A \ \ e \ \ c)" + using len1 len2 compe2c compe2e by auto + hence "P \ (?s1 @ ?t4) ! (length (compE\<^sub>2 e) + length (compE\<^sub>2 c) + 2) \' ty\<^sub>i' ST E A" + using ass by simp + thus "P \ ((?t1 # ?e @ [?t2]) @ ?t3 # ?c @ ?t4) ! (length (compE\<^sub>2 e) + length (compE\<^sub>2 c) + 2) \' + ((?t1 # ?e @ [?t2]) @ ?t3 # ?c @ ?t4) ! nat (int (length (compE\<^sub>2 e) + length (compE\<^sub>2 c) + 2) + + - int (length (compE\<^sub>2 c) + length (compE\<^sub>2 e) + 2))" + by simp + }qed + }qed also have "?\s = (?\ # ?\s\<^sub>e @ [?\\<^sub>e,?\\<^sub>1] @ ?\s\<^sub>c @ [?\\<^sub>c, ?\\<^sub>2]) @ [?\\<^sub>1, ?\']" by simp also have "\ [Push Unit],[] [::] [?\\<^sub>1,?\']" using While.prems max_stack1[OF wtc] by(auto simp add:wt_Push) finally show ?case using wtc wte by (simp add:after_def) next case (Cond e e\<^sub>1 e\<^sub>2) obtain T\<^sub>1 T\<^sub>2 where wte: "P,E \\<^sub>1 e :: Boolean" and wt\<^sub>1: "P,E \\<^sub>1 e\<^sub>1 :: T\<^sub>1" and wt\<^sub>2: "P,E \\<^sub>1 e\<^sub>2 :: T\<^sub>2" and sub\<^sub>1: "P \ T\<^sub>1 \ T" and sub\<^sub>2: "P \ T\<^sub>2 \ T" using Cond by auto + from wte wt\<^sub>1 wt\<^sub>2 have "compE\<^sub>2 e\<^sub>1 \ []" and "compE\<^sub>2 e\<^sub>2 \ []" and "compE\<^sub>2 e \ []" using WT\<^sub>1_nsub_RI by auto + then have compe: "length (compE\<^sub>2 e) > 0" + and compe1: "length (compE\<^sub>2 e\<^sub>1) > 0" + and compe2: "length (compE\<^sub>2 e\<^sub>2) > 0" by auto + + have [simp]: "ty E (if (e) e\<^sub>1 else e\<^sub>2) = T" using Cond by simp let ?A\<^sub>0 = "A \ \ e" let ?A\<^sub>2 = "?A\<^sub>0 \ \ e\<^sub>2" let ?A\<^sub>1 = "?A\<^sub>0 \ \ e\<^sub>1" let ?A' = "?A\<^sub>0 \ \ e\<^sub>1 \ \ e\<^sub>2" let ?\\<^sub>2 = "ty\<^sub>i' ST E ?A\<^sub>0" let ?\' = "ty\<^sub>i' (T#ST) E ?A'" let ?\s\<^sub>2 = "compT E ?A\<^sub>0 ST e\<^sub>2" have "PROP ?P e\<^sub>2 E T\<^sub>2 ?A\<^sub>0 ST" by fact hence "\ compE\<^sub>2 e\<^sub>2, compxE\<^sub>2 e\<^sub>2 0 (size ST) [::] (?\\<^sub>2#?\s\<^sub>2) @ [ty\<^sub>i' (T\<^sub>2#ST) E ?A\<^sub>2]" using Cond.prems wt\<^sub>2 by(auto simp add:after_def) also have "P \ ty\<^sub>i' (T\<^sub>2#ST) E ?A\<^sub>2 \' ?\'" using sub\<^sub>2 by(auto simp add: hyperset_defs ty\<^sub>i'_def intro!: ty\<^sub>l_antimono) also let ?\\<^sub>3 = "ty\<^sub>i' (T\<^sub>1 # ST) E ?A\<^sub>1" let ?g\<^sub>2 = "Goto(int (size (compE\<^sub>2 e\<^sub>2) + 1))" from sub\<^sub>1 have "P,T\<^sub>r,mxs,size(compE\<^sub>2 e\<^sub>2)+2,[] \ ?g\<^sub>2,0 :: ?\\<^sub>3#(?\\<^sub>2#?\s\<^sub>2)@[?\']" using wt\<^sub>2 by(auto simp: hyperset_defs wt_defs nth_Cons ty\<^sub>i'_def split:nat.split intro!: ty\<^sub>l_antimono) also let ?\s\<^sub>1 = "compT E ?A\<^sub>0 ST e\<^sub>1" have "PROP ?P e\<^sub>1 E T\<^sub>1 ?A\<^sub>0 ST" by fact hence "\ compE\<^sub>2 e\<^sub>1,compxE\<^sub>2 e\<^sub>1 0 (size ST) [::] ?\\<^sub>2 # ?\s\<^sub>1 @ [?\\<^sub>3]" using Cond.prems wt\<^sub>1 by(auto simp add:after_def) also let ?\s\<^sub>1\<^sub>2 = "?\\<^sub>2 # ?\s\<^sub>1 @ ?\\<^sub>3 # (?\\<^sub>2 # ?\s\<^sub>2) @ [?\']" let ?\\<^sub>1 = "ty\<^sub>i' (Boolean#ST) E ?A\<^sub>0" let ?g\<^sub>1 = "IfFalse(int (size (compE\<^sub>2 e\<^sub>1) + 2))" let ?code = "compE\<^sub>2 e\<^sub>1 @ ?g\<^sub>2 # compE\<^sub>2 e\<^sub>2" - have "\ [?g\<^sub>1],[] [::] [?\\<^sub>1] @ ?\s\<^sub>1\<^sub>2" using wt\<^sub>1 - by(simp add: wt_IfFalse nat_add_distrib split:nat_diff_split) + + have len1: "length ?\s\<^sub>1 = length (compE\<^sub>2 e\<^sub>1) - 1" using compT_sizes(1)[OF wt\<^sub>1] by simp + have len2: "length ?\s\<^sub>2 = length (compE\<^sub>2 e\<^sub>2) - 1" using compT_sizes(1)[OF wt\<^sub>2] by simp + have len_auxi: "length (compE\<^sub>2 e\<^sub>1) - (length (compE\<^sub>2 e\<^sub>1) - Suc 0) = Suc 0" using compe1 + by (simp add:diff_Suc split:nat.split) + have "\ [?g\<^sub>1],[] [::] [?\\<^sub>1] @ ?\s\<^sub>1\<^sub>2" + proof-{ + show ?thesis + apply clarsimp + apply (rule wt_IfFalse) + apply (simp only:nat_add_distrib) + apply simp + apply (auto simp only:nth_append split:if_splits) + apply (simp add:len1) + apply (simp only: len1 compe1) + apply (simp add:len1 len2 compe1 compe2 ) + apply (insert len_auxi) + apply simp + done + }qed also (wt_instrs_ext2) have "[?\\<^sub>1] @ ?\s\<^sub>1\<^sub>2 = ?\\<^sub>1 # ?\s\<^sub>1\<^sub>2" by simp also let ?\ = "ty\<^sub>i' ST E A" have "PROP ?P e E Boolean A ST" by fact hence "\ compE\<^sub>2 e, compxE\<^sub>2 e 0 (size ST) [::] ?\ # compT E A ST e @ [?\\<^sub>1]" using Cond.prems wte by(auto simp add:after_def) finally show ?case using wte wt\<^sub>1 wt\<^sub>2 by(simp add:after_def hyperUn_assoc) next case (Call e M es) obtain C D Ts m Ts' where C: "P,E \\<^sub>1 e :: Class C" and "method": "P \ C sees M,NonStatic:Ts \ T = m in D" and wtes: "P,E \\<^sub>1 es [::] Ts'" and subs: "P \ Ts' [\] Ts" using Call.prems by auto from wtes have same_size: "size es = size Ts'" by(rule WTs\<^sub>1_same_size) let ?A\<^sub>0 = "A \ \ e" let ?A\<^sub>1 = "?A\<^sub>0 \ \s es" let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>e = "compT E A ST e" let ?\\<^sub>e = "ty\<^sub>i' (Class C # ST) E ?A\<^sub>0" let ?\s\<^sub>e\<^sub>s = "compTs E ?A\<^sub>0 (Class C # ST) es" let ?\\<^sub>1 = "ty\<^sub>i' (rev Ts' @ Class C # ST) E ?A\<^sub>1" let ?\' = "ty\<^sub>i' (T # ST) E ?A\<^sub>1" have "\ [Invoke M (size es)],[] [::] [?\\<^sub>1,?\']" by(rule wt_Invoke[OF same_size "method" subs]) also have "PROP ?Ps es E Ts' ?A\<^sub>0 (Class C # ST)" by fact hence "\ compEs\<^sub>2 es,compxEs\<^sub>2 es 0 (size ST+1) [::] ?\\<^sub>e # ?\s\<^sub>e\<^sub>s" "last (?\\<^sub>e # ?\s\<^sub>e\<^sub>s) = ?\\<^sub>1" using Call.prems wtes by(auto simp add:after_def) also have "(?\\<^sub>e # ?\s\<^sub>e\<^sub>s) @ [?\'] = ?\\<^sub>e # ?\s\<^sub>e\<^sub>s @ [?\']" by simp also have "\ compE\<^sub>2 e,compxE\<^sub>2 e 0 (size ST) [::] ?\ # ?\s\<^sub>e @ [?\\<^sub>e]" using Call C by(auto simp add:after_def) finally show ?case using Call.prems C wtes by(simp add:after_def hyperUn_assoc) next case (SCall C M es) obtain D Ts m Ts' where "method": "P \ C sees M,Static:Ts \ T = m in D" and wtes: "P,E \\<^sub>1 es [::] Ts'" and subs: "P \ Ts' [\] Ts" using SCall.prems by auto from SCall.prems(1) have nclinit: "M \ clinit" by auto from wtes have same_size: "size es = size Ts'" by(rule WTs\<^sub>1_same_size) have mxs: "length ST < mxs" using WT\<^sub>1_nsub_RI[OF SCall.prems(1)] SCall.prems(4) by simp let ?A\<^sub>1 = "A \ \s es" let ?\ = "ty\<^sub>i' ST E A" let ?\s\<^sub>e\<^sub>s = "compTs E A ST es" let ?\\<^sub>1 = "ty\<^sub>i' (rev Ts' @ ST) E ?A\<^sub>1" let ?\' = "ty\<^sub>i' (T # ST) E ?A\<^sub>1" have "\ [Invokestatic C M (size es)],[] [::] [?\\<^sub>1,?\']" by(rule wt_Invokestatic[OF mxs same_size nclinit "method" subs]) also have "PROP ?Ps es E Ts' A ST" by fact hence "\ compEs\<^sub>2 es,compxEs\<^sub>2 es 0 (size ST) [::] ?\ # ?\s\<^sub>e\<^sub>s" "last (?\ # ?\s\<^sub>e\<^sub>s) = ?\\<^sub>1" using SCall.prems wtes by(auto simp add:after_def) also have "(?\ # ?\s\<^sub>e\<^sub>s) @ [?\'] = ?\ # ?\s\<^sub>e\<^sub>s @ [?\']" by simp finally show ?case using SCall.prems wtes by(simp add:after_def hyperUn_assoc) next case Seq thus ?case by(auto simp:after_def) (fastforce simp:wt_Push wt_Pop hyperUn_assoc intro:wt_instrs_app2 wt_instrs_Cons) next case (INIT C Cs b e) have "P,E \\<^sub>1 INIT C (Cs,b) \ e :: T" by fact thus ?case using WT\<^sub>1_nsub_RI by simp next case (RI C e' Cs e) have "P,E \\<^sub>1 RI (C,e') ; Cs \ e :: T" by fact thus ?case using WT\<^sub>1_nsub_RI by simp qed (*>*) lemma [simp]: "types (compP f P) = types P" (*<*)by auto(*>*) lemma [simp]: "states (compP f P) mxs mxl = states P mxs mxl" (*<*)by (simp add: JVM_states_unfold)(*>*) lemma [simp]: "app\<^sub>i (i, compP f P, pc, mpc, T, \) = app\<^sub>i (i, P, pc, mpc, T, \)" (*<*)(is "?A = ?B") proof - obtain ST LT where \: "\ = (ST, LT)" by(cases \) simp then show ?thesis proof(cases i) case Invoke show ?thesis proof(rule iffI) assume ?A then show ?B using Invoke \ by auto (fastforce dest!: sees_method_compPD) next assume ?B then show ?A using Invoke \ by auto (force dest: sees_method_compP) qed next case (Invokestatic x111 x112 x113) show ?thesis proof(rule iffI) assume ?A then show ?B using Invokestatic \ by auto (fastforce dest!: sees_method_compPD) next assume ?B then show ?A using Invokestatic \ by auto (force dest: sees_method_compP) qed qed auto qed (*>*) lemma [simp]: "is_relevant_entry (compP f P) i = is_relevant_entry P i" (*<*) proof - { fix pc e have "is_relevant_entry (compP f P) i pc e = is_relevant_entry P i pc e" by(cases i) (auto simp: is_relevant_entry_def) } then show ?thesis by fast qed (*>*) lemma [simp]: "relevant_entries (compP f P) i pc xt = relevant_entries P i pc xt" (*<*) by (simp add: relevant_entries_def)(*>*) lemma [simp]: "app i (compP f P) mpc T pc mxl xt \ = app i P mpc T pc mxl xt \" (*<*) by (simp add: app_def xcpt_app_def eff_def xcpt_eff_def norm_eff_def) (fastforce simp add: image_def) (*>*) lemma [simp]: assumes "app i P mpc T pc mxl xt \" shows "eff i (compP f P) pc xt \ = eff i P pc xt \" (*<*) using assms proof(clarsimp simp: eff_def norm_eff_def xcpt_eff_def app_def, cases i) qed auto (*>*) lemma [simp]: "subtype (compP f P) = subtype P" (*<*)by (rule ext)+ simp(*>*) lemma [simp]: "compP f P \ \ \' \' = P \ \ \' \'" (*<*) by (simp add: sup_state_opt_def sup_state_def sup_ty_opt_def)(*>*) lemma [simp]: "compP f P,T,mpc,mxl,xt \ i,pc :: \s = P,T,mpc,mxl,xt \ i,pc :: \s" (*<*)by (simp add: wt_instr_def cong: conj_cong)(*>*) declare TC1.compT_sizes[simp] TC0.ty_def2[simp] context TC2 begin lemma compT_method_NonStatic: fixes e and A and C and Ts and mxl\<^sub>0 defines [simp]: "E \ Class C # Ts" and [simp]: "A \ \{..size Ts}\" and [simp]: "A' \ A \ \ e" and [simp]: "mxl\<^sub>0 \ max_vars e" assumes mxs: "max_stack e = mxs" and mxl: "Suc (length Ts + max_vars e) = mxl" assumes wf: "wf_prog p P" and wte: "P,E \\<^sub>1 e :: T" and \: "\ e A" and \: "\ e (size E)" and E_P: "set E \ types P" and wid: "P \ T \ T\<^sub>r" shows "wt_method (compP\<^sub>2 P) C NonStatic Ts T\<^sub>r mxs mxl\<^sub>0 (compE\<^sub>2 e @ [Return]) (compxE\<^sub>2 e 0 0) (ty\<^sub>i' [] E A # compT\<^sub>a E A [] e)" (*<*)(is "wt_method ?P C ?b Ts T\<^sub>r mxs mxl\<^sub>0 ?is ?xt ?\s") proof - let ?n = "length E + mxl\<^sub>0" have wt_compE: "P,T\<^sub>r,mxs \ compE\<^sub>2 e, compxE\<^sub>2 e 0 (length []) [::] TC0.ty\<^sub>i' ?n [] E A # TC1.compT P ?n E A [] e @[TC0.after P ?n E A [] e]" using mxs TC2.compT_wt_instrs [OF wte \ \, of "[]" mxs ?n T\<^sub>r] by simp have "OK (ty\<^sub>i' [T] E A') \ states P mxs mxl" using mxs WT\<^sub>1_is_type[OF wf wte E_P] max_stack1[OF wte] OK_ty\<^sub>i'_in_statesI[OF E_P] by simp moreover have "OK ` set (compT E A [] e) \ states P mxs mxl" using mxs mxl wid compT_states(1)[OF wf wte E_P] by simp ultimately have "check_types ?P mxs ?n (map OK ?\s)" using mxl wte E_P by (simp add: compT\<^sub>a_def after_def check_types_def) moreover have "wt_start ?P C ?b Ts mxl\<^sub>0 ?\s" using mxl by (auto simp: wt_start_def ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth nth_Cons split: nat.split) moreover { fix pc assume pc: "pc < size ?is" then have "?P,T\<^sub>r,mxs,size ?is,?xt \ ?is!pc,pc :: ?\s" proof(cases "pc < length (compE\<^sub>2 e)") case True then show ?thesis using mxs wte wt_compE by (clarsimp simp: compT\<^sub>a_def mxl after_def wt_instrs_def) next case False have "length (compE\<^sub>2 e) = pc" using less_antisym[OF False] pc by simp then show ?thesis using mxl wte E_P wid by (clarsimp simp: compT\<^sub>a_def after_def wt_defs xcpt_app_pcs xcpt_eff_pcs ty\<^sub>i'_def) qed } moreover have "0 < size ?is" and "size ?\s = size ?is" using wte by (simp_all add: compT\<^sub>a_def) ultimately show ?thesis by(simp add: wt_method_def) qed (*>*) lemma compT_method_Static: fixes e and A and C and Ts and mxl\<^sub>0 defines [simp]: "E \ Ts" and [simp]: "A \ \{.." and [simp]: "A' \ A \ \ e" and [simp]: "mxl\<^sub>0 \ max_vars e" assumes mxs: "max_stack e = mxs" and mxl: "length Ts + max_vars e = mxl" assumes wf: "wf_prog p P" and wte: "P,E \\<^sub>1 e :: T" and \: "\ e A" and \: "\ e (size E)" and E_P: "set E \ types P" and wid: "P \ T \ T\<^sub>r" shows "wt_method (compP\<^sub>2 P) C Static Ts T\<^sub>r mxs mxl\<^sub>0 (compE\<^sub>2 e @ [Return]) (compxE\<^sub>2 e 0 0) (ty\<^sub>i' [] E A # compT\<^sub>a E A [] e)" (*<*)(is "wt_method ?P C ?b Ts T\<^sub>r mxs mxl\<^sub>0 ?is ?xt ?\s") proof - let ?n = "length E + mxl\<^sub>0" have wt_compE: "P,T\<^sub>r,mxs \ compE\<^sub>2 e, compxE\<^sub>2 e 0 (length []) [::] TC0.ty\<^sub>i' ?n [] E A # TC1.compT P ?n E A [] e @[TC0.after P ?n E A [] e]" using mxs TC2.compT_wt_instrs [OF wte \ \, of "[]" mxs ?n T\<^sub>r] by simp have "OK (ty\<^sub>i' [T] E A') \ states P mxs mxl" using mxs WT\<^sub>1_is_type[OF wf wte E_P] max_stack1[OF wte] OK_ty\<^sub>i'_in_statesI[OF E_P] by simp moreover have "OK ` set (compT E A [] e) \ states P mxs mxl" using mxs mxl wid compT_states(1)[OF wf wte E_P] by simp ultimately have "check_types ?P mxs ?n (map OK ?\s)" using mxl wte E_P by (simp add: compT\<^sub>a_def after_def check_types_def) moreover have "wt_start ?P C ?b Ts mxl\<^sub>0 ?\s" using mxl by (auto simp: wt_start_def ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth nth_Cons split: nat.split) moreover { fix pc assume pc: "pc < size ?is" then have "?P,T\<^sub>r,mxs,size ?is,?xt \ ?is!pc,pc :: ?\s" proof(cases "pc < length (compE\<^sub>2 e)") case True then show ?thesis using mxs wte wt_compE by (clarsimp simp: compT\<^sub>a_def mxl after_def wt_instrs_def) next case False have "length (compE\<^sub>2 e) = pc" using less_antisym[OF False] pc by simp then show ?thesis using mxl wte E_P wid by (clarsimp simp: compT\<^sub>a_def after_def wt_defs xcpt_app_pcs xcpt_eff_pcs ty\<^sub>i'_def) qed } moreover have "0 < size ?is" and "size ?\s = size ?is" using wte by (simp_all add: compT\<^sub>a_def) ultimately show ?thesis by(simp add: wt_method_def) qed (*>*) end definition compTP :: "J\<^sub>1_prog \ ty\<^sub>P" where "compTP P C M = ( let (D,b,Ts,T,e) = method P C M; E = case b of Static \ Ts | NonStatic \ Class C # Ts; A = case b of Static \ \{.. | NonStatic \ \{..size Ts}\; mxl = (case b of Static \ 0 | NonStatic \ 1) + size Ts + max_vars e in (TC0.ty\<^sub>i' mxl [] E A # TC1.compT\<^sub>a P mxl E A [] e))" theorem wt_compP\<^sub>2: assumes wf: "wf_J\<^sub>1_prog P" shows "wf_jvm_prog (compP\<^sub>2 P)" (*<*) proof - let ?\ = "compTP P" and ?f = compMb\<^sub>2 let ?wf\<^sub>2 = "\P C (M, b, Ts, T\<^sub>r, mxs, mxl\<^sub>0, is, xt). wt_method P C b Ts T\<^sub>r mxs mxl\<^sub>0 is xt (?\ C M)" and ?P = "compP ?f P" { fix C M b Ts T m let ?md = "(M,b,Ts,T,m)::expr\<^sub>1 mdecl" assume cM: "P \ C sees M, b : Ts\T = m in C" and wfm: "wf_mdecl wf_J\<^sub>1_mdecl P C ?md" then have Ts_types: "\T'\set Ts. is_type P T'" and T_type: "is_type P T" and wfm\<^sub>1: "wf_J\<^sub>1_mdecl P C ?md" by(simp_all add: wf_mdecl_def) have Ts_P: "set Ts \ types P" using sees_wf_mdecl[OF wf cM] by (clarsimp simp: wf_mdecl_def) then have CTs_P: "is_class P C \ set Ts \ types P" using sees_method_is_class[OF cM] by simp have "?wf\<^sub>2 ?P C (M,b,Ts,T,?f b m)" proof(cases b) case Static then obtain T' where wte: "P,Ts \\<^sub>1 m :: T'" and wid: "P \ T' \ T" and \: "\ m \{.." and \: "\ m (size Ts)" using wfm\<^sub>1 by(auto simp: wf_mdecl_def) show ?thesis using Static cM TC2.compT_method_Static [OF _ _ wf wte \ \ Ts_P wid] by(simp add: compTP_def) next case NonStatic then obtain T' where wte: "P,Class C#Ts \\<^sub>1 m :: T'" and wid: "P \ T' \ T" and \: "\ m \{..size Ts}\" and \: "\ m (Suc (size Ts))" using wfm\<^sub>1 by(auto simp: wf_mdecl_def) have Ts_P: "set Ts \ types P" using sees_wf_mdecl[OF wf cM] by (fastforce simp: wf_mdecl_def intro: sees_method_is_class) show ?thesis using NonStatic cM TC2.compT_method_NonStatic [simplified, OF _ _ wf wte \ \ CTs_P wid] by(simp add: compTP_def) qed then have "wf_mdecl ?wf\<^sub>2 ?P C (M, b, Ts, T, ?f b m)" using Ts_types T_type by(simp add: wf_mdecl_def) } then have "wf_prog ?wf\<^sub>2 (compP ?f P)" by(rule wf_prog_compPI[OF _ wf]) then show ?thesis by (simp add: wf_jvm_prog_def wf_jvm_prog_phi_def) fast qed (*>*) theorem wt_J2JVM: "wf_J_prog P \ wf_jvm_prog (J2JVM P)" (*<*) by(simp only:o_def J2JVM_def) (blast intro:wt_compP\<^sub>2 compP\<^sub>1_pres_wf) end