diff --git a/thys/Jinja/Compiler/TypeComp.thy b/thys/Jinja/Compiler/TypeComp.thy --- a/thys/Jinja/Compiler/TypeComp.thy +++ b/thys/Jinja/Compiler/TypeComp.thy @@ -1,1308 +1,1445 @@ (* Title: Jinja/Compiler/TypeComp.thy Author: Tobias Nipkow Copyright TUM 2003 *) section \Preservation of Well-Typedness\ theory TypeComp imports Compiler "../BV/BVSpec" begin (*<*) declare nth_append[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" -(*<*) -apply (unfold ty_def) -apply(blast intro: the_equality WT\<^sub>1_unique) -done -(*>*) +(*<*)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 (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 {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 (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" | "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]: "compE\<^sub>2 e \ []" (*<*)by(induct e) auto(*>*) lemma (in TC1) compT_sizes[simp]: shows "\E A ST. size(compT E A ST e) = size(compE\<^sub>2 e) - 1" and "\E A ST. size(compTs E A ST es) = size(compEs\<^sub>2 es)" (*<*) -apply(induct e and es rule: compE\<^sub>2.induct compEs\<^sub>2.induct) -apply(auto split:bop.splits nat_diff_split) -done +by(induct e and es rule: compE\<^sub>2.induct compEs\<^sub>2.induct) + (auto split:bop.splits nat_diff_split) (*>*) 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'_env_antimono *) 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: - "\ wf_prog p P; P,E \\<^sub>1 e :: T; set E \ types P; set ST \ types P; - size ST + max_stack e \ mxs \ - \ OK (after E A ST e) \ states P mxs mxl" +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" (*<*) -apply(subgoal_tac "size ST + 1 \ mxs") - apply(simp add: after_def ty\<^sub>i'_def JVM_states_unfold ty\<^sub>l_in_types) - apply(blast intro!:listI WT\<^sub>1_is_type) -using max_stack1[of e] apply simp -done +proof - + have "size ST + 1 \ mxs" using max_stack1[of 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" (*<*) -apply(simp add:ty\<^sub>i'_def JVM_states_unfold ty\<^sub>l_in_types) -apply(blast intro!:listI) -done +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 FAss 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[of e\<^sub>1] by auto 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]) 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}" (*<*) -apply(auto simp:shift_def pcs_def) -apply(rule_tac x = "x-n" in exI) -apply (force split:nat_diff_split) -done +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" (*<*) -apply(induct e and es rule: compxE\<^sub>2.induct compxEs\<^sub>2.induct) -apply(auto simp:shift_def ac_simps) -done +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)" (*<*) - apply (induct xt) - apply (unfold relevant_entries_def shift_def) - apply simp - apply (auto simp add: is_relevant_entry_def) - done +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)" (*<*) -apply(simp add: xcpt_eff_def) -apply(cases \) -apply(auto simp add: shift_def) -done +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 \))" -(*<*) -apply(simp add:eff_def norm_eff_def) -apply(cases "i",auto) -done -(*>*) +(*<*)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: - "\ P,T,m,mpc,xt \ i,pc :: \s; pc < size \s; mpc \ size \s \ - \ P,T,m,mpc + size \s',shift (size \s') xt \ i,pc+size \s' :: \s'@\s" +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" (*<*) -apply(auto simp:wt_instr_def app_def) -prefer 2 apply(fast) -prefer 2 apply(fast) -apply(cases "i",auto) -done +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: - "\ P,T,m,mpc - 1,[] \ i,pc - 1 :: \s; - 0 < pc; 0 < mpc; pc < size \s + 1; mpc \ size \s + 1 \ - \ P,T,m,mpc,[] \ i,pc :: \#\s" +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" (*<*) -apply(drule wt_instr_appL[where \s' = "[\]"]) -apply arith -apply arith -apply (simp split:nat_diff_split_asm) -done +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: - "\ P,T,m,mpc - size \s',[] \ i,pc - size \s' :: \s; - size \s' \ pc; size \s' \ mpc; pc < size \s + size \s'; mpc \ size \s + size \s' \ - \ P,T,m,mpc,[] \ i,pc :: \s'@\s" +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" (*<*) -apply(drule wt_instr_appL[where \s' = \s']) -apply arith -apply arith -apply (simp split:nat_diff_split_asm) -done +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: - "\ \ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@\s\<^sub>2; \ is\<^sub>2,xt\<^sub>2 [::] \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" +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" (*<*) -apply(clarsimp simp:wt_instrs_def) -apply(rule conjI, fastforce) -apply(rule conjI, fastforce) -apply clarsimp -apply(rule conjI, fastforce simp:wt_instr_appRx) -apply clarsimp -apply(erule_tac x = "pc - size is\<^sub>1" in allE)+ -apply(thin_tac "P \ Q" for P Q) -apply(erule impE, arith) -apply(drule_tac \s' = "\s\<^sub>1" in wt_instr_appL) - apply arith - apply simp -apply(fastforce simp add:add.commute intro!: wt_instr_appLx) -done +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]: - "\ \ 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 \ - \ \ is\<^sub>1@is\<^sub>2, xt\<^sub>1@shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\s\<^sub>2" +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" (*<*) -apply(cases \s\<^sub>1 rule:rev_cases) - apply simp -apply(simp add:wt_instrs_app) -done +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]: - "\ \ is,xt [::] \s; P,T\<^sub>r,mxs,mpc,[] \ i,pc :: \s; - pc = size is; mpc = size \s; size is + 1 < size \s \ - \ \ is@[i],xt [::] \s" +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" (*<*) -apply(clarsimp simp add:wt_instrs_def) -apply(rule conjI, fastforce) -apply(fastforce intro!:wt_instr_appLx[where xt = "[]",simplified] - dest!:less_antisym) -done +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]: - "\ \ is,xt [::] \s@[\]; P \ \ \' \' \ \ \ is,xt [::] \s@[\']" +assumes wtis: "\ is,xt [::] \s@[\]" and ss: "P \ \ \' \'" +shows "\ is,xt [::] \s@[\']" (*<*) -apply(clarsimp simp add:wt_instrs_def wt_instr_def) -apply(rule conjI) -apply(fastforce) -apply(clarsimp) -apply(rename_tac pc' tau') -apply(erule allE, erule (1) impE) -apply(clarsimp) -apply(drule (1) bspec) -apply(clarsimp) -apply(subgoal_tac "pc' = size \s") -prefer 2 -apply(clarsimp simp:app_def) -apply(drule (1) bspec) -apply(clarsimp) -apply(auto elim!:sup_state_opt_trans) -done +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: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_Put: "\ P \ C sees F: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_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: 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)(*>*) 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]: - "\ \ is\<^sub>1 @ is\<^sub>2, xt [::] \s\<^sub>1 @ ty\<^sub>i' (Class C # ST) E A # \s\<^sub>2; - \\ \ 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; - size is\<^sub>1 = size \s\<^sub>1; is_class P C; size ST < mxs \ \ - \ 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" -(*<*) -apply(simp add:wt_instrs_def) -apply(rule conjI) - apply(clarsimp) - apply arith -apply clarsimp -apply(erule allE, erule (1) impE) -apply(clarsimp simp add: wt_instr_def app_def eff_def) -apply(rule conjI) - apply (thin_tac "\x\ A \ B. P x" for A B P) - apply (thin_tac "\x\ A \ B. P x" for A B P) - apply (clarsimp simp add: xcpt_app_def relevant_entries_def) - apply (simp add: nth_append is_relevant_entry_def split!: if_splits) - apply (drule_tac x="\s\<^sub>1!pc" in bspec) - apply (blast intro: nth_mem) - apply fastforce -apply (rule conjI) - apply clarsimp - apply (erule disjE, blast) - apply (erule disjE, blast) - apply (clarsimp simp add: xcpt_eff_def relevant_entries_def split: if_split_asm) -apply clarsimp -apply (erule disjE, blast) -apply (erule disjE, blast) -apply (clarsimp simp add: xcpt_eff_def relevant_entries_def split: if_split_asm) -apply (simp add: nth_append is_relevant_entry_def split: if_split_asm) - apply (drule_tac x = "\s\<^sub>1!pc" in bspec) - apply (blast intro: nth_mem) - apply (fastforce simp add: ty\<^sub>i'_def) -done +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 - + let ?is = "is\<^sub>1 @ is\<^sub>2" and ?\s = "\s\<^sub>1 @ ty\<^sub>i' (Class C # ST) E A # \s\<^sub>2" + let ?xte = "(0,size is\<^sub>1 - 1,C,size is\<^sub>1,size ST)" + let ?xt' = "xt @ [?xte]" + 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" - apply (induct n) - apply simp - apply (simp add: drop_Suc) - done +proof(induct n) + case (Suc n) then show ?case by(simp add: drop_Suc) +qed simp lemma drop_mess: - "\Suc (length xs\<^sub>0) \ length xs; drop (length xs - Suc (length xs\<^sub>0)) xs = x # xs\<^sub>0\ - \ drop (length xs - length xs\<^sub>0) xs = xs\<^sub>0" -apply (cases xs) - apply simp -apply (simp add: Suc_diff_le) -apply (case_tac "length list - length xs\<^sub>0") - apply simp -apply (simp add: drop_Cons_Suc) -done +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 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 @ [?\']" 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 e\<^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: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 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 (LAss i e) thus ?case using max_stack1[of e] 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)" let ?if = "IfFalse (int ?n\<^sub>c + 3)" have "\ [?if],[] [::] ?\\<^sub>e # ?\\<^sub>1 # ?\s\<^sub>c @ [?\\<^sub>c, ?\\<^sub>2, ?\\<^sub>1, ?\']" by(simp add: wt_instr_Cons wt_instr_append wt_IfFalse nat_add_distrib split: nat_diff_split) 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" by(simp add: wt_Goto split: nat_diff_split) 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 c] 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 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)@[?\']" 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" by(simp add: wt_IfFalse nat_add_distrib split:nat_diff_split) 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: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 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) 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, \)" -(*<*) - apply (cases \) - apply (cases i) - apply auto - apply (fastforce dest!: sees_method_compPD) - apply (force dest: sees_method_compP) - done +(*<*)(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 + qed auto +qed (*>*) lemma [simp]: "is_relevant_entry (compP f P) i = is_relevant_entry P i" (*<*) - apply (rule ext)+ - apply (unfold is_relevant_entry_def) - apply (cases i) - apply auto - done +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 \" (*<*) - apply (simp add: app_def xcpt_app_def eff_def xcpt_eff_def norm_eff_def) - apply (fastforce simp add: image_def) - done +by (simp add: app_def xcpt_app_def eff_def xcpt_eff_def norm_eff_def) + (fastforce simp add: image_def) (*>*) -lemma [simp]: "app i P mpc T pc mxl xt \ \ eff i (compP f P) pc xt \ = eff i P pc xt \" +lemma [simp]: +assumes "app i P mpc T pc mxl xt \" +shows "eff i (compP f P) pc xt \ = eff i P pc xt \" (*<*) - apply (clarsimp simp add: eff_def norm_eff_def xcpt_eff_def app_def) - apply (cases i) - apply auto - done +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" -(*<*) - apply (rule ext)+ - apply (simp) - done -(*>*) +(*<*)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: 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 assm: "wf_prog p P" "P,E \\<^sub>1 e :: T" "\ e A" "\ e (size E)" - "set E \ types P" "P \ T \ T\<^sub>r" + 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 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)" -(*<*) -using assms apply (simp add: wt_method_def compT\<^sub>a_def after_def mxl) -apply (rule conjI) -apply (simp add: check_types_def OK_ty\<^sub>i'_in_statesI) -apply (rule conjI) -apply (drule (1) WT\<^sub>1_is_type) -apply simp -apply (insert max_stack1 [of e]) -apply (rule OK_ty\<^sub>i'_in_statesI) apply (simp_all add: mxs)[3] -apply (erule compT_states(1)) -apply assumption -apply (simp_all add: mxs mxl)[4] -apply (rule conjI) -apply (auto simp add: wt_start_def ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth - nth_Cons mxl split: nat.split dest: less_antisym)[1] -apply (frule (1) TC2.compT_wt_instrs [of P _ _ _ _ "[]" "max_stack e" "Suc (length Ts + max_vars e)" T\<^sub>r]) -apply simp_all -apply (clarsimp simp: after_def) -apply hypsubst_thin -apply (rule conjI) -apply (clarsimp simp: wt_instrs_def after_def mxl mxs) -apply clarsimp -apply (drule (1) less_antisym) -apply (clarsimp simp: wt_defs xcpt_app_pcs xcpt_eff_pcs ty\<^sub>i'_def) -done +(*<*)(is "wt_method ?P C 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 e] 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 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,Ts,T,e) = method P C M; E = Class C # Ts; A = \{..size Ts}\; mxl = 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: - "wf_J\<^sub>1_prog P \ wf_jvm_prog (compP\<^sub>2 P)" +assumes wf: "wf_J\<^sub>1_prog P" shows "wf_jvm_prog (compP\<^sub>2 P)" (*<*) - apply (simp add: wf_jvm_prog_def wf_jvm_prog_phi_def) - apply(rule_tac x = "compTP P" in exI) - apply (rule wf_prog_compPI) - prefer 2 apply assumption - apply (clarsimp simp add: wf_mdecl_def) - apply (simp add: compTP_def) - apply (rule TC2.compT_method [simplified]) - apply (rule refl) - apply (rule refl) - apply assumption - apply assumption - apply assumption - apply assumption - apply (drule (1) sees_wf_mdecl) - apply (simp add: wf_mdecl_def) - apply (blast intro: sees_method_is_class) - apply assumption - done +proof - + let ?\ = "compTP P" and ?f = compMb\<^sub>2 + let ?wf\<^sub>2 = "\P C (M, Ts, T\<^sub>r, mxs, mxl\<^sub>0, is, xt). + wt_method P C Ts T\<^sub>r mxs mxl\<^sub>0 is xt (?\ C M)" + and ?P = "compP ?f P" + { fix C M Ts T m + assume cM: "P \ C sees M : Ts\T = m in C" + and wfm: "wf_mdecl wf_J\<^sub>1_mdecl P C (M,Ts,T,m)" + 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 (M,Ts,T,m)" + by(simp_all add: wf_mdecl_def) + 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))" + by(auto simp: wf_mdecl_def) + have CTs_P: "is_class P C \ set Ts \ types P" + using sees_wf_mdecl[OF wf cM] sees_method_is_class[OF cM] + by (clarsimp simp: wf_mdecl_def) + + have "?wf\<^sub>2 ?P C (M,Ts,T,?f m)" + using cM TC2.compT_method [simplified, OF _ _ wf wte \ \ CTs_P wid] + by(simp add: compTP_def) + then have "wf_mdecl ?wf\<^sub>2 ?P C (M, Ts, T, ?f 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)" (*<*) -apply(simp only:o_def J2JVM_def) -apply(blast intro:wt_compP\<^sub>2 compP\<^sub>1_pres_wf) -done +by(simp only:o_def J2JVM_def) + (blast intro:wt_compP\<^sub>2 compP\<^sub>1_pres_wf) 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,1471 +1,1619 @@ (* 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" -(*<*) -apply (unfold ty_def) -apply(blast intro: the_equality WT\<^sub>1_unique) -done -(*>*) +(*<*)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)" (*<*) -apply(induct e and es rule: compE\<^sub>2.induct compEs\<^sub>2.induct) -apply(auto split:bop.splits nat_diff_split simp: compE\<^sub>2_not_Nil') -done +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: - "\ wf_prog p P; P,E \\<^sub>1 e :: T; set E \ types P; set ST \ types P; - size ST + max_stack e \ mxs \ - \ OK (after E A ST e) \ states P mxs mxl" +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" (*<*) -apply(subgoal_tac "size ST + 1 \ mxs") - apply(simp add: after_def ty\<^sub>i'_def JVM_states_unfold ty\<^sub>l_in_types) - apply(blast intro!:listI WT\<^sub>1_is_type) -using max_stack1[where e=e] apply fastforce -done +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" (*<*) -apply(simp add:ty\<^sub>i'_def JVM_states_unfold ty\<^sub>l_in_types) -apply(blast intro!:listI) -done +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}" (*<*) -apply(auto simp:shift_def pcs_def) -apply(rule_tac x = "x-n" in exI) -apply (force split:nat_diff_split) -done +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" (*<*) -apply(induct e and es rule: compxE\<^sub>2.induct compxEs\<^sub>2.induct) -apply(auto simp:shift_def ac_simps) -done +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)" (*<*) - apply (induct xt) - apply (unfold relevant_entries_def shift_def) - apply simp - apply (auto simp add: is_relevant_entry_def) - done +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)" (*<*) -apply(simp add: xcpt_eff_def) -apply(cases \) -apply(auto simp add: shift_def) -done +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 \))" -(*<*) -apply(simp add:eff_def norm_eff_def) -apply(cases "i",auto) -done -(*>*) +(*<*)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: - "\ P,T,m,mpc,xt \ i,pc :: \s; pc < size \s; mpc \ size \s \ - \ P,T,m,mpc + size \s',shift (size \s') xt \ i,pc+size \s' :: \s'@\s" +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" (*<*) -apply(auto simp:wt_instr_def app_def) -prefer 2 apply(fast) -prefer 2 apply(fast) -apply(cases "i",auto) -done +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: - "\ P,T,m,mpc - 1,[] \ i,pc - 1 :: \s; - 0 < pc; 0 < mpc; pc < size \s + 1; mpc \ size \s + 1 \ - \ P,T,m,mpc,[] \ i,pc :: \#\s" +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" (*<*) -apply(drule wt_instr_appL[where \s' = "[\]"]) -apply arith -apply arith -apply (simp split:nat_diff_split_asm) -done +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: - "\ P,T,m,mpc - size \s',[] \ i,pc - size \s' :: \s; - size \s' \ pc; size \s' \ mpc; pc < size \s + size \s'; mpc \ size \s + size \s' \ - \ P,T,m,mpc,[] \ i,pc :: \s'@\s" +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" (*<*) -apply(drule wt_instr_appL[where \s' = \s']) -apply arith -apply arith -apply (simp split:nat_diff_split_asm) -done +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: - "\ \ is\<^sub>1,xt\<^sub>1 [::] \s\<^sub>1@\s\<^sub>2; \ is\<^sub>2,xt\<^sub>2 [::] \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" +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" (*<*) -apply(clarsimp simp:wt_instrs_def) -apply(rule conjI, fastforce) -apply(rule conjI, fastforce) -apply clarsimp -apply(rule conjI, fastforce simp:wt_instr_appRx) -apply clarsimp -apply(erule_tac x = "pc - size is\<^sub>1" in allE)+ -apply(thin_tac "P \ Q" for P Q) -apply(erule impE, arith) -apply(drule_tac \s' = "\s\<^sub>1" in wt_instr_appL) - apply arith - apply simp -apply(fastforce simp add:add.commute intro!: wt_instr_appLx) -done +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]: - "\ \ 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 \ - \ \ is\<^sub>1@is\<^sub>2, xt\<^sub>1@shift (size is\<^sub>1) xt\<^sub>2 [::] \s\<^sub>1@\s\<^sub>2" +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" (*<*) -apply(cases \s\<^sub>1 rule:rev_cases) - apply simp -apply(simp add:wt_instrs_app) -done +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]: - "\ \ is,xt [::] \s; P,T\<^sub>r,mxs,mpc,[] \ i,pc :: \s; - pc = size is; mpc = size \s; size is + 1 < size \s \ - \ \ is@[i],xt [::] \s" +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" (*<*) -apply(clarsimp simp add:wt_instrs_def) -apply(rule conjI, fastforce) -apply(fastforce intro!:wt_instr_appLx[where xt = "[]",simplified] - dest!:less_antisym) -done +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]: - "\ \ is,xt [::] \s@[\]; P \ \ \' \' \ \ \ is,xt [::] \s@[\']" +assumes wtis: "\ is,xt [::] \s@[\]" and ss: "P \ \ \' \'" +shows "\ is,xt [::] \s@[\']" (*<*) -apply(clarsimp simp add:wt_instrs_def wt_instr_def) -apply(rule conjI) -apply(fastforce) -apply(clarsimp) -apply(rename_tac pc' tau') -apply(erule allE, erule (1) impE) -apply(clarsimp) -apply(drule (1) bspec) -apply(clarsimp) -apply(subgoal_tac "pc' = size \s") -prefer 2 -apply(clarsimp simp:app_def) -apply(drule (1) bspec) -apply(clarsimp) -apply(auto elim!:sup_state_opt_trans) -done +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]: - "\ \ is\<^sub>1 @ is\<^sub>2, xt [::] \s\<^sub>1 @ ty\<^sub>i' (Class C # ST) E A # \s\<^sub>2; - \\ \ 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; - size is\<^sub>1 = size \s\<^sub>1; is_class P C; size ST < mxs \ \ - \ 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" -(*<*) -apply(simp add:wt_instrs_def) -apply(rule conjI) - apply(clarsimp) - apply arith -apply clarsimp -apply(erule allE, erule (1) impE) -apply(clarsimp simp add: wt_instr_def app_def eff_def) -apply(rule conjI) - apply (thin_tac "\x\ A \ B. P x" for A B P) - apply (thin_tac "\x\ A \ B. P x" for A B P) - apply (clarsimp simp add: xcpt_app_def relevant_entries_def) - apply (simp add: nth_append is_relevant_entry_def split!: if_splits) - apply (drule_tac x="\s\<^sub>1!pc" in bspec) - apply (blast intro: nth_mem) - apply fastforce -apply (rule conjI) - apply clarsimp - apply (erule disjE, blast) - apply (erule disjE, blast) - apply (clarsimp simp add: xcpt_eff_def relevant_entries_def split: if_split_asm) -apply clarsimp -apply (erule disjE, blast) -apply (erule disjE, blast) -apply (clarsimp simp add: xcpt_eff_def relevant_entries_def split: if_split_asm) -apply (simp add: nth_append is_relevant_entry_def split: if_split_asm) - apply (drule_tac x = "\s\<^sub>1!pc" in bspec) - apply (blast intro: nth_mem) - apply (fastforce simp add: ty\<^sub>i'_def) -done +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" - apply (induct n) - apply simp - apply (simp add: drop_Suc) - done +proof(induct n) + case (Suc n) then show ?case by(simp add: drop_Suc) +qed simp lemma drop_mess: - "\Suc (length xs\<^sub>0) \ length xs; drop (length xs - Suc (length xs\<^sub>0)) xs = x # xs\<^sub>0\ - \ drop (length xs - length xs\<^sub>0) xs = xs\<^sub>0" -apply (cases xs) - apply simp -apply (simp add: Suc_diff_le) -apply (case_tac "length list - length xs\<^sub>0") - apply simp -apply (simp add: drop_Cons_Suc) -done +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)" 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) 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) 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 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) 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, \)" -(*<*) - apply (cases \) - apply (cases i) - apply auto -\ \ Invoke \ - apply (fastforce dest!: sees_method_compPD) - apply (force dest: sees_method_compP) -\ \ Invokestatic \ - apply (force dest!: sees_method_compPD) - apply (force dest: sees_method_compP) - done +(*<*)(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" (*<*) - apply (rule ext)+ - apply (unfold is_relevant_entry_def) - apply (cases i) - apply auto - done +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 \" (*<*) - apply (simp add: app_def xcpt_app_def eff_def xcpt_eff_def norm_eff_def) - apply (fastforce simp add: image_def) - done +by (simp add: app_def xcpt_app_def eff_def xcpt_eff_def norm_eff_def) + (fastforce simp add: image_def) (*>*) -lemma [simp]: "app i P mpc T pc mxl xt \ \ eff i (compP f P) pc xt \ = eff i P pc xt \" +lemma [simp]: +assumes "app i P mpc T pc mxl xt \" +shows "eff i (compP f P) pc xt \ = eff i P pc xt \" (*<*) - apply (clarsimp simp add: eff_def norm_eff_def xcpt_eff_def app_def) - apply (cases i) - apply auto - done +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" -(*<*) - apply (rule ext)+ - apply (simp) - done -(*>*) +(*<*)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 assm: "wf_prog p P" "P,E \\<^sub>1 e :: T" "\ e A" "\ e (size E)" - "set E \ types P" "P \ T \ T\<^sub>r" + 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)" -(*<*) -using assms apply (simp add: wt_method_def compT\<^sub>a_def after_def mxl) -apply (rule conjI) - apply (simp add: check_types_def OK_ty\<^sub>i'_in_statesI) - apply (rule conjI) - apply (drule (1) WT\<^sub>1_is_type) - apply simp - apply (insert max_stack1 [where e=e]) - apply (rule OK_ty\<^sub>i'_in_statesI) apply (simp_all add: mxs)[3] - apply (erule compT_states(1)) - apply assumption - apply (simp_all add: mxs mxl)[4] -apply (rule conjI) - apply (auto simp add: wt_start_def ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth - nth_Cons mxl split: nat.split dest: less_antisym)[1] -apply (frule (1) TC2.compT_wt_instrs [of P _ _ _ _ "[]" "max_stack e" "Suc (length Ts + max_vars e)" T\<^sub>r]) - apply simp_all -apply (clarsimp simp: after_def) -apply hypsubst_thin -apply (rule conjI) - apply (clarsimp simp: wt_instrs_def after_def mxl mxs) -apply clarsimp -apply (drule (1) less_antisym) -apply (clarsimp simp: wt_defs xcpt_app_pcs xcpt_eff_pcs ty\<^sub>i'_def) -done +(*<*)(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 assm: "wf_prog p P" "P,E \\<^sub>1 e :: T" "\ e A" "\ e (size E)" - "set E \ types P" "P \ T \ T\<^sub>r" + 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)" -(*<*) -using assms apply (simp add: wt_method_def compT\<^sub>a_def after_def mxl) -apply (rule conjI) - apply (simp add: check_types_def OK_ty\<^sub>i'_in_statesI) - apply (rule conjI) - apply (drule (1) WT\<^sub>1_is_type) - apply simp - apply (insert max_stack1 [where e=e]) - apply (rule OK_ty\<^sub>i'_in_statesI) apply (simp_all add: mxs)[3] - apply (erule compT_states(1)) - apply assumption - apply (simp_all add: mxs mxl)[4] -apply (rule conjI) - apply (auto simp add: wt_start_def ty\<^sub>i'_def ty\<^sub>l_def list_all2_conv_all_nth - nth_Cons mxl split: nat.split dest: less_antisym)[1] -apply (frule (1) TC2.compT_wt_instrs [of P _ _ _ _ "[]" "max_stack e" "length Ts + max_vars e" T\<^sub>r]) - apply simp_all -apply (clarsimp simp: after_def) -apply hypsubst_thin -apply (rule conjI) - apply (clarsimp simp: wt_instrs_def after_def mxl mxs) -apply clarsimp -apply (drule (1) less_antisym) -apply (clarsimp simp: wt_defs xcpt_app_pcs xcpt_eff_pcs ty\<^sub>i'_def) -done +(*<*)(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: - "wf_J\<^sub>1_prog P \ wf_jvm_prog (compP\<^sub>2 P)" +assumes wf: "wf_J\<^sub>1_prog P" shows "wf_jvm_prog (compP\<^sub>2 P)" (*<*) - apply (simp add: wf_jvm_prog_def wf_jvm_prog_phi_def) - apply(rule_tac x = "compTP P" in exI) - apply (rule wf_prog_compPI) - prefer 2 apply assumption - apply (simp add: compTP_def) apply(rename_tac C M b Ts T m) - apply(case_tac b) -\ \ Static \ - apply (clarsimp simp add: wf_mdecl_def) - apply (rule TC2.compT_method_Static [simplified]) - apply (rule refl) - apply (rule refl) - apply assumption - apply assumption - apply assumption - apply assumption - apply (drule (1) sees_wf_mdecl) - apply (simp add: wf_mdecl_def) - apply (blast intro: sees_method_is_class) - apply assumption -\ \ NonStatic \ - apply (clarsimp simp add: wf_mdecl_def) - apply (rule TC2.compT_method_NonStatic [simplified]) - apply (rule refl) - apply (rule refl) - apply assumption - apply assumption - apply assumption - apply assumption - apply (drule (1) sees_wf_mdecl) - apply (simp add: wf_mdecl_def) - apply (blast intro: sees_method_is_class) - apply assumption - done +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)" (*<*) -apply(simp only:o_def J2JVM_def) -apply(blast intro:wt_compP\<^sub>2 compP\<^sub>1_pres_wf) -done +by(simp only:o_def J2JVM_def) + (blast intro:wt_compP\<^sub>2 compP\<^sub>1_pres_wf) end