diff --git a/thys/Jinja/J/DefAss.thy b/thys/Jinja/J/DefAss.thy --- a/thys/Jinja/J/DefAss.thy +++ b/thys/Jinja/J/DefAss.thy @@ -1,194 +1,194 @@ (* Title: Jinja/DefAss.thy Author: Tobias Nipkow Copyright 2003 Technische Universitaet Muenchen *) section \Definite assignment\ theory DefAss imports BigStep begin subsection "Hypersets" type_synonym 'a hyperset = "'a set option" definition hyperUn :: "'a hyperset \ 'a hyperset \ 'a hyperset" (infixl "\" 65) where "A \ B \ case A of None \ None | \A\ \ (case B of None \ None | \B\ \ \A \ B\)" definition hyperInt :: "'a hyperset \ 'a hyperset \ 'a hyperset" (infixl "\" 70) where "A \ B \ case A of None \ B | \A\ \ (case B of None \ \A\ | \B\ \ \A \ B\)" definition hyperDiff1 :: "'a hyperset \ 'a \ 'a hyperset" (infixl "\" 65) where "A \ a \ case A of None \ None | \A\ \ \A - {a}\" definition hyper_isin :: "'a \ 'a hyperset \ bool" (infix "\\" 50) where "a \\ A \ case A of None \ True | \A\ \ a \ A" definition hyper_subset :: "'a hyperset \ 'a hyperset \ bool" (infix "\" 50) where "A \ B \ case B of None \ True | \B\ \ (case A of None \ False | \A\ \ A \ B)" lemmas hyperset_defs = hyperUn_def hyperInt_def hyperDiff1_def hyper_isin_def hyper_subset_def lemma [simp]: "\{}\ \ A = A \ A \ \{}\ = A" (*<*)by(simp add:hyperset_defs)(*>*) lemma [simp]: "\A\ \ \B\ = \A \ B\ \ \A\ \ a = \A - {a}\" (*<*)by(simp add:hyperset_defs)(*>*) lemma [simp]: "None \ A = None \ A \ None = None" (*<*)by(simp add:hyperset_defs)(*>*) lemma [simp]: "a \\ None \ None \ a = None" (*<*)by(simp add:hyperset_defs)(*>*) lemma hyperUn_assoc: "(A \ B) \ C = A \ (B \ C)" (*<*)by(simp add:hyperset_defs Un_assoc)(*>*) lemma hyper_insert_comm: "A \ \{a}\ = \{a}\ \ A \ A \ (\{a}\ \ B) = \{a}\ \ (A \ B)" (*<*)by(simp add:hyperset_defs)(*>*) subsection "Definite assignment" primrec \ :: "'a exp \ 'a hyperset" and \s :: "'a exp list \ 'a hyperset" where "\ (new C) = \{}\" | "\ (Cast C e) = \ e" | "\ (Val v) = \{}\" | "\ (e\<^sub>1 \bop\ e\<^sub>2) = \ e\<^sub>1 \ \ e\<^sub>2" | "\ (Var V) = \{}\" | "\ (LAss V e) = \{V}\ \ \ e" | "\ (e\F{D}) = \ e" | "\ (e\<^sub>1\F{D}:=e\<^sub>2) = \ e\<^sub>1 \ \ e\<^sub>2" | "\ (e\M(es)) = \ e \ \s es" | "\ ({V:T; e}) = \ e \ V" | "\ (e\<^sub>1;;e\<^sub>2) = \ e\<^sub>1 \ \ e\<^sub>2" | "\ (if (e) e\<^sub>1 else e\<^sub>2) = \ e \ (\ e\<^sub>1 \ \ e\<^sub>2)" | "\ (while (b) e) = \ b" | "\ (throw e) = None" | "\ (try e\<^sub>1 catch(C V) e\<^sub>2) = \ e\<^sub>1 \ (\ e\<^sub>2 \ V)" | "\s ([]) = \{}\" | "\s (e#es) = \ e \ \s es" primrec \ :: "'a exp \ 'a hyperset \ bool" and \s :: "'a exp list \ 'a hyperset \ bool" where "\ (new C) A = True" | "\ (Cast C e) A = \ e A" | "\ (Val v) A = True" | "\ (e\<^sub>1 \bop\ e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \ e\<^sub>1))" | "\ (Var V) A = (V \\ A)" | "\ (LAss V e) A = \ e A" | "\ (e\F{D}) A = \ e A" | "\ (e\<^sub>1\F{D}:=e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \ e\<^sub>1))" | "\ (e\M(es)) A = (\ e A \ \s es (A \ \ e))" | "\ ({V:T; e}) A = \ e (A \ V)" | "\ (e\<^sub>1;;e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \ e\<^sub>1))" | "\ (if (e) e\<^sub>1 else e\<^sub>2) A = (\ e A \ \ e\<^sub>1 (A \ \ e) \ \ e\<^sub>2 (A \ \ e))" | "\ (while (e) c) A = (\ e A \ \ c (A \ \ e))" | "\ (throw e) A = \ e A" | "\ (try e\<^sub>1 catch(C V) e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \{V}\))" | "\s ([]) A = True" | "\s (e#es) A = (\ e A \ \s es (A \ \ e))" lemma As_map_Val[simp]: "\s (map Val vs) = \{}\" (*<*)by (induct vs) simp_all(*>*) lemma D_append[iff]: "\A. \s (es @ es') A = (\s es A \ \s es' (A \ \s es))" (*<*)by (induct es type:list) (auto simp:hyperUn_assoc)(*>*) lemma A_fv: "\A. \ e = \A\ \ A \ fv e" and "\A. \s es = \A\ \ A \ fvs es" (*<*) -apply(induct e and es rule: \.induct \s.induct) -apply (simp_all add:hyperset_defs) -apply blast+ -done +by (induct e and es rule: \.induct \s.induct) + (fastforce simp add:hyperset_defs)+ (*>*) lemma sqUn_lem: "A \ A' \ A \ B \ A' \ B" (*<*)by(simp add:hyperset_defs) blast(*>*) lemma diff_lem: "A \ A' \ A \ b \ A' \ b" (*<*)by(simp add:hyperset_defs) blast(*>*) (* This order of the premises avoids looping of the simplifier *) lemma D_mono: "\A A'. A \ A' \ \ e A \ \ (e::'a exp) A'" and Ds_mono: "\A A'. A \ A' \ \s es A \ \s (es::'a exp list) A'" (*<*) -apply(induct e and es rule: \.induct \s.induct) -apply simp -apply simp -apply simp -apply simp apply (iprover dest:sqUn_lem) -apply (fastforce simp add:hyperset_defs) -apply simp -apply simp -apply simp apply (iprover dest:sqUn_lem) -apply simp apply (iprover dest:sqUn_lem) -apply simp apply (iprover dest:diff_lem) -apply simp apply (iprover dest:sqUn_lem) -apply simp apply (iprover dest:sqUn_lem) -apply simp apply (iprover dest:sqUn_lem) -apply simp -apply simp apply (iprover dest:sqUn_lem) -apply simp -apply simp apply (iprover dest:sqUn_lem) -done +proof(induct e and es rule: \.induct \s.induct) + case BinOp then show ?case by simp (iprover dest:sqUn_lem) +next + case Var then show ?case by (fastforce simp add:hyperset_defs) +next + case FAss then show ?case by simp (iprover dest:sqUn_lem) +next + case Call then show ?case by simp (iprover dest:sqUn_lem) +next + case Block then show ?case by simp (iprover dest:diff_lem) +next + case Seq then show ?case by simp (iprover dest:sqUn_lem) +next + case Cond then show ?case by simp (iprover dest:sqUn_lem) +next + case While then show ?case by simp (iprover dest:sqUn_lem) +next + case TryCatch then show ?case by simp (iprover dest:sqUn_lem) +next + case Cons_exp then show ?case by simp (iprover dest:sqUn_lem) +qed simp_all (*>*) (* And this is the order of premises preferred during application: *) lemma D_mono': "\ e A \ A \ A' \ \ e A'" and Ds_mono': "\s es A \ A \ A' \ \s es A'" (*<*)by(blast intro:D_mono, blast intro:Ds_mono)(*>*) (* text{* @{term"\"} is sound w.r.t.\ the big step semantics: it computes a conservative approximation of the variables actually assigned to. *} lemma "P \ \e,(h\<^sub>0,l\<^sub>0)\ \ \e',(h\<^sub>1,l\<^sub>1)\ \ (!!A. \ e = \A\ \ A \ dom l\<^sub>1)" and "P \ \es,(h\<^sub>0,l\<^sub>0)\ [\] \es',(h\<^sub>1,l\<^sub>1)\ \ (!!A. \s es = \A\ \ A \ dom l\<^sub>1)" proof (induct rule:eval_evals_induct) case LAss thus ?case apply(simp add:dom_def hyperset_defs) apply blast apply blast next case FAss thus ?case by simp (blast dest:eval_lcl_incr) next case BinOp thus ?case by simp (blast dest:eval_lcl_incr) next case Call thus ?case by simp (blast dest:evals_lcl_incr) next case Cons thus ?case by simp (blast dest:evals_lcl_incr) next case Block thus ?case by(simp del: fun_upd_apply) blast next case Seq thus ?case by simp (blast dest:eval_lcl_incr) next case CondT thus ?case by simp (blast dest:eval_lcl_incr) next case CondF thus ?case by simp (blast dest:eval_lcl_incr) next case Try thus ?case by(fastforce dest!: eval_lcl_incr) next case TryCatch thus ?case by(fastforce dest!: eval_lcl_incr) qed auto *) end diff --git a/thys/Jinja/J/JWellForm.thy b/thys/Jinja/J/JWellForm.thy --- a/thys/Jinja/J/JWellForm.thy +++ b/thys/Jinja/J/JWellForm.thy @@ -1,64 +1,53 @@ (* Title: Jinja/J/JWellForm.thy Author: Tobias Nipkow Copyright 2003 Technische Universitaet Muenchen *) section \Well-formedness Constraints\ theory JWellForm imports "../Common/WellForm" WWellForm WellType DefAss begin definition wf_J_mdecl :: "J_prog \ cname \ J_mb mdecl \ bool" where "wf_J_mdecl P C \ \(M,Ts,T,(pns,body)). length Ts = length pns \ distinct pns \ this \ set pns \ (\T'. P,[this\Class C,pns[\]Ts] \ body :: T' \ P \ T' \ T) \ \ body \{this} \ set pns\" lemma wf_J_mdecl[simp]: "wf_J_mdecl P C (M,Ts,T,pns,body) \ (length Ts = length pns \ distinct pns \ this \ set pns \ (\T'. P,[this\Class C,pns[\]Ts] \ body :: T' \ P \ T' \ T) \ \ body \{this} \ set pns\)" (*<*)by(simp add:wf_J_mdecl_def)(*>*) abbreviation wf_J_prog :: "J_prog \ bool" where "wf_J_prog == wf_prog wf_J_mdecl" lemma wf_J_prog_wf_J_mdecl: "\ wf_J_prog P; (C, D, fds, mths) \ set P; jmdcl \ set mths \ \ wf_J_mdecl P C jmdcl" -(*<*) -apply (simp add: wf_prog_def) -apply (simp add: wf_cdecl_def) -apply (erule conjE)+ -apply (drule bspec, assumption) -apply simp -apply (erule conjE)+ -apply (drule bspec, assumption) -apply (simp add: wf_mdecl_def split_beta) -done -(*>*) +(*<*)by(fastforce simp: wf_prog_def wf_cdecl_def wf_mdecl_def)(*>*) lemma wf_mdecl_wwf_mdecl: "wf_J_mdecl P C Md \ wwf_J_mdecl P C Md" (*<*)by(fastforce simp:wwf_J_mdecl_def dest!:WT_fv)(*>*) lemma wf_prog_wwf_prog: "wf_J_prog P \ wwf_J_prog P" (*<*) -apply(simp add:wf_prog_def wf_cdecl_def wf_mdecl_def) -apply(fast intro:wf_mdecl_wwf_mdecl) -done +by (simp add:wf_prog_def wf_cdecl_def wf_mdecl_def) + (fast intro:wf_mdecl_wwf_mdecl) (*>*) end diff --git a/thys/Jinja/J/Progress.thy b/thys/Jinja/J/Progress.thy --- a/thys/Jinja/J/Progress.thy +++ b/thys/Jinja/J/Progress.thy @@ -1,626 +1,619 @@ (* Title: Jinja/J/SmallProgress.thy Author: Tobias Nipkow Copyright 2003 Technische Universitaet Muenchen *) section \Progress of Small Step Semantics\ theory Progress imports Equivalence WellTypeRT DefAss "../Common/Conform" begin lemma final_addrE: "\ P,E,h \ e : Class C; final e; \a. e = addr a \ R; \a. e = Throw a \ R \ \ R" (*<*)by(auto simp:final_def)(*>*) lemma finalRefE: "\ P,E,h \ e : T; is_refT T; final e; e = null \ R; \a C. \ e = addr a; T = Class C \ \ R; \a. e = Throw a \ R \ \ R" (*<*)by(auto simp:final_def is_refT_def)(*>*) text\Derivation of new induction scheme for well typing:\ inductive WTrt' :: "[J_prog,heap,env,expr,ty] \ bool" and WTrts' :: "[J_prog,heap,env,expr list, ty list] \ bool" and WTrt2' :: "[J_prog,env,heap,expr,ty] \ bool" ("_,_,_ \ _ :'' _" [51,51,51]50) and WTrts2' :: "[J_prog,env,heap,expr list, ty list] \ bool" ("_,_,_ \ _ [:''] _" [51,51,51]50) for P :: J_prog and h :: heap where "P,E,h \ e :' T \ WTrt' P h E e T" | "P,E,h \ es [:'] Ts \ WTrts' P h E es Ts" | "is_class P C \ P,E,h \ new C :' Class C" | "\ P,E,h \ e :' T; is_refT T; is_class P C \ \ P,E,h \ Cast C e :' Class C" | "typeof\<^bsub>h\<^esub> v = Some T \ P,E,h \ Val v :' T" | "E v = Some T \ P,E,h \ Var v :' T" | "\ P,E,h \ e\<^sub>1 :' T\<^sub>1; P,E,h \ e\<^sub>2 :' T\<^sub>2 \ \ P,E,h \ e\<^sub>1 \Eq\ e\<^sub>2 :' Boolean" | "\ P,E,h \ e\<^sub>1 :' Integer; P,E,h \ e\<^sub>2 :' Integer \ \ P,E,h \ e\<^sub>1 \Add\ e\<^sub>2 :' Integer" | "\ P,E,h \ Var V :' T; P,E,h \ e :' T'; P \ T' \ T \<^cancel>\V \ This\ \ \ P,E,h \ V:=e :' Void" | "\ P,E,h \ e :' Class C; P \ C has F:T in D \ \ P,E,h \ e\F{D} :' T" | "P,E,h \ e :' NT \ P,E,h \ e\F{D} :' T" | "\ P,E,h \ e\<^sub>1 :' Class C; P \ C has F:T in D; P,E,h \ e\<^sub>2 :' T\<^sub>2; P \ T\<^sub>2 \ T \ \ P,E,h \ e\<^sub>1\F{D}:=e\<^sub>2 :' Void" | "\ P,E,h \ e\<^sub>1:'NT; P,E,h \ e\<^sub>2 :' T\<^sub>2 \ \ P,E,h \ e\<^sub>1\F{D}:=e\<^sub>2 :' Void" | "\ P,E,h \ e :' Class C; P \ C sees M:Ts \ T = (pns,body) in D; P,E,h \ es [:'] Ts'; P \ Ts' [\] Ts \ \ P,E,h \ e\M(es) :' T" | "\ P,E,h \ e :' NT; P,E,h \ es [:'] Ts \ \ P,E,h \ e\M(es) :' T" | "P,E,h \ [] [:'] []" | "\ P,E,h \ e :' T; P,E,h \ es [:'] Ts \ \ P,E,h \ e#es [:'] T#Ts" | "\ typeof\<^bsub>h\<^esub> v = Some T\<^sub>1; P \ T\<^sub>1 \ T; P,E(V\T),h \ e\<^sub>2 :' T\<^sub>2 \ \ P,E,h \ {V:T := Val v; e\<^sub>2} :' T\<^sub>2" | "\ P,E(V\T),h \ e :' T'; \ assigned V e \ \ P,E,h \ {V:T; e} :' T'" | "\ P,E,h \ e\<^sub>1:' T\<^sub>1; P,E,h \ e\<^sub>2:'T\<^sub>2 \ \ P,E,h \ e\<^sub>1;;e\<^sub>2 :' T\<^sub>2" | "\ P,E,h \ e :' Boolean; P,E,h \ e\<^sub>1:' T\<^sub>1; P,E,h \ e\<^sub>2:' T\<^sub>2; P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1; P \ T\<^sub>1 \ T\<^sub>2 \ T = T\<^sub>2; P \ T\<^sub>2 \ T\<^sub>1 \ T = T\<^sub>1 \ \ P,E,h \ if (e) e\<^sub>1 else e\<^sub>2 :' T" (* "\ P,E,h \ e :' Boolean; P,E,h \ e\<^sub>1:' T\<^sub>1; P,E,h \ e\<^sub>2:' T\<^sub>2; P \ T\<^sub>1 \ T\<^sub>2 \ \ P,E,h \ if (e) e\<^sub>1 else e\<^sub>2 :' T\<^sub>2" "\ P,E,h \ e :' Boolean; P,E,h \ e\<^sub>1:' T\<^sub>1; P,E,h \ e\<^sub>2:' T\<^sub>2; P \ T\<^sub>2 \ T\<^sub>1 \ \ P,E,h \ if (e) e\<^sub>1 else e\<^sub>2 :' T\<^sub>1" *) | "\ P,E,h \ e :' Boolean; P,E,h \ c:' T \ \ P,E,h \ while(e) c :' Void" | "\ P,E,h \ e :' T\<^sub>r; is_refT T\<^sub>r \ \ P,E,h \ throw e :' T" | "\ P,E,h \ e\<^sub>1 :' T\<^sub>1; P,E(V \ Class C),h \ e\<^sub>2 :' T\<^sub>2; P \ T\<^sub>1 \ T\<^sub>2 \ \ P,E,h \ try e\<^sub>1 catch(C V) e\<^sub>2 :' T\<^sub>2" (*<*) lemmas WTrt'_induct = WTrt'_WTrts'.induct [split_format (complete)] and WTrt'_inducts = WTrt'_WTrts'.inducts [split_format (complete)] inductive_cases WTrt'_elim_cases[elim!]: "P,E,h \ V :=e :' T" (*>*) lemma [iff]: "P,E,h \ e\<^sub>1;;e\<^sub>2 :' T\<^sub>2 = (\T\<^sub>1. P,E,h \ e\<^sub>1:' T\<^sub>1 \ P,E,h \ e\<^sub>2:' T\<^sub>2)" -(*<*) -apply(rule iffI) -apply (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros) -done -(*>*) +(*<*)by(rule iffI) (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros)(*>*) lemma [iff]: "P,E,h \ Val v :' T = (typeof\<^bsub>h\<^esub> v = Some T)" -(*<*) -apply(rule iffI) -apply (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros) -done -(*>*) +(*<*)by(rule iffI) (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros)(*>*) lemma [iff]: "P,E,h \ Var v :' T = (E v = Some T)" -(*<*) -apply(rule iffI) -apply (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros) -done -(*>*) +(*<*)by(rule iffI) (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros)(*>*) lemma wt_wt': "P,E,h \ e : T \ P,E,h \ e :' T" and wts_wts': "P,E,h \ es [:] Ts \ P,E,h \ es [:'] Ts" (*<*) -apply (induct rule:WTrt_inducts) -prefer 14 -apply(case_tac "assigned V e") -apply(clarsimp simp add:fun_upd_same assigned_def simp del:fun_upd_apply) -apply(erule (2) WTrt'_WTrts'.intros) -apply(erule (1) WTrt'_WTrts'.intros) -apply(blast intro:WTrt'_WTrts'.intros)+ -done +proof(induct rule:WTrt_inducts) + case (WTrtBlock E V T e T') + then show ?case + proof(cases "assigned V e") + case True then show ?thesis using WTrtBlock.hyps(2) + by(clarsimp simp add:fun_upd_same assigned_def WTrt'_WTrts'.intros + simp del:fun_upd_apply) + next + case False then show ?thesis + by (simp add: WTrtBlock.hyps(2) WTrt'_WTrts'.intros) + qed +qed (blast intro:WTrt'_WTrts'.intros)+ (*>*) lemma wt'_wt: "P,E,h \ e :' T \ P,E,h \ e : T" and wts'_wts: "P,E,h \ es [:'] Ts \ P,E,h \ es [:] Ts" (*<*) -apply (induct rule:WTrt'_inducts) -prefer 16 -apply(rule WTrt_WTrts.intros) -apply(rule WTrt_WTrts.intros) -apply(rule WTrt_WTrts.intros) -apply simp -apply(erule (2) WTrt_WTrts.intros) -apply(blast intro:WTrt_WTrts.intros)+ -done +proof(induct rule:WTrt'_inducts) + case Block: (16 v T\<^sub>1 T E V e\<^sub>2 T\<^sub>2) + let ?E = "E(V \ T)" + have "P,?E,h \ Val v : T\<^sub>1" using Block.hyps(1) by simp + moreover have "P \ T\<^sub>1 \ T" by(rule Block.hyps(2)) + ultimately have "P,?E,h \ V:=Val v : Void" using WTrtLAss by simp + moreover have "P,?E,h \ e\<^sub>2 : T\<^sub>2" by(rule Block.hyps(4)) + ultimately have "P,?E,h \ V:=Val v;; e\<^sub>2 : T\<^sub>2" by blast + then show ?case by simp +qed (blast intro:WTrt_WTrts.intros)+ (*>*) corollary wt'_iff_wt: "(P,E,h \ e :' T) = (P,E,h \ e : T)" (*<*)by(blast intro:wt_wt' wt'_wt)(*>*) corollary wts'_iff_wts: "(P,E,h \ es [:'] Ts) = (P,E,h \ es [:] Ts)" (*<*)by(blast intro:wts_wts' wts'_wts)(*>*) (*<*) lemmas WTrt_inducts2 = WTrt'_inducts [unfolded wt'_iff_wt wts'_iff_wts, case_names WTrtNew WTrtCast WTrtVal WTrtVar WTrtBinOpEq WTrtBinOpAdd WTrtLAss WTrtFAcc WTrtFAccNT WTrtFAss WTrtFAssNT WTrtCall WTrtCallNT WTrtNil WTrtCons WTrtInitBlock WTrtBlock WTrtSeq WTrtCond WTrtWhile WTrtThrow WTrtTry, consumes 1] (*>*) theorem assumes wf: "wwf_J_prog P" and hconf: "P \ h \" shows progress: "P,E,h \ e : T \ (\l. \ \ e \dom l\; \ final e \ \ \e' s'. P \ \e,(h,l)\ \ \e',s'\)" and "P,E,h \ es [:] Ts \ (\l. \ \s es \dom l\; \ finals es \ \ \es' s'. P \ \es,(h,l)\ [\] \es',s'\)" (*<*) proof (induct rule:WTrt_inducts2) case WTrtNew show ?case proof cases assume "\a. h a = None" with assms WTrtNew show ?thesis by (fastforce del:exE intro!:RedNew simp add:new_Addr_def elim!:wf_Fields_Ex[THEN exE]) next assume "\(\a. h a = None)" with assms WTrtNew show ?thesis by(fastforce intro:RedNewFail simp add:new_Addr_def) qed next case (WTrtCast E e T C) have wte: "P,E,h \ e : T" and ref: "is_refT T" and IH: "\l. \\ e \dom l\; \ final e\ \ \e' s'. P \ \e,(h,l)\ \ \e',s'\" and D: "\ (Cast C e) \dom l\" by fact+ from D have De: "\ e \dom l\" by auto show ?case proof cases assume "final e" with wte ref show ?thesis proof (rule finalRefE) assume "e = null" thus ?case by(fastforce intro:RedCastNull) next fix D a assume A: "T = Class D" "e = addr a" show ?thesis proof cases assume "P \ D \\<^sup>* C" thus ?thesis using A wte by(fastforce intro:RedCast) next assume "\ P \ D \\<^sup>* C" thus ?thesis using A wte by(force intro!:RedCastFail) qed next fix a assume "e = Throw a" thus ?thesis by(blast intro!:red_reds.CastThrow) qed next assume nf: "\ final e" from IH[OF De nf] show ?thesis by (blast intro:CastRed) qed next case WTrtVal thus ?case by(simp add:final_def) next case WTrtVar thus ?case by(fastforce intro:RedVar simp:hyper_isin_def) next case (WTrtBinOpEq E e1 T1 e2 T2) show ?case proof cases assume "final e1" thus ?thesis proof (rule finalE) fix v1 assume [simp]: "e1 = Val v1" show ?thesis proof cases assume "final e2" thus ?thesis proof (rule finalE) fix v2 assume "e2 = Val v2" thus ?thesis using WTrtBinOpEq by(fastforce intro:RedBinOp) next fix a assume "e2 = Throw a" thus ?thesis by(auto intro:red_reds.BinOpThrow2) qed next assume "\ final e2" with WTrtBinOpEq show ?thesis by simp (fast intro!:BinOpRed2) qed next fix a assume "e1 = Throw a" thus ?thesis by simp (fast intro:red_reds.BinOpThrow1) qed next assume "\ final e1" with WTrtBinOpEq show ?thesis by simp (fast intro:BinOpRed1) qed next case (WTrtBinOpAdd E e1 e2) show ?case proof cases assume "final e1" thus ?thesis proof (rule finalE) fix v1 assume [simp]: "e1 = Val v1" show ?thesis proof cases assume "final e2" thus ?thesis proof (rule finalE) fix v2 assume "e2 = Val v2" thus ?thesis using WTrtBinOpAdd by(fastforce intro:RedBinOp) next fix a assume "e2 = Throw a" thus ?thesis by(auto intro:red_reds.BinOpThrow2) qed next assume "\ final e2" with WTrtBinOpAdd show ?thesis by simp (fast intro!:BinOpRed2) qed next fix a assume "e1 = Throw a" thus ?thesis by simp (fast intro:red_reds.BinOpThrow1) qed next assume "\ final e1" with WTrtBinOpAdd show ?thesis by simp (fast intro:BinOpRed1) qed next case (WTrtLAss E V T e T') show ?case proof cases assume "final e" with WTrtLAss show ?thesis by(auto simp:final_def intro!:RedLAss red_reds.LAssThrow) next assume "\ final e" with WTrtLAss show ?thesis by simp (fast intro:LAssRed) qed next case (WTrtFAcc E e C F T D) have wte: "P,E,h \ e : Class C" and field: "P \ C has F:T in D" by fact+ show ?case proof cases assume "final e" with wte show ?thesis proof (rule final_addrE) fix a assume e: "e = addr a" with wte obtain fs where hp: "h a = Some(C,fs)" by auto with hconf have "P,h \ (C,fs) \" using hconf_def by fastforce then obtain v where "fs(F,D) = Some v" using field by(fastforce dest:has_fields_fun simp:oconf_def has_field_def) with hp e show ?thesis by(fastforce intro:RedFAcc) next fix a assume "e = Throw a" thus ?thesis by(fastforce intro:red_reds.FAccThrow) qed next assume "\ final e" with WTrtFAcc show ?thesis by(fastforce intro!:FAccRed) qed next case (WTrtFAccNT E e F D T) show ?case proof cases assume "final e" \ \@{term e} is @{term null} or @{term throw}\ with WTrtFAccNT show ?thesis by(fastforce simp:final_def intro: RedFAccNull red_reds.FAccThrow) next assume "\ final e" \ \@{term e} reduces by IH\ with WTrtFAccNT show ?thesis by simp (fast intro:FAccRed) qed next case (WTrtFAss E e1 C F T D e2 T2) have wte1: "P,E,h \ e1 : Class C" by fact show ?case proof cases assume "final e1" with wte1 show ?thesis proof (rule final_addrE) fix a assume e1: "e1 = addr a" show ?thesis proof cases assume "final e2" thus ?thesis proof (rule finalE) fix v assume "e2 = Val v" thus ?thesis using e1 wte1 by(fastforce intro:RedFAss) next fix a assume "e2 = Throw a" thus ?thesis using e1 by(fastforce intro:red_reds.FAssThrow2) qed next assume "\ final e2" with WTrtFAss e1 show ?thesis by simp (fast intro!:FAssRed2) qed next fix a assume "e1 = Throw a" thus ?thesis by(fastforce intro:red_reds.FAssThrow1) qed next assume "\ final e1" with WTrtFAss show ?thesis by simp (blast intro!:FAssRed1) qed next case (WTrtFAssNT E e\<^sub>1 e\<^sub>2 T\<^sub>2 F D) show ?case proof cases assume e1: "final e\<^sub>1" \ \@{term e\<^sub>1} is @{term null} or @{term throw}\ show ?thesis proof cases assume "final e\<^sub>2" \ \@{term e\<^sub>2} is @{term Val} or @{term throw}\ with WTrtFAssNT e1 show ?thesis by(fastforce simp:final_def intro: RedFAssNull red_reds.FAssThrow1 red_reds.FAssThrow2) next assume "\ final e\<^sub>2" \ \@{term e\<^sub>2} reduces by IH\ with WTrtFAssNT e1 show ?thesis by (fastforce simp:final_def intro!:red_reds.FAssRed2 red_reds.FAssThrow1) qed next assume "\ final e\<^sub>1" \ \@{term e\<^sub>1} reduces by IH\ with WTrtFAssNT show ?thesis by (fastforce intro:FAssRed1) qed next case (WTrtCall E e C M Ts T pns body D es Ts') have wte: "P,E,h \ e : Class C" and "method": "P \ C sees M:Ts\T = (pns,body) in D" and wtes: "P,E,h \ es [:] Ts'"and sub: "P \ Ts' [\] Ts" and IHes: "\l. \\s es \dom l\; \ finals es\ \ \es' s'. P \ \es,(h,l)\ [\] \es',s'\" and D: "\ (e\M(es)) \dom l\" by fact+ show ?case proof cases assume "final e" with wte show ?thesis proof (rule final_addrE) fix a assume e_addr: "e = addr a" show ?thesis proof cases assume es: "\vs. es = map Val vs" from wte e_addr obtain fs where ha: "h a = Some(C,fs)" by auto show ?thesis using e_addr ha "method" WTrts_same_length[OF wtes] sub es sees_wf_mdecl[OF wf "method"] by (fastforce intro!: RedCall simp:list_all2_iff wf_mdecl_def) next assume "\(\vs. es = map Val vs)" hence not_all_Val: "\(\e \ set es. \v. e = Val v)" by(simp add:ex_map_conv) let ?ves = "takeWhile (\e. \v. e = Val v) es" let ?rest = "dropWhile (\e. \v. e = Val v) es" let ?ex = "hd ?rest" let ?rst = "tl ?rest" from not_all_Val have nonempty: "?rest \ []" by auto hence es: "es = ?ves @ ?ex # ?rst" by simp have "\e \ set ?ves. \v. e = Val v" by(fastforce dest:set_takeWhileD) then obtain vs where ves: "?ves = map Val vs" using ex_map_conv by blast show ?thesis proof cases assume "final ?ex" moreover from nonempty have "\(\v. ?ex = Val v)" by(auto simp:neq_Nil_conv simp del:dropWhile_eq_Nil_conv) (simp add:dropWhile_eq_Cons_conv) ultimately obtain b where ex_Throw: "?ex = Throw b" by(fast elim!:finalE) show ?thesis using e_addr es ex_Throw ves by(fastforce intro:CallThrowParams) next assume not_fin: "\ final ?ex" have "finals es = finals(?ves @ ?ex # ?rst)" using es by(rule arg_cong) also have "\ = finals(?ex # ?rst)" using ves by simp finally have "finals es = finals(?ex # ?rst)" . hence "\ finals es" using not_finals_ConsI[OF not_fin] by blast thus ?thesis using e_addr D IHes by(fastforce intro!:CallParams) qed qed next fix a assume "e = Throw a" with WTrtCall.prems show ?thesis by(fast intro!:CallThrowObj) qed next assume "\ final e" with WTrtCall show ?thesis by simp (blast intro!:CallObj) qed next case (WTrtCallNT E e es Ts M T) show ?case proof cases assume "final e" moreover { fix v assume e: "e = Val v" hence "e = null" using WTrtCallNT by simp have ?case proof cases assume "finals es" moreover { fix vs assume "es = map Val vs" with WTrtCallNT e have ?thesis by(fastforce intro: RedCallNull) } moreover { fix vs a es' assume "es = map Val vs @ Throw a # es'" with WTrtCallNT e have ?thesis by(fastforce intro: CallThrowParams) } ultimately show ?thesis by(fastforce simp:finals_def) next assume "\ finals es" \ \@{term es} reduces by IH\ with WTrtCallNT e show ?thesis by(fastforce intro: CallParams) qed } moreover { fix a assume "e = Throw a" with WTrtCallNT have ?case by(fastforce intro: CallThrowObj) } ultimately show ?thesis by(fastforce simp:final_def) next assume "\ final e" \ \@{term e} reduces by IH\ with WTrtCallNT show ?thesis by (fastforce intro:CallObj) qed next case WTrtNil thus ?case by simp next case (WTrtCons E e T es Ts) have IHe: "\l. \\ e \dom l\; \ final e\ \ \e' s'. P \ \e,(h,l)\ \ \e',s'\" and IHes: "\l. \\s es \dom l\; \ finals es\ \ \es' s'. P \ \es,(h,l)\ [\] \es',s'\" and D: "\s (e#es) \dom l\" and not_fins: "\ finals(e # es)" by fact+ have De: "\ e \dom l\" and Des: "\s es (\dom l\ \ \ e)" using D by auto show ?case proof cases assume "final e" thus ?thesis proof (rule finalE) fix v assume e: "e = Val v" hence Des': "\s es \dom l\" using De Des by auto have not_fins_tl: "\ finals es" using not_fins e by simp show ?thesis using e IHes[OF Des' not_fins_tl] by (blast intro!:ListRed2) next fix a assume "e = Throw a" hence False using not_fins by simp thus ?thesis .. qed next assume "\ final e" with IHe[OF De] show ?thesis by(fast intro!:ListRed1) qed next case (WTrtInitBlock v T\<^sub>1 T E V e\<^sub>2 T\<^sub>2) have IH2: "\l. \\ e\<^sub>2 \dom l\; \ final e\<^sub>2\ \ \e' s'. P \ \e\<^sub>2,(h,l)\ \ \e',s'\" and D: "\ {V:T := Val v; e\<^sub>2} \dom l\" by fact+ show ?case proof cases assume "final e\<^sub>2" then show ?thesis proof (rule finalE) fix v\<^sub>2 assume "e\<^sub>2 = Val v\<^sub>2" thus ?thesis by(fast intro:RedInitBlock) next fix a assume "e\<^sub>2 = Throw a" thus ?thesis by(fast intro:red_reds.InitBlockThrow) qed next assume not_fin2: "\ final e\<^sub>2" from D have D2: "\ e\<^sub>2 \dom(l(V\v))\" by (auto simp:hyperset_defs) from IH2[OF D2 not_fin2] obtain h' l' e' where red2: "P \ \e\<^sub>2,(h, l(V\v))\ \ \e',(h', l')\" by auto from red_lcl_incr[OF red2] have "V \ dom l'" by auto with red2 show ?thesis by(fastforce intro:InitBlockRed) qed next case (WTrtBlock E V T e T') have IH: "\l. \\ e \dom l\; \ final e\ \ \e' s'. P \ \e,(h,l)\ \ \e',s'\" and unass: "\ assigned V e" and D: "\ {V:T; e} \dom l\" by fact+ show ?case proof cases assume "final e" thus ?thesis proof (rule finalE) fix v assume "e = Val v" thus ?thesis by(fast intro:RedBlock) next fix a assume "e = Throw a" thus ?thesis by(fast intro:red_reds.BlockThrow) qed next assume not_fin: "\ final e" from D have De: "\ e \dom(l(V:=None))\" by(simp add:hyperset_defs) from IH[OF De not_fin] obtain h' l' e' where red: "P \ \e,(h,l(V:=None))\ \ \e',(h',l')\" by auto show ?thesis proof (cases "l' V") assume "l' V = None" with red unass show ?thesis by(blast intro: BlockRedNone) next fix v assume "l' V = Some v" with red unass show ?thesis by(blast intro: BlockRedSome) qed qed next case (WTrtSeq E e1 T1 e2 T2) show ?case proof cases assume "final e1" thus ?thesis by(fast elim:finalE intro:RedSeq red_reds.SeqThrow) next assume "\ final e1" with WTrtSeq show ?thesis by simp (blast intro:SeqRed) qed next case (WTrtCond E e e\<^sub>1 T\<^sub>1 e\<^sub>2 T\<^sub>2 T) have wt: "P,E,h \ e : Boolean" by fact show ?case proof cases assume "final e" thus ?thesis proof (rule finalE) fix v assume val: "e = Val v" then obtain b where v: "v = Bool b" using wt by auto show ?thesis proof (cases b) case True with val v show ?thesis by(auto intro:RedCondT) next case False with val v show ?thesis by(auto intro:RedCondF) qed next fix a assume "e = Throw a" thus ?thesis by(fast intro:red_reds.CondThrow) qed next assume "\ final e" with WTrtCond show ?thesis by simp (fast intro:CondRed) qed next case WTrtWhile show ?case by(fast intro:RedWhile) next case (WTrtThrow E e T\<^sub>r T) show ?case proof cases assume "final e" \ \Then @{term e} must be @{term throw} or @{term null}\ with WTrtThrow show ?thesis by(fastforce simp:final_def is_refT_def intro:red_reds.ThrowThrow red_reds.RedThrowNull) next assume "\ final e" \ \Then @{term e} must reduce\ with WTrtThrow show ?thesis by simp (blast intro:ThrowRed) qed next case (WTrtTry E e1 T1 V C e2 T2) have wt1: "P,E,h \ e1 : T1" by fact show ?case proof cases assume "final e1" thus ?thesis proof (rule finalE) fix v assume "e1 = Val v" thus ?thesis by(fast intro:RedTry) next fix a assume e1_Throw: "e1 = Throw a" with wt1 obtain D fs where ha: "h a = Some(D,fs)" by fastforce show ?thesis proof cases assume "P \ D \\<^sup>* C" with e1_Throw ha show ?thesis by(fastforce intro!:RedTryCatch) next assume "\ P \ D \\<^sup>* C" with e1_Throw ha show ?thesis by(force intro!:RedTryFail) qed qed next assume "\ final e1" with WTrtTry show ?thesis by simp (fast intro:TryRed) qed qed (*>*) end diff --git a/thys/JinjaDCI/J/DefAss.thy b/thys/JinjaDCI/J/DefAss.thy --- a/thys/JinjaDCI/J/DefAss.thy +++ b/thys/JinjaDCI/J/DefAss.thy @@ -1,189 +1,192 @@ (* Title: JinjaDCI/J/DefAss.thy Author: Tobias Nipkow, Susannah Mansky Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC Based on the Jinja theory J/DefAss.thy by Tobias Nipkow *) section \ Definite assignment \ theory DefAss imports BigStep begin subsection "Hypersets" type_synonym 'a hyperset = "'a set option" definition hyperUn :: "'a hyperset \ 'a hyperset \ 'a hyperset" (infixl "\" 65) where "A \ B \ case A of None \ None | \A\ \ (case B of None \ None | \B\ \ \A \ B\)" definition hyperInt :: "'a hyperset \ 'a hyperset \ 'a hyperset" (infixl "\" 70) where "A \ B \ case A of None \ B | \A\ \ (case B of None \ \A\ | \B\ \ \A \ B\)" definition hyperDiff1 :: "'a hyperset \ 'a \ 'a hyperset" (infixl "\" 65) where "A \ a \ case A of None \ None | \A\ \ \A - {a}\" definition hyper_isin :: "'a \ 'a hyperset \ bool" (infix "\\" 50) where "a \\ A \ case A of None \ True | \A\ \ a \ A" definition hyper_subset :: "'a hyperset \ 'a hyperset \ bool" (infix "\" 50) where "A \ B \ case B of None \ True | \B\ \ (case A of None \ False | \A\ \ A \ B)" lemmas hyperset_defs = hyperUn_def hyperInt_def hyperDiff1_def hyper_isin_def hyper_subset_def lemma [simp]: "\{}\ \ A = A \ A \ \{}\ = A" (*<*)by(simp add:hyperset_defs)(*>*) lemma [simp]: "\A\ \ \B\ = \A \ B\ \ \A\ \ a = \A - {a}\" (*<*)by(simp add:hyperset_defs)(*>*) lemma [simp]: "None \ A = None \ A \ None = None" (*<*)by(simp add:hyperset_defs)(*>*) lemma [simp]: "a \\ None \ None \ a = None" (*<*)by(simp add:hyperset_defs)(*>*) lemma hyper_isin_union: "x \\ \A\ \ x \\ \A\ \ B" by(case_tac B, auto simp: hyper_isin_def) lemma hyperUn_assoc: "(A \ B) \ C = A \ (B \ C)" (*<*)by(simp add:hyperset_defs Un_assoc)(*>*) lemma hyper_insert_comm: "A \ \{a}\ = \{a}\ \ A \ A \ (\{a}\ \ B) = \{a}\ \ (A \ B)" (*<*)by(simp add:hyperset_defs)(*>*) lemma hyper_comm: "A \ B = B \ A \ A \ B \ C = B \ A \ C" -apply(case_tac A, simp, case_tac B, simp) -apply(case_tac C, simp add: Un_commute) -apply(simp add: Un_left_commute Un_commute) -done +(*<*) +proof(cases A) + case SomeA: Some then show ?thesis + proof(cases B) + case SomeB: Some with SomeA show ?thesis + proof(cases C) + case SomeC: Some with SomeA SomeB show ?thesis + by(simp add: Un_left_commute Un_commute) + qed (simp add: Un_commute) + qed simp +qed simp +(*>*) subsection "Definite assignment" primrec \ :: "'a exp \ 'a hyperset" and \s :: "'a exp list \ 'a hyperset" where "\ (new C) = \{}\" | "\ (Cast C e) = \ e" | "\ (Val v) = \{}\" | "\ (e\<^sub>1 \bop\ e\<^sub>2) = \ e\<^sub>1 \ \ e\<^sub>2" | "\ (Var V) = \{}\" | "\ (LAss V e) = \{V}\ \ \ e" | "\ (e\F{D}) = \ e" | "\ (C\\<^sub>sF{D}) = \{}\" | "\ (e\<^sub>1\F{D}:=e\<^sub>2) = \ e\<^sub>1 \ \ e\<^sub>2" | "\ (C\\<^sub>sF{D}:=e\<^sub>2) = \ e\<^sub>2" | "\ (e\M(es)) = \ e \ \s es" | "\ (C\\<^sub>sM(es)) = \s es" | "\ ({V:T; e}) = \ e \ V" | "\ (e\<^sub>1;;e\<^sub>2) = \ e\<^sub>1 \ \ e\<^sub>2" | "\ (if (e) e\<^sub>1 else e\<^sub>2) = \ e \ (\ e\<^sub>1 \ \ e\<^sub>2)" | "\ (while (b) e) = \ b" | "\ (throw e) = None" | "\ (try e\<^sub>1 catch(C V) e\<^sub>2) = \ e\<^sub>1 \ (\ e\<^sub>2 \ V)" | "\ (INIT C (Cs,b) \ e) = \{}\" | "\ (RI (C,e);Cs \ e') = \ e" | "\s ([]) = \{}\" | "\s (e#es) = \ e \ \s es" primrec \ :: "'a exp \ 'a hyperset \ bool" and \s :: "'a exp list \ 'a hyperset \ bool" where "\ (new C) A = True" | "\ (Cast C e) A = \ e A" | "\ (Val v) A = True" | "\ (e\<^sub>1 \bop\ e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \ e\<^sub>1))" | "\ (Var V) A = (V \\ A)" | "\ (LAss V e) A = \ e A" | "\ (e\F{D}) A = \ e A" | "\ (C\\<^sub>sF{D}) A = True" | "\ (e\<^sub>1\F{D}:=e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \ e\<^sub>1))" | "\ (C\\<^sub>sF{D}:=e\<^sub>2) A = \ e\<^sub>2 A" | "\ (e\M(es)) A = (\ e A \ \s es (A \ \ e))" | "\ (C\\<^sub>sM(es)) A = \s es A" | "\ ({V:T; e}) A = \ e (A \ V)" | "\ (e\<^sub>1;;e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \ e\<^sub>1))" | "\ (if (e) e\<^sub>1 else e\<^sub>2) A = (\ e A \ \ e\<^sub>1 (A \ \ e) \ \ e\<^sub>2 (A \ \ e))" | "\ (while (e) c) A = (\ e A \ \ c (A \ \ e))" | "\ (throw e) A = \ e A" | "\ (try e\<^sub>1 catch(C V) e\<^sub>2) A = (\ e\<^sub>1 A \ \ e\<^sub>2 (A \ \{V}\))" | "\ (INIT C (Cs,b) \ e) A = \ e A" | "\ (RI (C,e);Cs \ e') A = (\ e A \ \ e' A)" | "\s ([]) A = True" | "\s (e#es) A = (\ e A \ \s es (A \ \ e))" lemma As_map_Val[simp]: "\s (map Val vs) = \{}\" (*<*)by (induct vs) simp_all(*>*) lemma D_append[iff]: "\A. \s (es @ es') A = (\s es A \ \s es' (A \ \s es))" (*<*)by (induct es type:list) (auto simp:hyperUn_assoc)(*>*) lemma A_fv: "\A. \ e = \A\ \ A \ fv e" and "\A. \s es = \A\ \ A \ fvs es" (*<*) -apply(induct e and es rule: \.induct \s.induct) -apply (simp_all add:hyperset_defs) -apply blast+ -done +by (induct e and es rule: \.induct \s.induct) + (fastforce simp add:hyperset_defs)+ (*>*) lemma sqUn_lem: "A \ A' \ A \ B \ A' \ B" (*<*)by(simp add:hyperset_defs) blast(*>*) lemma diff_lem: "A \ A' \ A \ b \ A' \ b" (*<*)by(simp add:hyperset_defs) blast(*>*) (* This order of the premises avoids looping of the simplifier *) lemma D_mono: "\A A'. A \ A' \ \ e A \ \ (e::'a exp) A'" and Ds_mono: "\A A'. A \ A' \ \s es A \ \s (es::'a exp list) A'" (*<*) -apply(induct e and es rule: \.induct \s.induct) -apply simp -apply simp -apply simp -apply simp apply (iprover dest:sqUn_lem) -apply (fastforce simp add:hyperset_defs) -apply simp -apply simp -apply simp -apply simp apply (iprover dest:sqUn_lem) -apply simp -apply simp apply (iprover dest:sqUn_lem) -apply simp -apply simp apply (iprover dest:diff_lem) -apply simp apply (iprover dest:sqUn_lem) -apply simp apply (iprover dest:sqUn_lem) -apply simp apply (iprover dest:sqUn_lem) -apply simp -apply simp apply (iprover dest:sqUn_lem) -apply simp -apply simp -apply simp -apply simp apply (iprover dest:sqUn_lem) -done +proof(induct e and es rule: \.induct \s.induct) + case BinOp then show ?case by simp (iprover dest:sqUn_lem) +next + case Var then show ?case by (fastforce simp add:hyperset_defs) +next + case FAss then show ?case by simp (iprover dest:sqUn_lem) +next + case Call then show ?case by simp (iprover dest:sqUn_lem) +next + case Block then show ?case by simp (iprover dest:diff_lem) +next + case Seq then show ?case by simp (iprover dest:sqUn_lem) +next + case Cond then show ?case by simp (iprover dest:sqUn_lem) +next + case While then show ?case by simp (iprover dest:sqUn_lem) +next + case TryCatch then show ?case by simp (iprover dest:sqUn_lem) +next + case Cons_exp then show ?case by simp (iprover dest:sqUn_lem) +qed simp_all (*>*) (* And this is the order of premises preferred during application: *) lemma D_mono': "\ e A \ A \ A' \ \ e A'" and Ds_mono': "\s es A \ A \ A' \ \s es A'" (*<*)by(blast intro:D_mono, blast intro:Ds_mono)(*>*) lemma Ds_Vals: "\s (map Val vs) A" by(induct vs, auto) end diff --git a/thys/JinjaDCI/J/EConform.thy b/thys/JinjaDCI/J/EConform.thy --- a/thys/JinjaDCI/J/EConform.thy +++ b/thys/JinjaDCI/J/EConform.thy @@ -1,350 +1,337 @@ (* Title: JinjaDCI/J/EConform.thy Author: Susannah Mansky 2019-20 UIUC *) section \ Expression conformance properties \ theory EConform imports SmallStep BigStep begin lemma cons_to_append: "list \ [] \ (\ls. a # list = ls @ [last list])" by (metis append_butlast_last_id last_ConsR list.simps(3)) subsection "Initialization conformance" \ \ returns class that can be initialized (if any) by top-level expression \ fun init_class :: "'m prog \ 'a exp \ cname option" where "init_class P (new C) = Some C" | "init_class P (C\\<^sub>sF{D}) = Some D" | "init_class P (C\\<^sub>sF{D}:=e\<^sub>2) = Some D" | "init_class P (C\\<^sub>sM(es)) = seeing_class P C M" | "init_class _ _ = None" lemma icheck_init_class: "icheck P C e \ init_class P e = \C\" -apply(induct e, auto) apply(rename_tac x1 x2 x3 x4) -apply(case_tac x4, auto) -done +proof(induct e) + case (SFAss x1 x2 x3 e') + then show ?case by(case_tac e') auto +qed auto \ \ exp to take next small step (in particular, subexp that may contain initialization) \ fun ss_exp :: "'a exp \ 'a exp" and ss_exps :: "'a exp list \ 'a exp option" where "ss_exp (new C) = new C" | "ss_exp (Cast C e) = (case val_of e of Some v \ Cast C e | _ \ ss_exp e)" | "ss_exp (Val v) = Val v" | "ss_exp (e\<^sub>1 \bop\ e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ (case val_of e\<^sub>2 of Some v \ e\<^sub>1 \bop\ e\<^sub>2 | _ \ ss_exp e\<^sub>2) | _ \ ss_exp e\<^sub>1)" | "ss_exp (Var V) = Var V" | "ss_exp (LAss V e) = (case val_of e of Some v \ LAss V e | _ \ ss_exp e)" | "ss_exp (e\F{D}) = (case val_of e of Some v \ e\F{D} | _ \ ss_exp e)" | "ss_exp (C\\<^sub>sF{D}) = C\\<^sub>sF{D}" | "ss_exp (e\<^sub>1\F{D}:=e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ (case val_of e\<^sub>2 of Some v \ e\<^sub>1\F{D}:=e\<^sub>2 | _ \ ss_exp e\<^sub>2) | _ \ ss_exp e\<^sub>1)" | "ss_exp (C\\<^sub>sF{D}:=e\<^sub>2) = (case val_of e\<^sub>2 of Some v \ C\\<^sub>sF{D}:=e\<^sub>2 | _ \ ss_exp e\<^sub>2)" | "ss_exp (e\M(es)) = (case val_of e of Some v \ (case map_vals_of es of Some t \ e\M(es) | _ \ the(ss_exps es)) | _ \ ss_exp e)" | "ss_exp (C\\<^sub>sM(es)) = (case map_vals_of es of Some t \ C\\<^sub>sM(es) | _ \ the(ss_exps es))" | "ss_exp ({V:T; e}) = ss_exp e" | "ss_exp (e\<^sub>1;;e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ ss_exp e\<^sub>2 | None \ (case lass_val_of e\<^sub>1 of Some p \ ss_exp e\<^sub>2 | None \ ss_exp e\<^sub>1))" | "ss_exp (if (b) e\<^sub>1 else e\<^sub>2) = (case bool_of b of Some True \ if (b) e\<^sub>1 else e\<^sub>2 | Some False \ if (b) e\<^sub>1 else e\<^sub>2 | _ \ ss_exp b)" | "ss_exp (while (b) e) = while (b) e" | "ss_exp (throw e) = (case val_of e of Some v \ throw e | _ \ ss_exp e)" | "ss_exp (try e\<^sub>1 catch(C V) e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ try e\<^sub>1 catch(C V) e\<^sub>2 | _ \ ss_exp e\<^sub>1)" | "ss_exp (INIT C (Cs,b) \ e) = INIT C (Cs,b) \ e" | "ss_exp (RI (C,e);Cs \ e') = (case val_of e of Some v \ RI (C,e);Cs \ e | _ \ ss_exp e)" | "ss_exps([]) = None" | "ss_exps(e#es) = (case val_of e of Some v \ ss_exps es | _ \ Some (ss_exp e))" (*<*) lemmas ss_exp_ss_exps_induct = ss_exp_ss_exps.induct [ case_names New Cast Val BinOp Var LAss FAcc SFAcc FAss SFAss Call SCall Block Seq Cond While Throw Try Init RI Nil Cons ] (*>*) lemma icheck_ss_exp: assumes "icheck P C e" shows "ss_exp e = e" using assms proof(cases e) case (SFAss C F D e) then show ?thesis using assms proof(cases e)qed(auto) qed(auto) lemma ss_exps_Vals_None[simp]: "ss_exps (map Val vs) = None" - by(induct vs, auto) + by(induct vs) (auto) lemma ss_exps_Vals_NoneI: "ss_exps es = None \ \vs. es = map Val vs" -using val_of_spec by(induct es, auto) +using val_of_spec by(induct es) (auto) lemma ss_exps_throw_nVal: "\ val_of e = None; ss_exps (map Val vs @ throw e # es') = \e'\ \ \ e' = ss_exp e" - by(induct vs, auto) + by(induct vs) (auto) lemma ss_exps_throw_Val: "\ val_of e = \a\; ss_exps (map Val vs @ throw e # es') = \e'\ \ \ e' = throw e" - by(induct vs, auto) + by(induct vs) (auto) abbreviation curr_init :: "'m prog \ 'a exp \ cname option" where "curr_init P e \ init_class P (ss_exp e)" abbreviation curr_inits :: "'m prog \ 'a exp list \ cname option" where "curr_inits P es \ case ss_exps es of Some e \ init_class P e | _ \ None" lemma icheck_curr_init': "\e'. ss_exp e = e' \ icheck P C e' \ curr_init P e = \C\" and icheck_curr_inits': "\e. ss_exps es = \e\ \ icheck P C e \ curr_inits P es = \C\" proof(induct rule: ss_exp_ss_exps_induct) qed(simp_all add: icheck_init_class) lemma icheck_curr_init: "icheck P C e' \ ss_exp e = e' \ curr_init P e = \C\" by(rule icheck_curr_init') lemma icheck_curr_inits: "icheck P C e \ ss_exps es = \e\ \ curr_inits P es = \C\" by(rule icheck_curr_inits') definition initPD :: "sheap \ cname \ bool" where "initPD sh C \ \sfs i. sh C = Some (sfs, i) \ (i = Done \ i = Processing)" \ \ checks that @{text INIT} and @{text RI} conform and are only in the main computation \ fun iconf :: "sheap \ 'a exp \ bool" and iconfs :: " sheap \ 'a exp list \ bool" where "iconf sh (new C) = True" | "iconf sh (Cast C e) = iconf sh e" | "iconf sh (Val v) = True" | "iconf sh (e\<^sub>1 \bop\ e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ iconf sh e\<^sub>2 | _ \ iconf sh e\<^sub>1 \ \sub_RI e\<^sub>2)" | "iconf sh (Var V) = True" | "iconf sh (LAss V e) = iconf sh e" | "iconf sh (e\F{D}) = iconf sh e" | "iconf sh (C\\<^sub>sF{D}) = True" | "iconf sh (e\<^sub>1\F{D}:=e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ iconf sh e\<^sub>2 | _ \ iconf sh e\<^sub>1 \ \sub_RI e\<^sub>2)" | "iconf sh (C\\<^sub>sF{D}:=e\<^sub>2) = iconf sh e\<^sub>2" | "iconf sh (e\M(es)) = (case val_of e of Some v \ iconfs sh es | _ \ iconf sh e \ \sub_RIs es)" | "iconf sh (C\\<^sub>sM(es)) = iconfs sh es" | "iconf sh ({V:T; e}) = iconf sh e" | "iconf sh (e\<^sub>1;;e\<^sub>2) = (case val_of e\<^sub>1 of Some v \ iconf sh e\<^sub>2 | None \ (case lass_val_of e\<^sub>1 of Some p \ iconf sh e\<^sub>2 | None \ iconf sh e\<^sub>1 \ \sub_RI e\<^sub>2))" | "iconf sh (if (b) e\<^sub>1 else e\<^sub>2) = (iconf sh b \ \sub_RI e\<^sub>1 \ \sub_RI e\<^sub>2)" | "iconf sh (while (b) e) = (\sub_RI b \ \sub_RI e)" | "iconf sh (throw e) = iconf sh e" | "iconf sh (try e\<^sub>1 catch(C V) e\<^sub>2) = (iconf sh e\<^sub>1 \ \sub_RI e\<^sub>2)" | "iconf sh (INIT C (Cs,b) \ e) = ((case Cs of Nil \ initPD sh C | C'#Cs' \ last Cs = C) \ \sub_RI e)" | "iconf sh (RI (C,e);Cs \ e') = (iconf sh e \ \sub_RI e')" | "iconfs sh ([]) = True" | "iconfs sh (e#es) = (case val_of e of Some v \ iconfs sh es | _ \ iconf sh e \ \sub_RIs es)" lemma iconfs_map_throw: "iconfs sh (map Val vs @ throw e # es') \ iconf sh e" by(induct vs,auto) lemma nsub_RI_iconf_aux: "(\sub_RI (e::'a exp) \ (\e'. e' \ subexp e \ \sub_RI e' \ iconf sh e') \ iconf sh e) \ (\sub_RIs (es::'a exp list) \ (\e'. e' \ subexps es \ \sub_RI e' \ iconf sh e') \ iconfs sh es)" proof(induct rule: sub_RI_sub_RIs.induct) qed(auto) lemma nsub_RI_iconf_aux': "(\e'. subexp_of e' e \ \sub_RI e' \ iconf sh e') \ (\sub_RI e \ iconf sh e)" by(simp add: nsub_RI_iconf_aux) lemma nsub_RI_iconf: "\sub_RI e \ iconf sh e" -apply(cut_tac e = e and R = "\e. \sub_RI e \ iconf sh e" in subexp_induct) - apply(rename_tac ea) apply(case_tac ea, simp_all) -apply(clarsimp simp: nsub_RI_iconf_aux) -done - -lemma nsub_RIs_iconfs: "\sub_RIs es \ iconfs sh es" -apply(cut_tac es = es and R = "\e. \sub_RI e \ iconf sh e" - and Rs = "\es. \sub_RIs es \ iconfs sh es" in subexps_induct) - apply(rename_tac esa) apply(case_tac esa, simp_all) - apply(clarsimp simp: nsub_RI_iconf_aux)+ -done + and nsub_RIs_iconfs: "\sub_RIs es \ iconfs sh es" +proof - + let ?R = "\e. \sub_RI e \ iconf sh e" + let ?Rs = "\es. \sub_RIs es \ iconfs sh es" + have "(\e'. subexp_of e' e \ ?R e') \ ?R e" + and "(\e'. e' \ subexps es \ ?R e') \ ?Rs es" + by(rule subexp_induct[where ?Rs = ?Rs]; clarsimp simp: nsub_RI_iconf_aux) + (rule subexps_induct; clarsimp simp: nsub_RI_iconf_aux) + then show "\sub_RI e \ iconf sh e" + and "\sub_RIs es \ iconfs sh es" by simp+ +qed lemma lass_val_of_iconf: "lass_val_of e = \a\ \ iconf sh e" by(drule lass_val_of_nsub_RI, erule nsub_RI_iconf) lemma icheck_iconf: assumes "icheck P C e" shows "iconf sh e" using assms proof(cases e) case (SFAss C F D e) then show ?thesis using assms proof(cases e)qed(auto) next case (SCall C M es) then show ?thesis using assms by (auto simp: nsub_RIs_iconfs) next qed(auto) subsection "Indicator boolean conformance" \ \ checks that the given expression, indicator boolean pair is allowed in small-step (i.e., if @{term b} is True, then @{term e} is an initialization-calling expression to a class that is marked either @{term Processing} or @{term Done}) \ definition bconf :: "'m prog \ sheap \ 'a exp \ bool \ bool" ("_,_ \\<^sub>b '(_,_') \" [51,51,0,0] 50) where "P,sh \\<^sub>b (e,b) \ \ b \ (\C. icheck P C (ss_exp e) \ initPD sh C)" definition bconfs :: "'m prog \ sheap \ 'a exp list \ bool \ bool" ("_,_ \\<^sub>b '(_,_') \" [51,51,0,0] 50) where "P,sh \\<^sub>b (es,b) \ \ b \ (\C. (icheck P C (the(ss_exps es)) \ (curr_inits P es = Some C) \ initPD sh C))" \ \ bconf helper lemmas \ lemma bconf_nonVal[simp]: "P,sh \\<^sub>b (e,True) \ \ val_of e = None" - by(cases e, auto simp: bconf_def) + by(cases e) (auto simp: bconf_def) lemma bconfs_nonVals[simp]: "P,sh \\<^sub>b (es,True) \ \ map_vals_of es = None" - by(induct es, auto simp: bconfs_def) + by(induct es) (auto simp: bconfs_def) lemma bconf_Cast[iff]: "P,sh \\<^sub>b (Cast C e,b) \ \ P,sh \\<^sub>b (e,b) \" -apply(unfold bconf_def, cases b, auto) -apply(drule val_of_spec, simp) -done + by(cases b) (auto simp: bconf_def dest: val_of_spec) lemma bconf_BinOp[iff]: "P,sh \\<^sub>b (e1 \bop\ e2,b) \ \ (case val_of e1 of Some v \ P,sh \\<^sub>b (e2,b) \ | _ \ P,sh \\<^sub>b (e1,b) \)" -apply(unfold bconf_def, cases b, auto) -apply(drule val_of_spec, simp) -done + by(cases b) (auto simp: bconf_def dest: val_of_spec) lemma bconf_LAss[iff]: "P,sh \\<^sub>b (LAss V e,b) \ \ P,sh \\<^sub>b (e,b) \" -apply(unfold bconf_def, cases b, auto) -apply(drule val_of_spec, simp) -done + by(cases b) (auto simp: bconf_def dest: val_of_spec) lemma bconf_FAcc[iff]: "P,sh \\<^sub>b (e\F{D},b) \ \ P,sh \\<^sub>b (e,b) \" -apply(unfold bconf_def, cases b, auto) -apply(drule val_of_spec, simp) -done + by(cases b) (auto simp: bconf_def dest: val_of_spec) lemma bconf_FAss[iff]: "P,sh \\<^sub>b (FAss e1 F D e2,b) \ \ (case val_of e1 of Some v \ P,sh \\<^sub>b (e2,b) \ | _ \ P,sh \\<^sub>b (e1,b) \)" -apply(unfold bconf_def, cases b, auto) -apply(drule val_of_spec, simp) -done + by(cases b) (auto simp: bconf_def dest: val_of_spec) lemma bconf_SFAss[iff]: "val_of e2 = None \ P,sh \\<^sub>b (SFAss C F D e2,b) \ \ P,sh \\<^sub>b (e2,b) \" - by(unfold bconf_def, cases b, auto) + by(cases b) (auto simp: bconf_def) lemma bconfs_Vals[iff]: "P,sh \\<^sub>b (map Val vs, b) \ \ \ b" - by(unfold bconfs_def, simp) + by(unfold bconfs_def) simp lemma bconf_Call[iff]: "P,sh \\<^sub>b (e\M(es),b) \ \ (case val_of e of Some v \ P,sh \\<^sub>b (es,b) \ | _ \ P,sh \\<^sub>b (e,b) \)" proof(cases b) case True then show ?thesis proof(cases "ss_exps es") case None then obtain vs where "es = map Val vs" using ss_exps_Vals_NoneI by auto then have mv: "map_vals_of es = \vs\" by simp then show ?thesis by(auto simp: bconf_def) (simp add: bconfs_def) next case (Some a) - then show ?thesis by(auto simp: bconf_def, auto simp: bconfs_def icheck_init_class) + then show ?thesis by(auto simp: bconf_def) (auto simp: bconfs_def icheck_init_class) qed qed(simp add: bconf_def bconfs_def) lemma bconf_SCall[iff]: assumes mvn: "map_vals_of es = None" shows "P,sh \\<^sub>b (C\\<^sub>sM(es),b) \ \ P,sh \\<^sub>b (es,b) \" proof(cases b) case True then show ?thesis proof(cases "ss_exps es") case None then have "\vs. es = map Val vs" using ss_exps_Vals_NoneI by auto then show ?thesis using mvn finals_def by clarsimp next case (Some a) - then show ?thesis by(auto simp: bconf_def, auto simp: bconfs_def icheck_init_class) + then show ?thesis by(auto simp: bconf_def) (auto simp: bconfs_def icheck_init_class) qed qed(simp add: bconf_def bconfs_def) lemma bconf_Cons[iff]: "P,sh \\<^sub>b (e#es,b) \ \ (case val_of e of Some v \ P,sh \\<^sub>b (es,b) \ | _ \ P,sh \\<^sub>b (e,b) \)" proof(cases b) case True then show ?thesis proof(cases "ss_exps es") case None then have "\vs. es = map Val vs" using ss_exps_Vals_NoneI by auto then show ?thesis using None by(auto simp: bconf_def bconfs_def icheck_init_class) next case (Some a) then show ?thesis by(auto simp: bconf_def bconfs_def icheck_init_class) qed qed(simp add: bconf_def bconfs_def) lemma bconf_InitBlock[iff]: "P,sh \\<^sub>b ({V:T; V:=Val v;; e\<^sub>2},b) \ \ P,sh \\<^sub>b (e\<^sub>2,b) \" - by(unfold bconf_def, cases b, auto simp: assigned_def) + by(cases b) (auto simp: bconf_def assigned_def) lemma bconf_Block[iff]: "P,sh \\<^sub>b ({V:T; e},b) \ \ P,sh \\<^sub>b (e,b) \" - by(unfold bconf_def, cases b, auto) + by(cases b) (auto simp: bconf_def) lemma bconf_Seq[iff]: "P,sh \\<^sub>b (e1;;e2,b) \ \ (case val_of e1 of Some v \ P,sh \\<^sub>b (e2,b) \ | _ \ (case lass_val_of e1 of Some p \ P,sh \\<^sub>b (e2,b) \ - | None \ P,sh \\<^sub>b (e1,b) \))" (* \ P,sh \\<^sub>b (e1,b) \"*) -by(unfold bconf_def, cases b, auto dest: val_of_spec lass_val_of_spec) + | None \ P,sh \\<^sub>b (e1,b) \))" + by(cases b) (auto simp: bconf_def dest: val_of_spec lass_val_of_spec) lemma bconf_Cond[iff]: "P,sh \\<^sub>b (if (b) e\<^sub>1 else e\<^sub>2,b') \ \ P,sh \\<^sub>b (b,b') \" -apply(unfold bconf_def, cases "bool_of b") apply auto[1] -apply(rename_tac a) apply(case_tac a) - apply(simp, drule bool_of_specT) apply auto[1] -apply(simp, drule bool_of_specF) apply auto[1] -done +proof(cases "bool_of b") + case None + then show ?thesis by(auto simp: bconf_def) +next + case (Some a) + then show ?thesis by(case_tac a) (auto simp: bconf_def dest: bool_of_specT bool_of_specF) +qed lemma bconf_While[iff]: "P,sh \\<^sub>b (while (b) e,b') \ \ \b'" - by(unfold bconf_def, cases b, auto) + by(cases b) (auto simp: bconf_def) lemma bconf_Throw[iff]: "P,sh \\<^sub>b (throw e,b) \ \ P,sh \\<^sub>b (e,b) \" -apply(unfold bconf_def, cases b, auto) -apply(drule val_of_spec, simp) -done + by(cases b) (auto simp: bconf_def dest: val_of_spec) lemma bconf_Try[iff]: "P,sh \\<^sub>b (try e\<^sub>1 catch(C V) e\<^sub>2,b) \ \ P,sh \\<^sub>b (e\<^sub>1,b) \" -apply(unfold bconf_def, cases b, auto) -apply(drule val_of_spec, simp) -done + by(cases b) (auto simp: bconf_def dest: val_of_spec) lemma bconf_INIT[iff]: "P,sh \\<^sub>b (INIT C (Cs,b') \ e,b) \ \ \b" - by(unfold bconf_def, cases b, auto) + by(cases b) (auto simp: bconf_def) lemma bconf_RI[iff]: "P,sh \\<^sub>b (RI(C,e);Cs \ e',b) \ \ P,sh \\<^sub>b (e,b) \" -apply(unfold bconf_def, cases b, auto) -apply(drule val_of_spec, simp) -done + by(cases b) (auto simp: bconf_def dest: val_of_spec) lemma bconfs_map_throw[iff]: "P,sh \\<^sub>b (map Val vs @ throw e # es',b) \ \ P,sh \\<^sub>b (e,b) \" - by(induct vs, auto) + by(induct vs) auto end diff --git a/thys/JinjaDCI/J/JWellForm.thy b/thys/JinjaDCI/J/JWellForm.thy --- a/thys/JinjaDCI/J/JWellForm.thy +++ b/thys/JinjaDCI/J/JWellForm.thy @@ -1,82 +1,73 @@ (* Title: JinjaDCI/J/JWellForm.thy Author: Tobias Nipkow, Susannah Mansky Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC Based on the Jinja theory J/JWellForm.thy by Tobias Nipkow *) section \ Well-formedness Constraints \ theory JWellForm imports "../Common/WellForm" WWellForm WellType DefAss begin definition wf_J_mdecl :: "J_prog \ cname \ J_mb mdecl \ bool" where "wf_J_mdecl P C \ \(M,b,Ts,T,(pns,body)). length Ts = length pns \ distinct pns \ \sub_RI body \ (case b of NonStatic \ this \ set pns \ (\T'. P,[this\Class C,pns[\]Ts] \ body :: T' \ P \ T' \ T) \ \ body \{this} \ set pns\ | Static \ (\T'. P,[pns[\]Ts] \ body :: T' \ P \ T' \ T) \ \ body \set pns\)" lemma wf_J_mdecl_NonStatic[simp]: "wf_J_mdecl P C (M,NonStatic,Ts,T,pns,body) \ (length Ts = length pns \ distinct pns \ \sub_RI body \ this \ set pns \ (\T'. P,[this\Class C,pns[\]Ts] \ body :: T' \ P \ T' \ T) \ \ body \{this} \ set pns\)" (*<*)by(simp add:wf_J_mdecl_def)(*>*) lemma wf_J_mdecl_Static[simp]: "wf_J_mdecl P C (M,Static,Ts,T,pns,body) \ (length Ts = length pns \ distinct pns \ \sub_RI body \ (\T'. P,[pns[\]Ts] \ body :: T' \ P \ T' \ T) \ \ body \set pns\)" (*<*)by(simp add:wf_J_mdecl_def)(*>*) abbreviation wf_J_prog :: "J_prog \ bool" where "wf_J_prog == wf_prog wf_J_mdecl" lemma wf_J_prog_wf_J_mdecl: "\ wf_J_prog P; (C, D, fds, mths) \ set P; jmdcl \ set mths \ \ wf_J_mdecl P C jmdcl" -(*<*) -apply (simp add: wf_prog_def) -apply (simp add: wf_cdecl_def) -apply (erule conjE)+ -apply (drule bspec, assumption) -apply simp -apply (erule conjE)+ -apply (drule bspec, assumption) -apply (simp add: wf_mdecl_def split_beta) -done -(*>*) +(*<*)by(fastforce simp: wf_prog_def wf_cdecl_def wf_mdecl_def)(*>*) lemma wf_mdecl_wwf_mdecl: "wf_J_mdecl P C Md \ wwf_J_mdecl P C Md" (*<*) -apply(clarsimp simp:wwf_J_mdecl_def) apply(rename_tac M b Ts T pns body) -apply (case_tac b) - by (fastforce dest!:WT_fv)+ +proof - + obtain M b Ts T pns body where "Md = (M, b, Ts, T, pns, body)" by(cases Md) simp + then show "wf_J_mdecl P C Md \ wwf_J_mdecl P C Md" + by(case_tac b) (fastforce simp:wwf_J_mdecl_def dest!:WT_fv)+ +qed (*>*) lemma wf_prog_wwf_prog: "wf_J_prog P \ wwf_J_prog P" (*<*) -apply(simp add:wf_prog_def wf_cdecl_def wf_mdecl_def) -apply(fast intro:wf_mdecl_wwf_mdecl) -done +by (simp add:wf_prog_def wf_cdecl_def wf_mdecl_def) + (fast intro:wf_mdecl_wwf_mdecl) (*>*) end diff --git a/thys/JinjaDCI/J/Progress.thy b/thys/JinjaDCI/J/Progress.thy --- a/thys/JinjaDCI/J/Progress.thy +++ b/thys/JinjaDCI/J/Progress.thy @@ -1,887 +1,880 @@ (* Title: JinjaDCI/J/Progress.thy Author: Tobias Nipkow, Susannah Mansky Copyright 2003 Technische Universitaet Muenchen, 2019-20 UIUC Based on the Jinja theory J/Progress.thy by Tobias Nipkow *) section \ Progress of Small Step Semantics \ theory Progress imports WellTypeRT DefAss "../Common/Conform" EConform begin lemma final_addrE: "\ P,E,h,sh \ e : Class C; final e; \a. e = addr a \ R; \a. e = Throw a \ R \ \ R" (*<*)by(auto simp:final_def)(*>*) lemma finalRefE: "\ P,E,h,sh \ e : T; is_refT T; final e; e = null \ R; \a C. \ e = addr a; T = Class C \ \ R; \a. e = Throw a \ R \ \ R" (*<*)by(auto simp:final_def is_refT_def)(*>*) text\ Derivation of new induction scheme for well typing: \ inductive WTrt' :: "[J_prog,heap,sheap,env,expr,ty] \ bool" and WTrts' :: "[J_prog,heap,sheap,env,expr list, ty list] \ bool" and WTrt2' :: "[J_prog,env,heap,sheap,expr,ty] \ bool" ("_,_,_,_ \ _ :'' _" [51,51,51,51]50) and WTrts2' :: "[J_prog,env,heap,sheap,expr list, ty list] \ bool" ("_,_,_,_ \ _ [:''] _" [51,51,51,51]50) for P :: J_prog and h :: heap and sh :: sheap where "P,E,h,sh \ e :' T \ WTrt' P h sh E e T" | "P,E,h,sh \ es [:'] Ts \ WTrts' P h sh E es Ts" | "is_class P C \ P,E,h,sh \ new C :' Class C" | "\ P,E,h,sh \ e :' T; is_refT T; is_class P C \ \ P,E,h,sh \ Cast C e :' Class C" | "typeof\<^bsub>h\<^esub> v = Some T \ P,E,h,sh \ Val v :' T" | "E v = Some T \ P,E,h,sh \ Var v :' T" | "\ P,E,h,sh \ e\<^sub>1 :' T\<^sub>1; P,E,h,sh \ e\<^sub>2 :' T\<^sub>2 \ \ P,E,h,sh \ e\<^sub>1 \Eq\ e\<^sub>2 :' Boolean" | "\ P,E,h,sh \ e\<^sub>1 :' Integer; P,E,h,sh \ e\<^sub>2 :' Integer \ \ P,E,h,sh \ e\<^sub>1 \Add\ e\<^sub>2 :' Integer" | "\ P,E,h,sh \ Var V :' T; P,E,h,sh \ e :' T'; P \ T' \ T \ \ P,E,h,sh \ V:=e :' Void" | "\ P,E,h,sh \ e :' Class C; P \ C has F,NonStatic:T in D \ \ P,E,h,sh \ e\F{D} :' T" | "P,E,h,sh \ e :' NT \ P,E,h,sh \ e\F{D} :' T" | "\ P \ C has F,Static:T in D \ \ P,E,h,sh \ C\\<^sub>sF{D} :' T" | "\ P,E,h,sh \ e\<^sub>1 :' Class C; P \ C has F,NonStatic:T in D; P,E,h,sh \ e\<^sub>2 :' T\<^sub>2; P \ T\<^sub>2 \ T \ \ P,E,h,sh \ e\<^sub>1\F{D}:=e\<^sub>2 :' Void" | "\ P,E,h,sh \ e\<^sub>1:'NT; P,E,h,sh \ e\<^sub>2 :' T\<^sub>2 \ \ P,E,h,sh \ e\<^sub>1\F{D}:=e\<^sub>2 :' Void" | "\ P \ C has F,Static:T in D; P,E,h,sh \ e\<^sub>2 :' T\<^sub>2; P \ T\<^sub>2 \ T \ \ P,E,h,sh \ C\\<^sub>sF{D}:=e\<^sub>2 :' Void" | "\ P,E,h,sh \ e :' Class C; P \ C sees M,NonStatic:Ts \ T = (pns,body) in D; P,E,h,sh \ es [:'] Ts'; P \ Ts' [\] Ts \ \ P,E,h,sh \ e\M(es) :' T" | "\ P,E,h,sh \ e :' NT; P,E,h,sh \ es [:'] Ts \ \ P,E,h,sh \ e\M(es) :' T" | "\ P \ C sees M,Static:Ts \ T = (pns,body) in D; P,E,h,sh \ es [:'] Ts'; P \ Ts' [\] Ts; M = clinit \ sh D = \(sfs,Processing)\ \ es = map Val vs \ \ P,E,h,sh \ C\\<^sub>sM(es) :' T" | "P,E,h,sh \ [] [:'] []" | "\ P,E,h,sh \ e :' T; P,E,h,sh \ es [:'] Ts \ \ P,E,h,sh \ e#es [:'] T#Ts" | "\ typeof\<^bsub>h\<^esub> v = Some T\<^sub>1; P \ T\<^sub>1 \ T; P,E(V\T),h,sh \ e\<^sub>2 :' T\<^sub>2 \ \ P,E,h,sh \ {V:T := Val v; e\<^sub>2} :' T\<^sub>2" | "\ P,E(V\T),h,sh \ e :' T'; \ assigned V e \ \ P,E,h,sh \ {V:T; e} :' T'" | "\ P,E,h,sh \ e\<^sub>1:' T\<^sub>1; P,E,h,sh \ e\<^sub>2:'T\<^sub>2 \ \ P,E,h,sh \ e\<^sub>1;;e\<^sub>2 :' T\<^sub>2" | "\ P,E,h,sh \ e :' Boolean; P,E,h,sh \ e\<^sub>1:' T\<^sub>1; P,E,h,sh \ e\<^sub>2:' T\<^sub>2; P \ T\<^sub>1 \ T\<^sub>2 \ P \ T\<^sub>2 \ T\<^sub>1; P \ T\<^sub>1 \ T\<^sub>2 \ T = T\<^sub>2; P \ T\<^sub>2 \ T\<^sub>1 \ T = T\<^sub>1 \ \ P,E,h,sh \ if (e) e\<^sub>1 else e\<^sub>2 :' T" | "\ P,E,h,sh \ e :' Boolean; P,E,h,sh \ c:' T \ \ P,E,h,sh \ while(e) c :' Void" | "\ P,E,h,sh \ e :' T\<^sub>r; is_refT T\<^sub>r \ \ P,E,h,sh \ throw e :' T" | "\ P,E,h,sh \ e\<^sub>1 :' T\<^sub>1; P,E(V \ Class C),h,sh \ e\<^sub>2 :' T\<^sub>2; P \ T\<^sub>1 \ T\<^sub>2 \ \ P,E,h,sh \ try e\<^sub>1 catch(C V) e\<^sub>2 :' T\<^sub>2" | "\ P,E,h,sh \ e :' T; \C' \ set (C#Cs). is_class P C'; \sub_RI e; \C' \ set (tl Cs). \sfs. sh C' = \(sfs,Processing)\; b \ (\C' \ set Cs. \sfs. sh C' = \(sfs,Processing)\); distinct Cs; supercls_lst P Cs \ \ P,E,h,sh \ INIT C (Cs, b) \ e :' T" | "\ P,E,h,sh \ e :' T; P,E,h,sh \ e' :' T'; \C' \ set (C#Cs). is_class P C'; \sub_RI e'; \C' \ set (C#Cs). not_init C' e; \C' \ set Cs. \sfs. sh C' = \(sfs,Processing)\; \sfs. sh C = \(sfs, Processing)\ \ (sh C = \(sfs, Error)\ \ e = THROW NoClassDefFoundError); distinct (C#Cs); supercls_lst P (C#Cs) \ \ P,E,h,sh \ RI(C, e);Cs \ e' :' T'" (*<*) lemmas WTrt'_induct = WTrt'_WTrts'.induct [split_format (complete)] and WTrt'_inducts = WTrt'_WTrts'.inducts [split_format (complete)] inductive_cases WTrt'_elim_cases[elim!]: "P,E,h,sh \ V :=e :' T" (*>*) lemma [iff]: "P,E,h,sh \ e\<^sub>1;;e\<^sub>2 :' T\<^sub>2 = (\T\<^sub>1. P,E,h,sh \ e\<^sub>1:' T\<^sub>1 \ P,E,h,sh \ e\<^sub>2:' T\<^sub>2)" -(*<*) -apply(rule iffI) -apply (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros) -done -(*>*) +(*<*)by(rule iffI) (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros)(*>*) lemma [iff]: "P,E,h,sh \ Val v :' T = (typeof\<^bsub>h\<^esub> v = Some T)" -(*<*) -apply(rule iffI) -apply (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros) -done -(*>*) +(*<*)by(rule iffI) (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros)(*>*) lemma [iff]: "P,E,h,sh \ Var v :' T = (E v = Some T)" -(*<*) -apply(rule iffI) -apply (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros) -done -(*>*) +(*<*)by(rule iffI) (auto elim: WTrt'.cases intro!:WTrt'_WTrts'.intros)(*>*) lemma wt_wt': "P,E,h,sh \ e : T \ P,E,h,sh \ e :' T" and wts_wts': "P,E,h,sh \ es [:] Ts \ P,E,h,sh \ es [:'] Ts" (*<*) -apply (induct rule:WTrt_inducts) -prefer 17 -apply(case_tac "assigned V e") -apply(clarsimp simp add:fun_upd_same assigned_def simp del:fun_upd_apply) -apply(erule (2) WTrt'_WTrts'.intros) -apply(erule (1) WTrt'_WTrts'.intros) -apply(blast intro:WTrt'_WTrts'.intros)+ -done +proof(induct rule:WTrt_inducts) + case (WTrtBlock E V T e T') + then show ?case + proof(cases "assigned V e") + case True then show ?thesis using WTrtBlock.hyps(2) + by(clarsimp simp add:fun_upd_same assigned_def WTrt'_WTrts'.intros + simp del:fun_upd_apply) + next + case False then show ?thesis + by (simp add: WTrtBlock.hyps(2) WTrt'_WTrts'.intros) + qed +qed (blast intro:WTrt'_WTrts'.intros)+ (*>*) lemma wt'_wt: "P,E,h,sh \ e :' T \ P,E,h,sh \ e : T" and wts'_wts: "P,E,h,sh \ es [:'] Ts \ P,E,h,sh \ es [:] Ts" (*<*) -apply (induct rule:WTrt'_inducts) -prefer 19 -apply(rule WTrt_WTrts.intros) -apply(rule WTrt_WTrts.intros) -apply(rule WTrt_WTrts.intros) -apply simp -apply(erule (2) WTrt_WTrts.intros) -apply(blast intro:WTrt_WTrts.intros)+ -done +proof(induct rule:WTrt'_inducts) + case Block: (19 v T\<^sub>1 T E V e\<^sub>2 T\<^sub>2) + let ?E = "E(V \ T)" + have "P,?E,h,sh \ Val v : T\<^sub>1" using Block.hyps(1) by simp + moreover have "P \ T\<^sub>1 \ T" by(rule Block.hyps(2)) + ultimately have "P,?E,h,sh \ V:=Val v : Void" using WTrtLAss by simp + moreover have "P,?E,h,sh \ e\<^sub>2 : T\<^sub>2" by(rule Block.hyps(4)) + ultimately have "P,?E,h,sh \ V:=Val v;; e\<^sub>2 : T\<^sub>2" by blast + then show ?case by simp +qed (blast intro:WTrt_WTrts.intros)+ (*>*) corollary wt'_iff_wt: "(P,E,h,sh \ e :' T) = (P,E,h,sh \ e : T)" (*<*)by(blast intro:wt_wt' wt'_wt)(*>*) corollary wts'_iff_wts: "(P,E,h,sh \ es [:'] Ts) = (P,E,h,sh \ es [:] Ts)" (*<*)by(blast intro:wts_wts' wts'_wts)(*>*) (*<*) lemmas WTrt_inducts2 = WTrt'_inducts [unfolded wt'_iff_wt wts'_iff_wts, case_names WTrtNew WTrtCast WTrtVal WTrtVar WTrtBinOpEq WTrtBinOpAdd WTrtLAss WTrtFAcc WTrtFAccNT WTrtSFAcc WTrtFAss WTrtFAssNT WTrtSFAss WTrtCall WTrtCallNT WTrtSCall WTrtNil WTrtCons WTrtInitBlock WTrtBlock WTrtSeq WTrtCond WTrtWhile WTrtThrow WTrtTry WTrtInit WTrtRI, consumes 1] (*>*) theorem assumes wf: "wwf_J_prog P" and hconf: "P \ h \" and shconf: "P,h \\<^sub>s sh \" shows progress: "P,E,h,sh \ e : T \ (\l. \ \ e \dom l\; P,sh \\<^sub>b (e,b) \; \ final e \ \ \e' s' b'. P \ \e,(h,l,sh),b\ \ \e',s',b'\)" and "P,E,h,sh \ es [:] Ts \ (\l. \ \s es \dom l\; P,sh \\<^sub>b (es,b) \; \ finals es \ \ \es' s' b'. P \ \es,(h,l,sh),b\ [\] \es',s',b'\)" (*<*) proof (induct rule:WTrt_inducts2) case (WTrtNew C) show ?case proof (cases b) case True then show ?thesis proof cases assume "\a. h a = None" with assms WTrtNew True show ?thesis by (fastforce del:exE intro!:RedNew simp add:new_Addr_def elim!:wf_Fields_Ex[THEN exE]) next assume "\(\a. h a = None)" with assms WTrtNew True show ?thesis by(fastforce intro:RedNewFail simp:new_Addr_def) qed next case False then show ?thesis proof cases assume "\sfs. sh C = Some (sfs, Done)" with assms WTrtNew False show ?thesis by(fastforce intro:NewInitDoneRed simp:new_Addr_def) next assume "\sfs. sh C = Some (sfs, Done)" with assms WTrtNew False show ?thesis by(fastforce intro:NewInitRed simp:new_Addr_def) qed qed next case (WTrtCast E e T C) have wte: "P,E,h,sh \ e : T" and ref: "is_refT T" and IH: "\l. \\ e \dom l\; P,sh \\<^sub>b (e,b) \; \ final e\ \ \e' s' b'. P \ \e,(h,l,sh),b\ \ \e',s',b'\" and D: "\ (Cast C e) \dom l\" and castconf: "P,sh \\<^sub>b (Cast C e,b) \" by fact+ from D have De: "\ e \dom l\" by auto have bconf: "P,sh \\<^sub>b (e,b) \" using castconf bconf_Cast by fast show ?case proof cases assume "final e" with wte ref show ?thesis proof (rule finalRefE) assume "e = null" thus ?case by(fastforce intro:RedCastNull) next fix D a assume A: "T = Class D" "e = addr a" show ?thesis proof cases assume "P \ D \\<^sup>* C" thus ?thesis using A wte by(fastforce intro:RedCast) next assume "\ P \ D \\<^sup>* C" thus ?thesis using A wte by(fastforce elim!:RedCastFail) qed next fix a assume "e = Throw a" thus ?thesis by(blast intro!:red_reds.CastThrow) qed next assume nf: "\ final e" from IH[OF De bconf nf] show ?thesis by (blast intro:CastRed) qed next case WTrtVal thus ?case by(simp add:final_def) next case WTrtVar thus ?case by(fastforce intro:RedVar simp:hyper_isin_def) next case (WTrtBinOpEq E e1 T1 e2 T2) show ?case proof cases assume "final e1" thus ?thesis proof (rule finalE) fix v1 assume eV[simp]: "e1 = Val v1" show ?thesis proof cases assume "final e2" thus ?thesis proof (rule finalE) fix v2 assume "e2 = Val v2" thus ?thesis using WTrtBinOpEq by(fastforce intro:RedBinOp) next fix a assume "e2 = Throw a" thus ?thesis using eV by(blast intro:red_reds.BinOpThrow2) qed next assume nf: "\ final e2" then have "P,sh \\<^sub>b (e2,b) \" using WTrtBinOpEq.prems(2) by(simp add:bconf_BinOp) with WTrtBinOpEq nf show ?thesis by simp (fast intro!:BinOpRed2) qed next fix a assume "e1 = Throw a" thus ?thesis by (fast intro:red_reds.BinOpThrow1) qed next assume nf: "\ final e1" then have e1: "val_of e1 = None" proof(cases e1)qed(auto) then have "P,sh \\<^sub>b (e1,b) \" using WTrtBinOpEq.prems(2) by(simp add:bconf_BinOp) with WTrtBinOpEq nf e1 show ?thesis by simp (fast intro:BinOpRed1) qed next case (WTrtBinOpAdd E e1 e2) show ?case proof cases assume "final e1" thus ?thesis proof (rule finalE) fix v1 assume eV[simp]: "e1 = Val v1" show ?thesis proof cases assume "final e2" thus ?thesis proof (rule finalE) fix v2 assume eV2:"e2 = Val v2" then obtain i1 i2 where "v1 = Intg i1 \ v2 = Intg i2" using WTrtBinOpAdd by clarsimp thus ?thesis using WTrtBinOpAdd eV eV2 by(fastforce intro:RedBinOp) next fix a assume "e2 = Throw a" thus ?thesis using eV by(blast intro:red_reds.BinOpThrow2) qed next assume nf:"\ final e2" then have "P,sh \\<^sub>b (e2,b) \" using WTrtBinOpAdd.prems(2) by(simp add:bconf_BinOp) with WTrtBinOpAdd nf show ?thesis by simp (fast intro!:BinOpRed2) qed next fix a assume "e1 = Throw a" thus ?thesis by(fast intro:red_reds.BinOpThrow1) qed next assume nf: "\ final e1" then have e1: "val_of e1 = None" proof(cases e1)qed(auto) then have "P,sh \\<^sub>b (e1,b) \" using WTrtBinOpAdd.prems(2) by(simp add:bconf_BinOp) with WTrtBinOpAdd nf e1 show ?thesis by simp (fast intro:BinOpRed1) qed next case (WTrtLAss E V T e T') then have bconf: "P,sh \\<^sub>b (e,b) \" using bconf_LAss by fast show ?case proof cases assume "final e" with WTrtLAss show ?thesis by(fastforce simp:final_def intro: red_reds.RedLAss red_reds.LAssThrow) next assume "\ final e" with WTrtLAss bconf show ?thesis by simp (fast intro:LAssRed) qed next case (WTrtFAcc E e C F T D) then have bconf: "P,sh \\<^sub>b (e,b) \" using bconf_FAcc by fast have wte: "P,E,h,sh \ e : Class C" and field: "P \ C has F,NonStatic:T in D" by fact+ show ?case proof cases assume "final e" with wte show ?thesis proof (rule final_addrE) fix a assume e: "e = addr a" with wte obtain fs where hp: "h a = Some(C,fs)" by auto with hconf have "P,h \ (C,fs) \" using hconf_def by fastforce then obtain v where "fs(F,D) = Some v" using field by(fastforce dest:has_fields_fun simp:oconf_def has_field_def) with hp e show ?thesis by (meson field red_reds.RedFAcc) next fix a assume "e = Throw a" thus ?thesis by(fastforce intro:red_reds.FAccThrow) qed next assume "\ final e" with WTrtFAcc bconf show ?thesis by(fastforce intro!:FAccRed) qed next case (WTrtFAccNT E e F D T) then have bconf: "P,sh \\<^sub>b (e,b) \" using bconf_FAcc by fast show ?case proof cases assume "final e" \ \@{term e} is @{term null} or @{term throw}\ with WTrtFAccNT show ?thesis by(fastforce simp:final_def intro: red_reds.RedFAccNull red_reds.FAccThrow) next assume "\ final e" \ \@{term e} reduces by IH\ with WTrtFAccNT bconf show ?thesis by simp (fast intro:FAccRed) qed next case (WTrtSFAcc C F T D E) then show ?case proof (cases b) case True then obtain sfs i where shD: "sh D = \(sfs,i)\" using bconf_def[of P sh "C\\<^sub>sF{D}" b] WTrtSFAcc.prems(2) initPD_def by auto with shconf have "P,h,D \\<^sub>s sfs \" using shconf_def[of P h sh] by auto then obtain v where sfsF: "sfs F = Some v" using WTrtSFAcc.hyps by(unfold soconf_def) (auto dest:has_field_idemp) then show ?thesis using WTrtSFAcc.hyps shD sfsF True by(fastforce elim:RedSFAcc) next case False with assms WTrtSFAcc show ?thesis by(metis (full_types) SFAccInitDoneRed SFAccInitRed) qed next case (WTrtFAss E e1 C F T D e2 T2) have wte1: "P,E,h,sh \ e1 : Class C" and field: "P \ C has F,NonStatic:T in D" by fact+ show ?case proof cases assume "final e1" with wte1 show ?thesis proof (rule final_addrE) fix a assume e1: "e1 = addr a" show ?thesis proof cases assume "final e2" thus ?thesis proof (rule finalE) fix v assume "e2 = Val v" thus ?thesis using e1 wte1 by(fastforce intro: RedFAss[OF field]) next fix a assume "e2 = Throw a" thus ?thesis using e1 by(fastforce intro:red_reds.FAssThrow2) qed next assume nf: "\ final e2" then have "P,sh \\<^sub>b (e2,b) \" using WTrtFAss.prems(2) e1 by(simp add:bconf_FAss) with WTrtFAss e1 nf show ?thesis by simp (fast intro!:FAssRed2) qed next fix a assume "e1 = Throw a" thus ?thesis by(fastforce intro:red_reds.FAssThrow1) qed next assume nf: "\ final e1" then have e1: "val_of e1 = None" proof(cases e1)qed(auto) then have "P,sh \\<^sub>b (e1,b) \" using WTrtFAss.prems(2) by(simp add:bconf_FAss) with WTrtFAss nf e1 show ?thesis by simp (blast intro!:FAssRed1) qed next case (WTrtFAssNT E e\<^sub>1 e\<^sub>2 T\<^sub>2 F D) show ?case proof cases assume e1: "final e\<^sub>1" \ \@{term e\<^sub>1} is @{term null} or @{term throw}\ show ?thesis proof cases assume "final e\<^sub>2" \ \@{term e\<^sub>2} is @{term Val} or @{term throw}\ with WTrtFAssNT e1 show ?thesis by(fastforce simp:final_def intro: red_reds.RedFAssNull red_reds.FAssThrow1 red_reds.FAssThrow2) next assume nf: "\ final e\<^sub>2" \ \@{term e\<^sub>2} reduces by IH\ show ?thesis proof (rule finalE[OF e1]) fix v assume ev: "e\<^sub>1 = Val v" then have "P,sh \\<^sub>b (e\<^sub>2,b) \" using WTrtFAssNT.prems(2) nf by(simp add:bconf_FAss) with WTrtFAssNT ev nf show ?thesis by auto (meson red_reds.FAssRed2) next fix a assume et: "e\<^sub>1 = Throw a" then have "P,sh \\<^sub>b (e\<^sub>1,b) \" using WTrtFAssNT.prems(2) nf by(simp add:bconf_FAss) with WTrtFAssNT et nf show ?thesis by(fastforce intro: red_reds.FAssThrow1) qed qed next assume nf: "\ final e\<^sub>1" \ \@{term e\<^sub>1} reduces by IH\ then have e1: "val_of e\<^sub>1 = None" proof(cases e\<^sub>1)qed(auto) then have "P,sh \\<^sub>b (e\<^sub>1,b) \" using WTrtFAssNT.prems(2) by(simp add:bconf_FAss) with WTrtFAssNT nf e1 show ?thesis by simp (blast intro!:FAssRed1) qed next case (WTrtSFAss C F T D E e2 T\<^sub>2) have field: "P \ C has F,Static:T in D" by fact+ show ?case proof cases assume "final e2" thus ?thesis proof (rule finalE) fix v assume ev: "e2 = Val v" then show ?case proof (cases b) case True then obtain sfs i where shD: "sh D = \(sfs,i)\" using bconf_def[of P _ "C\\<^sub>sF{D} := e2"] WTrtSFAss.prems(2) initPD_def ev by auto with shconf have "P,h,D \\<^sub>s sfs \" using shconf_def[of P] by auto then obtain v where sfsF: "sfs F = Some v" using field by(unfold soconf_def) (auto dest:has_field_idemp) then show ?thesis using WTrtSFAss.hyps shD sfsF True ev by(fastforce elim:RedSFAss) next case False with assms WTrtSFAss ev show ?thesis by(metis (full_types) SFAssInitDoneRed SFAssInitRed) qed next fix a assume "e2 = Throw a" thus ?thesis by(fastforce intro:red_reds.SFAssThrow) qed next assume nf: "\ final e2" then have "val_of e2 = None" using final_def val_of_spec by fastforce then have "P,sh \\<^sub>b (e2,b) \" using WTrtSFAss.prems(2) by(simp add:bconf_SFAss) with WTrtSFAss nf show ?thesis by simp (fast intro!:SFAssRed) qed next case (WTrtCall E e C M Ts T pns body D es Ts') have wte: "P,E,h,sh \ e : Class C" and "method": "P \ C sees M,NonStatic:Ts\T = (pns,body) in D" and wtes: "P,E,h,sh \ es [:] Ts'"and sub: "P \ Ts' [\] Ts" and IHes: "\l. \\s es \dom l\; P,sh \\<^sub>b (es,b) \; \ finals es\ \ \es' s' b'. P \ \es,(h,l,sh),b\ [\] \es',s',b'\" and D: "\ (e\M(es)) \dom l\" by fact+ show ?case proof cases assume "final e" with wte show ?thesis proof (rule final_addrE) fix a assume e_addr: "e = addr a" show ?thesis proof cases assume es: "\vs. es = map Val vs" from wte e_addr obtain fs where ha: "h a = Some(C,fs)" by auto show ?thesis using e_addr ha "method" WTrts_same_length[OF wtes] sub es sees_wf_mdecl[OF wf "method"] by(fastforce intro!: RedCall simp:list_all2_iff wf_mdecl_def) next assume "\(\vs. es = map Val vs)" hence not_all_Val: "\(\e \ set es. \v. e = Val v)" by(simp add:ex_map_conv) let ?ves = "takeWhile (\e. \v. e = Val v) es" let ?rest = "dropWhile (\e. \v. e = Val v) es" let ?ex = "hd ?rest" let ?rst = "tl ?rest" from not_all_Val have nonempty: "?rest \ []" by auto hence es: "es = ?ves @ ?ex # ?rst" by simp have "\e \ set ?ves. \v. e = Val v" by(fastforce dest:set_takeWhileD) then obtain vs where ves: "?ves = map Val vs" using ex_map_conv by blast show ?thesis proof cases assume "final ?ex" moreover from nonempty have "\(\v. ?ex = Val v)" by(auto simp:neq_Nil_conv simp del:dropWhile_eq_Nil_conv) (simp add:dropWhile_eq_Cons_conv) ultimately obtain b where ex_Throw: "?ex = Throw b" by(fast elim!:finalE) show ?thesis using e_addr es ex_Throw ves by(fastforce intro:CallThrowParams) next assume not_fin: "\ final ?ex" have "finals es = finals(?ves @ ?ex # ?rst)" using es by(rule arg_cong) also have "\ = finals(?ex # ?rst)" using ves by simp finally have "finals es = finals(?ex # ?rst)" . hence fes: "\ finals es" using not_finals_ConsI[OF not_fin] by blast have "P,sh \\<^sub>b (es,b) \" using bconf_Call WTrtCall.prems(2) by (metis e_addr option.simps(5) val_of.simps(1)) thus ?thesis using fes e_addr D IHes by(fastforce intro!:CallParams) qed qed next fix a assume "e = Throw a" with WTrtCall.prems show ?thesis by(fast intro!:CallThrowObj) qed next assume nf: "\ final e" then have e1: "val_of e = None" proof(cases e)qed(auto) then have "P,sh \\<^sub>b (e,b) \" using WTrtCall.prems(2) by(simp add:bconf_Call) with WTrtCall nf e1 show ?thesis by simp (blast intro!:CallObj) qed next case (WTrtCallNT E e es Ts M T) show ?case proof cases assume "final e" moreover { fix v assume e: "e = Val v" hence "e = null" using WTrtCallNT by simp have ?case proof cases assume "finals es" moreover { fix vs assume "es = map Val vs" with WTrtCallNT e have ?thesis by(fastforce intro: RedCallNull) } moreover { fix vs a es' assume "es = map Val vs @ Throw a # es'" with WTrtCallNT e have ?thesis by(fastforce intro: CallThrowParams) } ultimately show ?thesis by(fastforce simp:finals_def) next assume nf: "\ finals es" \ \@{term es} reduces by IH\ have "P,sh \\<^sub>b (es,b) \" using WTrtCallNT.prems(2) e by (simp add: bconf_Call) with WTrtCallNT e nf show ?thesis by(fastforce intro: CallParams) qed } moreover { fix a assume "e = Throw a" with WTrtCallNT have ?case by(fastforce intro: CallThrowObj) } ultimately show ?thesis by(fastforce simp:final_def) next assume nf: "\ final e" \ \@{term e} reduces by IH\ then have "val_of e = None" proof(cases e)qed(auto) then have "P,sh \\<^sub>b (e,b) \" using WTrtCallNT.prems(2) by(simp add:bconf_Call) with WTrtCallNT nf show ?thesis by (fastforce intro:CallObj) qed next case (WTrtSCall C M Ts T pns body D E es Ts' sfs vs) have "method": "P \ C sees M,Static:Ts\T = (pns,body) in D" and wtes: "P,E,h,sh \ es [:] Ts'"and sub: "P \ Ts' [\] Ts" and IHes: "\l. \\s es \dom l\; P,sh \\<^sub>b (es,b) \; \ finals es\ \ \es' s' b'. P \ \es,(h,l,sh),b\ [\] \es',s',b'\" and clinit: "M = clinit \ sh D = \(sfs, Processing)\ \ es = map Val vs" and D: "\ (C\\<^sub>sM(es)) \dom l\" by fact+ show ?case proof cases assume es: "\vs. es = map Val vs" show ?thesis proof (cases b) case True then show ?thesis using "method" WTrts_same_length[OF wtes] sub es sees_wf_mdecl[OF wf "method"] True by(fastforce intro!: RedSCall simp:list_all2_iff wf_mdecl_def) next case False show ?thesis using "method" clinit WTrts_same_length[OF wtes] sub es False by (metis (full_types) red_reds.SCallInitDoneRed red_reds.SCallInitRed) qed next assume nmap: "\(\vs. es = map Val vs)" hence not_all_Val: "\(\e \ set es. \v. e = Val v)" by(simp add:ex_map_conv) let ?ves = "takeWhile (\e. \v. e = Val v) es" let ?rest = "dropWhile (\e. \v. e = Val v) es" let ?ex = "hd ?rest" let ?rst = "tl ?rest" from not_all_Val have nonempty: "?rest \ []" by auto hence es: "es = ?ves @ ?ex # ?rst" by simp have "\e \ set ?ves. \v. e = Val v" by(fastforce dest:set_takeWhileD) then obtain vs where ves: "?ves = map Val vs" using ex_map_conv by blast show ?thesis proof cases assume "final ?ex" moreover from nonempty have "\(\v. ?ex = Val v)" by(auto simp:neq_Nil_conv simp del:dropWhile_eq_Nil_conv) (simp add:dropWhile_eq_Cons_conv) ultimately obtain b where ex_Throw: "?ex = Throw b" by(fast elim!:finalE) show ?thesis using es ex_Throw ves by(fastforce intro:SCallThrowParams) next assume not_fin: "\ final ?ex" have "finals es = finals(?ves @ ?ex # ?rst)" using es by(rule arg_cong) also have "\ = finals(?ex # ?rst)" using ves by simp finally have "finals es = finals(?ex # ?rst)" . hence fes: "\ finals es" using not_finals_ConsI[OF not_fin] by blast have "P,sh \\<^sub>b (es,b) \" by (meson WTrtSCall.prems(2) nmap bconf_SCall map_vals_of_spec not_None_eq) thus ?thesis using fes D IHes by(fastforce intro!:SCallParams) qed qed next case WTrtNil thus ?case by simp next case (WTrtCons E e T es Ts) have IHe: "\l. \\ e \dom l\; P,sh \\<^sub>b (e,b) \; \ final e\ \ \e' s' b'. P \ \e,(h,l,sh),b\ \ \e',s',b'\" and IHes: "\l. \\s es \dom l\; P,sh \\<^sub>b (es,b) \; \ finals es\ \ \es' s' b'. P \ \es,(h,l,sh),b\ [\] \es',s',b'\" and D: "\s (e#es) \dom l\" and not_fins: "\ finals(e # es)" by fact+ have De: "\ e \dom l\" and Des: "\s es (\dom l\ \ \ e)" using D by auto show ?case proof cases assume "final e" thus ?thesis proof (rule finalE) fix v assume e: "e = Val v" hence Des': "\s es \dom l\" using De Des by auto have bconfs: "P,sh \\<^sub>b (es,b) \" using WTrtCons.prems(2) e by(simp add: bconf_Cons) have not_fins_tl: "\ finals es" using not_fins e by simp show ?thesis using e IHes[OF Des' bconfs not_fins_tl] by (blast intro!:ListRed2) next fix a assume "e = Throw a" hence False using not_fins by simp thus ?thesis .. qed next assume nf:"\ final e" then have "val_of e = None" proof(cases e)qed(auto) then have bconf: "P,sh \\<^sub>b (e,b) \" using WTrtCons.prems(2) by(simp add: bconf_Cons) with IHe[OF De bconf nf] show ?thesis by(fast intro!:ListRed1) qed next case (WTrtInitBlock v T\<^sub>1 T E V e\<^sub>2 T\<^sub>2) have IH2: "\l. \\ e\<^sub>2 \dom l\; P,sh \\<^sub>b (e\<^sub>2,b) \; \ final e\<^sub>2\ \ \e' s' b'. P \ \e\<^sub>2,(h,l,sh),b\ \ \e',s',b'\" and D: "\ {V:T := Val v; e\<^sub>2} \dom l\" by fact+ show ?case proof cases assume "final e\<^sub>2" then show ?thesis proof (rule finalE) fix v\<^sub>2 assume "e\<^sub>2 = Val v\<^sub>2" thus ?thesis by(fast intro:RedInitBlock) next fix a assume "e\<^sub>2 = Throw a" thus ?thesis by(fast intro:red_reds.InitBlockThrow) qed next assume not_fin2: "\ final e\<^sub>2" then have "val_of e\<^sub>2 = None" proof(cases e\<^sub>2)qed(auto) from D have D2: "\ e\<^sub>2 \dom(l(V\v))\" by (auto simp:hyperset_defs) have e2conf: "P,sh \\<^sub>b (e\<^sub>2,b) \" using WTrtInitBlock.prems(2) by(simp add: bconf_InitBlock) from IH2[OF D2 e2conf not_fin2] obtain h' l' sh' e' b' where red2: "P \ \e\<^sub>2,(h, l(V\v),sh),b\ \ \e',(h', l',sh'),b'\" by auto from red_lcl_incr[OF red2] have "V \ dom l'" by auto with red2 show ?thesis by(fastforce intro:InitBlockRed) qed next case (WTrtBlock E V T e T') have IH: "\l. \\ e \dom l\; P,sh \\<^sub>b (e,b) \; \ final e\ \ \e' s' b'. P \ \e,(h,l,sh),b\ \ \e',s',b'\" and unass: "\ assigned V e" and D: "\ {V:T; e} \dom l\" by fact+ show ?case proof cases assume "final e" thus ?thesis proof (rule finalE) fix v assume "e = Val v" thus ?thesis by(fast intro:RedBlock) next fix a assume "e = Throw a" thus ?thesis by(fast intro:red_reds.BlockThrow) qed next assume not_fin: "\ final e" then have "val_of e = None" proof(cases e)qed(auto) from D have De: "\ e \dom(l(V:=None))\" by(simp add:hyperset_defs) have bconf: "P,sh \\<^sub>b (e,b) \" using WTrtBlock by(simp add: bconf_Block) from IH[OF De bconf not_fin] obtain h' l' sh' e' b' where red: "P \ \e,(h,l(V:=None),sh),b\ \ \e',(h',l',sh'),b'\" by auto show ?thesis proof (cases "l' V") assume "l' V = None" with red unass show ?thesis by(blast intro: BlockRedNone) next fix v assume "l' V = Some v" with red unass show ?thesis by(blast intro: BlockRedSome) qed qed next case (WTrtSeq E e1 T1 e2 T2) show ?case proof cases assume "final e1" thus ?thesis by(fast elim:finalE intro:RedSeq red_reds.SeqThrow) next assume nf: "\ final e1" then have e1: "val_of e1 = None" proof(cases e1)qed(auto) then show ?thesis proof(cases "lass_val_of e1") case None then have "P,sh \\<^sub>b (e1,b) \" using WTrtSeq.prems(2) e1 by(simp add: bconf_Seq) with WTrtSeq nf e1 None show ?thesis by simp (blast intro:SeqRed) next case (Some p) obtain V v where "e1 = V:=Val v" using lass_val_of_spec[OF Some] by simp then show ?thesis using SeqRed[OF RedLAss] by blast qed qed next case (WTrtCond E e e\<^sub>1 T\<^sub>1 e\<^sub>2 T\<^sub>2 T) have wt: "P,E,h,sh \ e : Boolean" by fact show ?case proof cases assume "final e" thus ?thesis proof (rule finalE) fix v assume val: "e = Val v" then obtain b where v: "v = Bool b" using wt by auto show ?thesis proof (cases b) case True with val v show ?thesis by(fastforce intro:RedCondT simp: prod_cases3) next case False with val v show ?thesis by(fastforce intro:RedCondF simp: prod_cases3) qed next fix a assume "e = Throw a" thus ?thesis by(fast intro:red_reds.CondThrow) qed next assume nf: "\ final e" then have "bool_of e = None" proof(cases e)qed(auto) then have "P,sh \\<^sub>b (e,b) \" using WTrtCond.prems(2) by(simp add: bconf_Cond) with WTrtCond nf show ?thesis by simp (blast intro:CondRed) qed next case WTrtWhile show ?case by(fast intro:RedWhile) next case (WTrtThrow E e T\<^sub>r T) show ?case proof cases assume "final e" \ \Then @{term e} must be @{term throw} or @{term null}\ with WTrtThrow show ?thesis by(fastforce simp:final_def is_refT_def intro:red_reds.ThrowThrow red_reds.RedThrowNull) next assume nf: "\ final e" \ \Then @{term e} must reduce\ then have "val_of e = None" proof(cases e)qed(auto) then have "P,sh \\<^sub>b (e,b) \" using WTrtThrow.prems(2) by(simp add: bconf_Throw) with WTrtThrow nf show ?thesis by simp (blast intro:ThrowRed) qed next case (WTrtTry E e1 T1 V C e2 T2) have wt1: "P,E,h,sh \ e1 : T1" by fact show ?case proof cases assume "final e1" thus ?thesis proof (rule finalE) fix v assume "e1 = Val v" thus ?thesis by(fast intro:RedTry) next fix a assume e1_Throw: "e1 = Throw a" with wt1 obtain D fs where ha: "h a = Some(D,fs)" by fastforce show ?thesis proof cases assume "P \ D \\<^sup>* C" with e1_Throw ha show ?thesis by(fastforce intro!:RedTryCatch) next assume "\ P \ D \\<^sup>* C" with e1_Throw ha show ?thesis by(fastforce intro!:RedTryFail) qed qed next assume nf: "\ final e1" then have "val_of e1 = None" proof(cases e1)qed(auto) then have "P,sh \\<^sub>b (e1,b) \" using WTrtTry.prems(2) by(simp add: bconf_Try) with WTrtTry nf show ?thesis by simp (fast intro:TryRed) qed next case (WTrtInit E e T\<^sub>r C Cs b) show ?case proof(cases Cs) case Nil then show ?thesis using WTrtInit by(fastforce intro!: RedInit) next case (Cons C' Cs') show ?thesis proof(cases b) case True then show ?thesis using Cons by(fastforce intro!: RedInitRInit) next case False show ?thesis proof(cases "sh C'") case None then show ?thesis using False Cons by(fastforce intro!: InitNoneRed) next case (Some sfsi) then obtain sfs i where sfsi:"sfsi = (sfs,i)" by(cases sfsi) show ?thesis proof(cases i) case Done then show ?thesis using False Some sfsi Cons by(fastforce intro!: RedInitDone) next case Processing then show ?thesis using False Some sfsi Cons by(fastforce intro!: RedInitProcessing) next case Error then show ?thesis using False Some sfsi Cons by(fastforce intro!: RedInitError) next case Prepared show ?thesis proof cases assume "C' = Object" then show ?thesis using False Some sfsi Prepared Cons by(fastforce intro: InitObjectRed) next assume "C' \ Object" then show ?thesis using False Some sfsi Prepared WTrtInit.hyps(3) Cons by(simp only: is_class_def)(fastforce intro!: InitNonObjectSuperRed) qed qed qed qed qed next case (WTrtRI E e T\<^sub>r e' T\<^sub>r' C Cs) obtain sfs i where shC: "sh C = \(sfs, i)\" using WTrtRI.hyps(9) by blast show ?case proof cases assume fin: "final e" then show ?thesis proof (rule finalE) fix v assume e: "e = Val v" then show ?thesis using shC e by(fast intro:RedRInit) next fix a assume eThrow: "e = Throw a" show ?thesis proof(cases Cs) case Nil then show ?thesis using eThrow shC by(fastforce intro!: RInitThrow) next case Cons then show ?thesis using eThrow shC by(fastforce intro!: RInitInitThrow) qed qed next assume nf: "\ final e" then have "val_of e = None" proof(cases e)qed(auto) then have "P,sh \\<^sub>b (e,b) \" using WTrtRI.prems(2) by(simp add: bconf_RI) with WTrtRI nf show ?thesis by simp (meson red_reds.RInitRed) qed qed (*>*) end