(* Title: Jinja/Compiler/J1.thy ID: $Id: J1.html 1910 2004-05-19 04:46:04Z kleing $ Author: Tobias Nipkow Copyright 2003 Technische Universitaet Muenchen *) header {* \chapter{Compilation}\label{cha:comp} \isaheader{An Intermediate Language} *} theory J1 = BigStep: types expr1 = "nat exp" J1_prog = "expr1 prog" state1 = "heap × (val list)" consts max_vars:: "'a exp => nat" max_varss:: "'a exp list => nat" primrec "max_vars(new C) = 0" "max_vars(Cast C e) = max_vars e" "max_vars(Val v) = 0" "max_vars(e1 «bop» e2) = max (max_vars e1) (max_vars e2)" "max_vars(Var V) = 0" "max_vars(V:=e) = max_vars e" "max_vars(e\<bullet>F{D}) = max_vars e" "max_vars(FAss e1 F D e2) = max (max_vars e1) (max_vars e2)" "max_vars(e\<bullet>M(es)) = max (max_vars e) (max_varss es)" "max_vars({V:T; e}) = max_vars e + 1" "max_vars(e1;;e2) = max (max_vars e1) (max_vars e2)" "max_vars(if (e) e1 else e2) = max (max_vars e) (max (max_vars e1) (max_vars e2))" "max_vars(while (b) e) = max (max_vars b) (max_vars e)" "max_vars(throw e) = max_vars e" "max_vars(try e1 catch(C V) e2) = max (max_vars e1) (max_vars e2 + 1)" "max_varss [] = 0" "max_varss (e#es) = max (max_vars e) (max_varss es)" consts eval1 :: "J1_prog => ((expr1 × state1) × (expr1 × state1)) set" evals1 :: "J1_prog => ((expr1 list × state1) × (expr1 list × state1)) set" (*<*) syntax (xsymbols) eval1 :: "J1_prog => expr => state1 => nat => expr => state1 => bool" ("_ \<turnstile>1 ((1〈_,/_〉) =>/ (1〈_,/_〉))" [51,0,0,0,0] 81) evals1 :: "J1_prog => expr list => state1 => nat => expr list => state1 => bool" ("_ \<turnstile>1 ((1〈_,/_〉) [=>]/ (1〈_,/_〉))" [51,0,0,0,0] 81) (*>*) translations "P \<turnstile>1 〈e,s〉 => 〈e',s'〉" == "((e,s), e',s') ∈ eval1 P" "P \<turnstile>1 〈e,s〉 [=>] 〈e',s'〉" == "((e,s), e',s') ∈ evals1 P" (*<*) "P \<turnstile>1 〈e,(h,l)〉 => 〈e',(h',l')〉" <= "((e,h,l), e',h',l') ∈ eval1 P" "P \<turnstile>1 〈e,s〉 => 〈e',(h',l')〉" <= "((e,s), e',h',l') ∈ eval1 P" "P \<turnstile>1 〈e,(h,l)〉 => 〈e',s'〉" <= "((e,h,l), e',s') ∈ eval1 P" "P \<turnstile>1 〈e,(h,l)〉 [=>] 〈e',(h',l')〉" <= "((e,h,l), e',h',l') ∈ evals1 P" "P \<turnstile>1 〈e,s〉 [=>] 〈e',(h',l')〉" <= "((e,s), e',h',l') ∈ evals1 P" "P \<turnstile>1 〈e,(h,l)〉 [=>] 〈e',s'〉" <= "((e,h,l), e',s') ∈ evals1 P" (*>*) inductive "eval1 P" "evals1 P" intros New1: "[| new_Addr h = Some a; P \<turnstile> C has_fields FDTs; h' = h(a\<mapsto>(C,init_fields FDTs)) |] ==> P \<turnstile>1 〈new C,(h,l)〉 => 〈addr a,(h',l)〉" NewFail1: "new_Addr h = None ==> P \<turnstile>1 〈new C, (h,l)〉 => 〈THROW OutOfMemory,(h,l)〉" Cast1: "[| P \<turnstile>1 〈e,s0〉 => 〈addr a,(h,l)〉; h a = Some(D,fs); P \<turnstile> D \<preceq>* C |] ==> P \<turnstile>1 〈Cast C e,s0〉 => 〈addr a,(h,l)〉" CastNull1: "P \<turnstile>1 〈e,s0〉 => 〈null,s1〉 ==> P \<turnstile>1 〈Cast C e,s0〉 => 〈null,s1〉" CastFail1: "[| P \<turnstile>1 〈e,s0〉 => 〈addr a,(h,l)〉; h a = Some(D,fs); ¬ P \<turnstile> D \<preceq>* C |] ==> P \<turnstile>1 〈Cast C e,s0〉 => 〈THROW ClassCast,(h,l)〉" CastThrow1: "P \<turnstile>1 〈e,s0〉 => 〈throw e',s1〉 ==> P \<turnstile>1 〈Cast C e,s0〉 => 〈throw e',s1〉" Val1: "P \<turnstile>1 〈Val v,s〉 => 〈Val v,s〉" BinOp1: "[| P \<turnstile>1 〈e1,s0〉 => 〈Val v1,s1〉; P \<turnstile>1 〈e2,s1〉 => 〈Val v2,s2〉; binop(bop,v1,v2) = Some v |] ==> P \<turnstile>1 〈e1 «bop» e2,s0〉 => 〈Val v,s2〉" BinOpThrow11: "P \<turnstile>1 〈e1,s0〉 => 〈throw e,s1〉 ==> P \<turnstile>1 〈e1 «bop» e2, s0〉 => 〈throw e,s1〉" BinOpThrow21: "[| P \<turnstile>1 〈e1,s0〉 => 〈Val v1,s1〉; P \<turnstile>1 〈e2,s1〉 => 〈throw e,s2〉 |] ==> P \<turnstile>1 〈e1 «bop» e2,s0〉 => 〈throw e,s2〉" Var1: "[| ls!i = v; i < size ls |] ==> P \<turnstile>1 〈Var i,(h,ls)〉 => 〈Val v,(h,ls)〉" LAss1: "[| P \<turnstile>1 〈e,s0〉 => 〈Val v,(h,ls)〉; i < size ls; ls' = ls[i := v] |] ==> P \<turnstile>1 〈i:= e,s0〉 => 〈unit,(h,ls')〉" LAssThrow1: "P \<turnstile>1 〈e,s0〉 => 〈throw e',s1〉 ==> P \<turnstile>1 〈i:= e,s0〉 => 〈throw e',s1〉" FAcc1: "[| P \<turnstile>1 〈e,s0〉 => 〈addr a,(h,ls)〉; h a = Some(C,fs); fs(F,D) = Some v |] ==> P \<turnstile>1 〈e\<bullet>F{D},s0〉 => 〈Val v,(h,ls)〉" FAccNull1: "P \<turnstile>1 〈e,s0〉 => 〈null,s1〉 ==> P \<turnstile>1 〈e\<bullet>F{D},s0〉 => 〈THROW NullPointer,s1〉" FAccThrow1: "P \<turnstile>1 〈e,s0〉 => 〈throw e',s1〉 ==> P \<turnstile>1 〈e\<bullet>F{D},s0〉 => 〈throw e',s1〉" FAss1: "[| P \<turnstile>1 〈e1,s0〉 => 〈addr a,s1〉; P \<turnstile>1 〈e2,s1〉 => 〈Val v,(h2,l2)〉; h2 a = Some(C,fs); fs' = fs((F,D)\<mapsto>v); h2' = h2(a\<mapsto>(C,fs')) |] ==> P \<turnstile>1 〈e1\<bullet>F{D}:= e2,s0〉 => 〈unit,(h2',l2)〉" FAssNull1: "[| P \<turnstile>1 〈e1,s0〉 => 〈null,s1〉; P \<turnstile>1 〈e2,s1〉 => 〈Val v,s2〉 |] ==> P \<turnstile>1 〈e1\<bullet>F{D}:= e2,s0〉 => 〈THROW NullPointer,s2〉" FAssThrow11: "P \<turnstile>1 〈e1,s0〉 => 〈throw e',s1〉 ==> P \<turnstile>1 〈e1\<bullet>F{D}:= e2,s0〉 => 〈throw e',s1〉" FAssThrow21: "[| P \<turnstile>1 〈e1,s0〉 => 〈Val v,s1〉; P \<turnstile>1 〈e2,s1〉 => 〈throw e',s2〉 |] ==> P \<turnstile>1 〈e1\<bullet>F{D}:= e2,s0〉 => 〈throw e',s2〉" CallObjThrow1: "P \<turnstile>1 〈e,s0〉 => 〈throw e',s1〉 ==> P \<turnstile>1 〈e\<bullet>M(es),s0〉 => 〈throw e',s1〉" CallNull1: "[| P \<turnstile>1 〈e,s0〉 => 〈null,s1〉; P \<turnstile>1 〈es,s1〉 [=>] 〈map Val vs,s2〉 |] ==> P \<turnstile>1 〈e\<bullet>M(es),s0〉 => 〈THROW NullPointer,s2〉" Call1: "[| P \<turnstile>1 〈e,s0〉 => 〈addr a,s1〉; P \<turnstile>1 〈es,s1〉 [=>] 〈map Val vs,(h2,ls2)〉; h2 a = Some(C,fs); P \<turnstile> C sees M:Ts->T = body in D; size vs = size Ts; ls2' = (Addr a) # vs @ replicate (max_vars body) arbitrary; P \<turnstile>1 〈body,(h2,ls2')〉 => 〈e',(h3,ls3)〉 |] ==> P \<turnstile>1 〈e\<bullet>M(es),s0〉 => 〈e',(h3,ls2)〉" CallParamsThrow1: "[| P \<turnstile>1 〈e,s0〉 => 〈Val v,s1〉; P \<turnstile>1 〈es,s1〉 [=>] 〈es',s2〉; es' = map Val vs @ throw ex # es2 |] ==> P \<turnstile>1 〈e\<bullet>M(es),s0〉 => 〈throw ex,s2〉" Block1: "P \<turnstile>1 〈e,s0〉 => 〈f,s1〉 ==> P \<turnstile>1 〈Block i T e,s0〉 => 〈f,s1〉" Seq1: "[| P \<turnstile>1 〈e0,s0〉 => 〈Val v,s1〉; P \<turnstile>1 〈e1,s1〉 => 〈e2,s2〉 |] ==> P \<turnstile>1 〈e0;;e1,s0〉 => 〈e2,s2〉" SeqThrow1: "P \<turnstile>1 〈e0,s0〉 => 〈throw e,s1〉 ==> P \<turnstile>1 〈e0;;e1,s0〉 => 〈throw e,s1〉" CondT1: "[| P \<turnstile>1 〈e,s0〉 => 〈true,s1〉; P \<turnstile>1 〈e1,s1〉 => 〈e',s2〉 |] ==> P \<turnstile>1 〈if (e) e1 else e2,s0〉 => 〈e',s2〉" CondF1: "[| P \<turnstile>1 〈e,s0〉 => 〈false,s1〉; P \<turnstile>1 〈e2,s1〉 => 〈e',s2〉 |] ==> P \<turnstile>1 〈if (e) e1 else e2,s0〉 => 〈e',s2〉" CondThrow1: "P \<turnstile>1 〈e,s0〉 => 〈throw e',s1〉 ==> P \<turnstile>1 〈if (e) e1 else e2, s0〉 => 〈throw e',s1〉" WhileF1: "P \<turnstile>1 〈e,s0〉 => 〈false,s1〉 ==> P \<turnstile>1 〈while (e) c,s0〉 => 〈unit,s1〉" WhileT1: "[| P \<turnstile>1 〈e,s0〉 => 〈true,s1〉; P \<turnstile>1 〈c,s1〉 => 〈Val v1,s2〉; P \<turnstile>1 〈while (e) c,s2〉 => 〈e3,s3〉 |] ==> P \<turnstile>1 〈while (e) c,s0〉 => 〈e3,s3〉" WhileCondThrow1: "P \<turnstile>1 〈e,s0〉 => 〈throw e',s1〉 ==> P \<turnstile>1 〈while (e) c,s0〉 => 〈throw e',s1〉" WhileBodyThrow1: "[| P \<turnstile>1 〈e,s0〉 => 〈true,s1〉; P \<turnstile>1 〈c,s1〉 => 〈throw e',s2〉|] ==> P \<turnstile>1 〈while (e) c,s0〉 => 〈throw e',s2〉" Throw1: "P \<turnstile>1 〈e,s0〉 => 〈addr a,s1〉 ==> P \<turnstile>1 〈throw e,s0〉 => 〈Throw a,s1〉" ThrowNull1: "P \<turnstile>1 〈e,s0〉 => 〈null,s1〉 ==> P \<turnstile>1 〈throw e,s0〉 => 〈THROW NullPointer,s1〉" ThrowThrow1: "P \<turnstile>1 〈e,s0〉 => 〈throw e',s1〉 ==> P \<turnstile>1 〈throw e,s0〉 => 〈throw e',s1〉" Try1: "P \<turnstile>1 〈e1,s0〉 => 〈Val v1,s1〉 ==> P \<turnstile>1 〈try e1 catch(C i) e2,s0〉 => 〈Val v1,s1〉" TryCatch1: "[| P \<turnstile>1 〈e1,s0〉 => 〈Throw a,(h1,ls1)〉; h1 a = Some(D,fs); P \<turnstile> D \<preceq>* C; i < length ls1; P \<turnstile>1 〈e2,(h1,ls1[i:=Addr a])〉 => 〈e2',(h2,ls2)〉 |] ==> P \<turnstile>1 〈try e1 catch(C i) e2,s0〉 => 〈e2',(h2,ls2)〉" TryThrow1: "[| P \<turnstile>1 〈e1,s0〉 => 〈Throw a,(h1,ls1)〉; h1 a = Some(D,fs); ¬ P \<turnstile> D \<preceq>* C |] ==> P \<turnstile>1 〈try e1 catch(C i) e2,s0〉 => 〈Throw a,(h1,ls1)〉" Nil1: "P \<turnstile>1 〈[],s〉 [=>] 〈[],s〉" Cons1: "[| P \<turnstile>1 〈e,s0〉 => 〈Val v,s1〉; P \<turnstile>1 〈es,s1〉 [=>] 〈es',s2〉 |] ==> P \<turnstile>1 〈e#es,s0〉 [=>] 〈Val v # es',s2〉" ConsThrow1: "P \<turnstile>1 〈e,s0〉 => 〈throw e',s1〉 ==> P \<turnstile>1 〈e#es,s0〉 [=>] 〈throw e' # es, s1〉" (*<*) lemmas eval1_evals1_induct = eval1_evals1.induct [split_format (complete)] (*>*) lemma eval1_preserves_len: "P \<turnstile>1 〈e0,(h0,ls0)〉 => 〈e1,(h1,ls1)〉 ==> length ls0 = length ls1" and evals1_preserves_len: "P \<turnstile>1 〈es0,(h0,ls0)〉 [=>] 〈es1,(h1,ls1)〉 ==> length ls0 = length ls1" (*<*)by (induct rule:eval1_evals1_induct, simp_all)(*>*) lemma evals1_preserves_elen: "!!es' s s'. P \<turnstile>1 〈es,s〉 [=>] 〈es',s'〉 ==> length es = length es'" (*<*) apply(induct es type:list) apply (auto elim:eval1_evals1.elims) done (*>*) lemma eval1_final: "P \<turnstile>1 〈e,s〉 => 〈e',s'〉 ==> final e'" and evals1_final: "P \<turnstile>1 〈es,s〉 [=>] 〈es',s'〉 ==> finals es'" (*<*)by(induct rule:eval1_evals1.induct, simp_all)(*>*) end
lemmas eval1_evals1_induct:
[| !!C FDTs a h h' l. [| new_Addr h = ⌊a⌋; P \<turnstile> C has_fields FDTs; h' = h(a |-> (C, init_fields FDTs)) |] ==> P1 (new C) h l (addr a) h' l; !!C h l. new_Addr h = None ==> P1 (new C) h l (THROW OutOfMemory) h l; !!C D a e fs h l aa b. [| eval1 P e (aa, b) (addr a) (h, l); P1 e aa b (addr a) h l; h a = ⌊(D, fs)⌋; subcls P D C |] ==> P1 (Cast C e) aa b (addr a) h l; !!C e a b aa ba. [| eval1 P e (a, b) null (aa, ba); P1 e a b null aa ba |] ==> P1 (Cast C e) a b null aa ba; !!C D a e fs h l aa b. [| eval1 P e (aa, b) (addr a) (h, l); P1 e aa b (addr a) h l; h a = ⌊(D, fs)⌋; ¬ subcls P D C |] ==> P1 (Cast C e) aa b (THROW ClassCast) h l; !!C e e' a b aa ba. [| eval1 P e (a, b) (throw e') (aa, ba); P1 e a b (throw e') aa ba |] ==> P1 (Cast C e) a b (throw e') aa ba; !!a b v. P1 (Val v) a b (Val v) a b; !!bop e1 e2 a b aa ba ab bb v v1 v2. [| eval1 P e1 (a, b) (Val v1) (aa, ba); P1 e1 a b (Val v1) aa ba; eval1 P e2 (aa, ba) (Val v2) (ab, bb); P1 e2 aa ba (Val v2) ab bb; binop (bop, v1, v2) = ⌊v⌋ |] ==> P1 (e1 «bop» e2) a b (Val v) ab bb; !!bop e e1 e2 a b aa ba. [| eval1 P e1 (a, b) (throw e) (aa, ba); P1 e1 a b (throw e) aa ba |] ==> P1 (e1 «bop» e2) a b (throw e) aa ba; !!bop e e1 e2 a b aa ba ab bb v1. [| eval1 P e1 (a, b) (Val v1) (aa, ba); P1 e1 a b (Val v1) aa ba; eval1 P e2 (aa, ba) (throw e) (ab, bb); P1 e2 aa ba (throw e) ab bb |] ==> P1 (e1 «bop» e2) a b (throw e) ab bb; !!h i ls v. [| ls ! i = v; i < length ls |] ==> P1 (Var i) h ls (Val v) h ls; !!e h i ls ls' a b v. [| eval1 P e (a, b) (Val v) (h, ls); P1 e a b (Val v) h ls; i < length ls; ls' = ls[i := v] |] ==> P1 (i:=e) a b unit h ls'; !!e e' i a b aa ba. [| eval1 P e (a, b) (throw e') (aa, ba); P1 e a b (throw e') aa ba |] ==> P1 (i:=e) a b (throw e') aa ba; !!C D F a e fs h ls aa b v. [| eval1 P e (aa, b) (addr a) (h, ls); P1 e aa b (addr a) h ls; h a = ⌊(C, fs)⌋; fs (F, D) = ⌊v⌋ |] ==> P1 (e\<bullet>F{D}) aa b (Val v) h ls; !!D F e a b aa ba. [| eval1 P e (a, b) null (aa, ba); P1 e a b null aa ba |] ==> P1 (e\<bullet>F{D}) a b (THROW NullPointer) aa ba; !!D F e e' a b aa ba. [| eval1 P e (a, b) (throw e') (aa, ba); P1 e a b (throw e') aa ba |] ==> P1 (e\<bullet>F{D}) a b (throw e') aa ba; !!C D F a e1 e2 fs fs' h2 h2' l2 aa b ab ba v. [| eval1 P e1 (aa, b) (addr a) (ab, ba); P1 e1 aa b (addr a) ab ba; eval1 P e2 (ab, ba) (Val v) (h2, l2); P1 e2 ab ba (Val v) h2 l2; h2 a = ⌊(C, fs)⌋; fs' = fs((F, D) |-> v); h2' = h2(a |-> (C, fs')) |] ==> P1 (e1\<bullet>F{D} := e2) aa b unit h2' l2; !!D F e1 e2 a b aa ba ab bb v. [| eval1 P e1 (a, b) null (aa, ba); P1 e1 a b null aa ba; eval1 P e2 (aa, ba) (Val v) (ab, bb); P1 e2 aa ba (Val v) ab bb |] ==> P1 (e1\<bullet>F{D} := e2) a b (THROW NullPointer) ab bb; !!D F e' e1 e2 a b aa ba. [| eval1 P e1 (a, b) (throw e') (aa, ba); P1 e1 a b (throw e') aa ba |] ==> P1 (e1\<bullet>F{D} := e2) a b (throw e') aa ba; !!D F e' e1 e2 a b aa ba ab bb v. [| eval1 P e1 (a, b) (Val v) (aa, ba); P1 e1 a b (Val v) aa ba; eval1 P e2 (aa, ba) (throw e') (ab, bb); P1 e2 aa ba (throw e') ab bb |] ==> P1 (e1\<bullet>F{D} := e2) a b (throw e') ab bb; !!M e e' es a b aa ba. [| eval1 P e (a, b) (throw e') (aa, ba); P1 e a b (throw e') aa ba |] ==> P1 (e\<bullet>M(es)) a b (throw e') aa ba; !!M e es a b aa ba ab bb vs. [| eval1 P e (a, b) null (aa, ba); P1 e a b null aa ba; evals1 P es (aa, ba) (map Val vs) (ab, bb); P2 es aa ba (map Val vs) ab bb |] ==> P1 (e\<bullet>M(es)) a b (THROW NullPointer) ab bb; !!C D M T Ts a body e e' es fs h2 h3 ls2 ls2' ls3 aa b ab ba vs. [| eval1 P e (aa, b) (addr a) (ab, ba); P1 e aa b (addr a) ab ba; evals1 P es (ab, ba) (map Val vs) (h2, ls2); P2 es ab ba (map Val vs) h2 ls2; h2 a = ⌊(C, fs)⌋; P \<turnstile> C sees M: Ts->T = body in D; length vs = length Ts; ls2' = Addr a # vs @ replicate (max_vars body) arbitrary; eval1 P body (h2, ls2') e' (h3, ls3); P1 body h2 ls2' e' h3 ls3 |] ==> P1 (e\<bullet>M(es)) aa b e' h3 ls2; !!M e es es' es2 ex a b aa ba ab bb v vs. [| eval1 P e (a, b) (Val v) (aa, ba); P1 e a b (Val v) aa ba; evals1 P es (aa, ba) es' (ab, bb); P2 es aa ba es' ab bb; es' = map Val vs @ throw ex # es2 |] ==> P1 (e\<bullet>M(es)) a b (throw ex) ab bb; !!T e f i a b aa ba. [| eval1 P e (a, b) f (aa, ba); P1 e a b f aa ba |] ==> P1 {i:T; e} a b f aa ba; !!e0 e1 e2 a b aa ba ab bb v. [| eval1 P e0 (a, b) (Val v) (aa, ba); P1 e0 a b (Val v) aa ba; eval1 P e1 (aa, ba) e2 (ab, bb); P1 e1 aa ba e2 ab bb |] ==> P1 (e0;; e1) a b e2 ab bb; !!e e0 e1 a b aa ba. [| eval1 P e0 (a, b) (throw e) (aa, ba); P1 e0 a b (throw e) aa ba |] ==> P1 (e0;; e1) a b (throw e) aa ba; !!e e' e1 e2 a b aa ba ab bb. [| eval1 P e (a, b) true (aa, ba); P1 e a b true aa ba; eval1 P e1 (aa, ba) e' (ab, bb); P1 e1 aa ba e' ab bb |] ==> P1 (if (e) e1 else e2) a b e' ab bb; !!e e' e1 e2 a b aa ba ab bb. [| eval1 P e (a, b) false (aa, ba); P1 e a b false aa ba; eval1 P e2 (aa, ba) e' (ab, bb); P1 e2 aa ba e' ab bb |] ==> P1 (if (e) e1 else e2) a b e' ab bb; !!e e' e1 e2 a b aa ba. [| eval1 P e (a, b) (throw e') (aa, ba); P1 e a b (throw e') aa ba |] ==> P1 (if (e) e1 else e2) a b (throw e') aa ba; !!c e a b aa ba. [| eval1 P e (a, b) false (aa, ba); P1 e a b false aa ba |] ==> P1 (while (e) c) a b unit aa ba; !!c e e3 a b aa ba ab bb ac bc v1. [| eval1 P e (a, b) true (aa, ba); P1 e a b true aa ba; eval1 P c (aa, ba) (Val v1) (ab, bb); P1 c aa ba (Val v1) ab bb; eval1 P (while (e) c) (ab, bb) e3 (ac, bc); P1 (while (e) c) ab bb e3 ac bc |] ==> P1 (while (e) c) a b e3 ac bc; !!c e e' a b aa ba. [| eval1 P e (a, b) (throw e') (aa, ba); P1 e a b (throw e') aa ba |] ==> P1 (while (e) c) a b (throw e') aa ba; !!c e e' a b aa ba ab bb. [| eval1 P e (a, b) true (aa, ba); P1 e a b true aa ba; eval1 P c (aa, ba) (throw e') (ab, bb); P1 c aa ba (throw e') ab bb |] ==> P1 (while (e) c) a b (throw e') ab bb; !!a e aa b ab ba. [| eval1 P e (aa, b) (addr a) (ab, ba); P1 e aa b (addr a) ab ba |] ==> P1 (throw e) aa b (Throw a) ab ba; !!e a b aa ba. [| eval1 P e (a, b) null (aa, ba); P1 e a b null aa ba |] ==> P1 (throw e) a b (THROW NullPointer) aa ba; !!e e' a b aa ba. [| eval1 P e (a, b) (throw e') (aa, ba); P1 e a b (throw e') aa ba |] ==> P1 (throw e) a b (throw e') aa ba; !!C e1 e2 i a b aa ba v1. [| eval1 P e1 (a, b) (Val v1) (aa, ba); P1 e1 a b (Val v1) aa ba |] ==> P1 (try e1 catch(C i) e2) a b (Val v1) aa ba; !!C D a e1 e2 e2' fs h1 h2 i ls1 ls2 aa b. [| eval1 P e1 (aa, b) (Throw a) (h1, ls1); P1 e1 aa b (Throw a) h1 ls1; h1 a = ⌊(D, fs)⌋; subcls P D C; i < length ls1; eval1 P e2 (h1, ls1[i := Addr a]) e2' (h2, ls2); P1 e2 h1 (ls1[i := Addr a]) e2' h2 ls2 |] ==> P1 (try e1 catch(C i) e2) aa b e2' h2 ls2; !!C D a e1 e2 fs h1 i ls1 aa b. [| eval1 P e1 (aa, b) (Throw a) (h1, ls1); P1 e1 aa b (Throw a) h1 ls1; h1 a = ⌊(D, fs)⌋; ¬ subcls P D C |] ==> P1 (try e1 catch(C i) e2) aa b (Throw a) h1 ls1; !!a b. P2 [] a b [] a b; !!e es es' a b aa ba ab bb v. [| eval1 P e (a, b) (Val v) (aa, ba); P1 e a b (Val v) aa ba; evals1 P es (aa, ba) es' (ab, bb); P2 es aa ba es' ab bb |] ==> P2 (e # es) a b (Val v # es') ab bb; !!e e' es a b aa ba. [| eval1 P e (a, b) (throw e') (aa, ba); P1 e a b (throw e') aa ba |] ==> P2 (e # es) a b (throw e' # es) aa ba |] ==> (eval1 P xha (xga, xgb) xfa (xea, xeb) --> P1 xha xga xgb xfa xea xeb) & (evals1 P xda (xca, xcb) xba (xaa, xab) --> P2 xda xca xcb xba xaa xab)
lemma eval1_preserves_len:
eval1 P e0 (h0, ls0) e1 (h1, ls1) ==> length ls0 = length ls1
and evals1_preserves_len:
evals1 P es0 (h0, ls0) es1 (h1, ls1) ==> length ls0 = length ls1
lemma evals1_preserves_elen:
evals1 P es s es' s' ==> length es = length es'
lemma eval1_final:
eval1 P e s e' s' ==> final e'
and evals1_final:
evals1 P es s es' s' ==> finals es'