Theory WellTypeRT

Up to index of Isabelle/HOL/Jinja

theory WellTypeRT
imports WellType
(*  Title:      Jinja/J/WellTypeRT.thy

Author: Tobias Nipkow
Copyright 2003 Technische Universitaet Muenchen
*)


header {* \isaheader{Runtime Well-typedness} *}

theory WellTypeRT
imports WellType
begin

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"
("_,_,_ \<turnstile> _ : _" [51,51,51]50)
and WTrts2 :: "[J_prog,env,heap,expr list, ty list] => bool"
("_,_,_ \<turnstile> _ [:] _" [51,51,51]50)
for P :: J_prog and h :: heap
where

"P,E,h \<turnstile> e : T ≡ WTrt P h E e T"
| "P,E,h \<turnstile> es[:]Ts ≡ WTrts P h E es Ts"

| WTrtNew:
"is_class P C ==>
P,E,h \<turnstile> new C : Class C"


| WTrtCast:
"[| P,E,h \<turnstile> e : T; is_refT T; is_class P C |]
==> P,E,h \<turnstile> Cast C e : Class C"


| WTrtVal:
"typeofh v = Some T ==>
P,E,h \<turnstile> Val v : T"


| WTrtVar:
"E V = Some T ==>
P,E,h \<turnstile> Var V : T"

(*
WTrtBinOp:
"[| P,E,h \<turnstile> e1 : T1; P,E,h \<turnstile> e2 : T2;
case bop of Eq => T = Boolean
| Add => T1 = Integer ∧ T2 = Integer ∧ T = Integer |]
==> P,E,h \<turnstile> e1 «bop» e2 : T"
*)

| WTrtBinOpEq:
"[| P,E,h \<turnstile> e1 : T1; P,E,h \<turnstile> e2 : T2 |]
==> P,E,h \<turnstile> e1 «Eq» e2 : Boolean"


| WTrtBinOpAdd:
"[| P,E,h \<turnstile> e1 : Integer; P,E,h \<turnstile> e2 : Integer |]
==> P,E,h \<turnstile> e1 «Add» e2 : Integer"


| WTrtLAss:
"[| E V = Some T; P,E,h \<turnstile> e : T'; P \<turnstile> T' ≤ T |]
==> P,E,h \<turnstile> V:=e : Void"


| WTrtFAcc:
"[| P,E,h \<turnstile> e : Class C; P \<turnstile> C has F:T in D |] ==>
P,E,h \<turnstile> e•F{D} : T"


| WTrtFAccNT:
"P,E,h \<turnstile> e : NT ==>
P,E,h \<turnstile> e•F{D} : T"


| WTrtFAss:
"[| P,E,h \<turnstile> e1 : Class C; P \<turnstile> C has F:T in D; P,E,h \<turnstile> e2 : T2; P \<turnstile> T2 ≤ T |]
==> P,E,h \<turnstile> e1•F{D}:=e2 : Void"


| WTrtFAssNT:
"[| P,E,h \<turnstile> e1:NT; P,E,h \<turnstile> e2 : T2 |]
==> P,E,h \<turnstile> e1•F{D}:=e2 : Void"


| WTrtCall:
"[| P,E,h \<turnstile> e : Class C; P \<turnstile> C sees M:Ts -> T = (pns,body) in D;
P,E,h \<turnstile> es [:] Ts'; P \<turnstile> Ts' [≤] Ts |]
==> P,E,h \<turnstile> e•M(es) : T"


| WTrtCallNT:
"[| P,E,h \<turnstile> e : NT; P,E,h \<turnstile> es [:] Ts |]
==> P,E,h \<turnstile> e•M(es) : T"


| WTrtBlock:
"P,E(V\<mapsto>T),h \<turnstile> e : T' ==>
P,E,h \<turnstile> {V:T; e} : T'"


| WTrtSeq:
"[| P,E,h \<turnstile> e1:T1; P,E,h \<turnstile> e2:T2 |]
==> P,E,h \<turnstile> e1;;e2 : T2"


| WTrtCond:
"[| P,E,h \<turnstile> e : Boolean; P,E,h \<turnstile> e1:T1; P,E,h \<turnstile> e2:T2;
P \<turnstile> T1 ≤ T2 ∨ P \<turnstile> T2 ≤ T1; P \<turnstile> T1 ≤ T2 --> T = T2; P \<turnstile> T2 ≤ T1 --> T = T1 |]
==> P,E,h \<turnstile> if (e) e1 else e2 : T"


| WTrtWhile:
"[| P,E,h \<turnstile> e : Boolean; P,E,h \<turnstile> c:T |]
==> P,E,h \<turnstile> while(e) c : Void"


| WTrtThrow:
"[| P,E,h \<turnstile> e : Tr; is_refT Tr |] ==>
P,E,h \<turnstile> throw e : T"


| WTrtTry:
"[| P,E,h \<turnstile> e1 : T1; P,E(V \<mapsto> Class C),h \<turnstile> e2 : T2; P \<turnstile> T1 ≤ T2 |]
==> P,E,h \<turnstile> try e1 catch(C V) e2 : T2"


-- "well-typed expression lists"

| WTrtNil:
"P,E,h \<turnstile> [] [:] []"

| WTrtCons:
"[| P,E,h \<turnstile> e : T; P,E,h \<turnstile> es [:] Ts |]
==> P,E,h \<turnstile> e#es [:] T#Ts"


(*<*)
declare WTrt_WTrts.intros[intro!] WTrtNil[iff]
declare
WTrtFAcc[rule del] WTrtFAccNT[rule del]
WTrtFAss[rule del] WTrtFAssNT[rule del]
WTrtCall[rule del] WTrtCallNT[rule del]

lemmas WTrt_induct = WTrt_WTrts.induct [split_format (complete)]
and WTrt_inducts = WTrt_WTrts.inducts [split_format (complete)]
(*>*)


subsection{*Easy consequences*}

lemma [iff]: "(P,E,h \<turnstile> [] [:] Ts) = (Ts = [])"
(*<*)
apply(rule iffI)
apply (auto elim: WTrts.cases)
done
(*>*)

lemma [iff]: "(P,E,h \<turnstile> e#es [:] T#Ts) = (P,E,h \<turnstile> e : T ∧ P,E,h \<turnstile> es [:] Ts)"
(*<*)
apply(rule iffI)
apply (auto elim: WTrts.cases)
done
(*>*)

lemma [iff]: "(P,E,h \<turnstile> (e#es) [:] Ts) =
(∃U Us. Ts = U#Us ∧ P,E,h \<turnstile> e : U ∧ P,E,h \<turnstile> es [:] Us)"

(*<*)
apply(rule iffI)
apply (auto elim: WTrts.cases)
done
(*>*)

lemma [simp]: "∀Ts. (P,E,h \<turnstile> es1 @ es2 [:] Ts) =
(∃Ts1 Ts2. Ts = Ts1 @ Ts2 ∧ P,E,h \<turnstile> es1 [:] Ts1 & P,E,h \<turnstile> es2[:]Ts2)"

(*<*)
apply(induct_tac es1)
apply simp
apply clarsimp
apply(erule thin_rl)
apply (rule iffI)
apply clarsimp
apply(rule exI)+
apply(rule conjI)
prefer 2 apply blast
apply simp
apply fastforce
done
(*>*)

lemma [iff]: "P,E,h \<turnstile> Val v : T = (typeofh v = Some T)"
(*<*)
apply(rule iffI)
apply (auto elim: WTrt.cases)
done
(*>*)

lemma [iff]: "P,E,h \<turnstile> Var v : T = (E v = Some T)"
(*<*)
apply(rule iffI)
apply (auto elim: WTrt.cases)
done
(*>*)

lemma [iff]: "P,E,h \<turnstile> e1;;e2 : T2 = (∃T1. P,E,h \<turnstile> e1:T1 ∧ P,E,h \<turnstile> e2:T2)"
(*<*)
apply(rule iffI)
apply (auto elim: WTrt.cases)
done
(*>*)

lemma [iff]: "P,E,h \<turnstile> {V:T; e} : T' = (P,E(V\<mapsto>T),h \<turnstile> e : T')"
(*<*)
apply(rule iffI)
apply (auto elim: WTrt.cases)
done
(*>*)
(*<*)
inductive_cases WTrt_elim_cases[elim!]:
"P,E,h \<turnstile> v :=e : T"
"P,E,h \<turnstile> if (e) e1 else e2 : T"
"P,E,h \<turnstile> while(e) c : T"
"P,E,h \<turnstile> throw e : T"
"P,E,h \<turnstile> try e1 catch(C V) e2 : T"
"P,E,h \<turnstile> Cast D e : T"
"P,E,h \<turnstile> e•F{D} : T"
"P,E,h \<turnstile> e•F{D} := v : T"
"P,E,h \<turnstile> e1 «bop» e2 : T"
"P,E,h \<turnstile> new C : T"
"P,E,h \<turnstile> e•M{D}(es) : T"
(*>*)

subsection{*Some interesting lemmas*}

lemma WTrts_Val[simp]:
"!!Ts. (P,E,h \<turnstile> map Val vs [:] Ts) = (map (typeofh) vs = map Some Ts)"
(*<*)
apply(induct vs)
apply simp
apply(case_tac Ts)
apply simp
apply simp
done
(*>*)


lemma WTrts_same_length: "!!Ts. P,E,h \<turnstile> es [:] Ts ==> length es = length Ts"
(*<*)by(induct es type:list)auto(*>*)


lemma WTrt_env_mono:
"P,E,h \<turnstile> e : T ==> (!!E'. E ⊆m E' ==> P,E',h \<turnstile> e : T)" and
"P,E,h \<turnstile> es [:] Ts ==> (!!E'. E ⊆m E' ==> P,E',h \<turnstile> es [:] Ts)"
(*<*)
apply(induct rule: WTrt_inducts)
apply(simp add: WTrtNew)
apply(fastforce simp: WTrtCast)
apply(fastforce simp: WTrtVal)
apply(simp add: WTrtVar map_le_def dom_def)
apply(fastforce simp add: WTrtBinOpEq)
apply(fastforce simp add: WTrtBinOpAdd)
apply(force simp: map_le_def)
apply(fastforce simp: WTrtFAcc)
apply(simp add: WTrtFAccNT)
apply(fastforce simp: WTrtFAss)
apply(fastforce simp: WTrtFAssNT)
apply(fastforce simp: WTrtCall)
apply(fastforce simp: WTrtCallNT)
apply(simp add: WTrtNil)
apply(simp add: WTrtCons)
apply(fastforce simp: map_le_def)
apply(fastforce)
apply(fastforce simp: WTrtSeq)
apply(fastforce simp: WTrtWhile)
apply(fastforce simp: WTrtThrow)
apply(auto simp: WTrtTry map_le_def dom_def)
done
(*>*)


lemma WTrt_hext_mono: "P,E,h \<turnstile> e : T ==> h \<unlhd> h' ==> P,E,h' \<turnstile> e : T"
and WTrts_hext_mono: "P,E,h \<turnstile> es [:] Ts ==> h \<unlhd> h' ==> P,E,h' \<turnstile> es [:] Ts"
(*<*)
apply(induct rule: WTrt_inducts)
apply(simp add: WTrtNew)
apply(fastforce simp: WTrtCast)
apply(fastforce simp: WTrtVal dest:hext_typeof_mono)
apply(simp add: WTrtVar)
apply(fastforce simp add: WTrtBinOpEq)
apply(fastforce simp add: WTrtBinOpAdd)
apply(fastforce simp add: WTrtLAss)
apply(fast intro: WTrtFAcc)
apply(simp add: WTrtFAccNT)
apply(fastforce simp: WTrtFAss del:WTrt_WTrts.intros WTrt_elim_cases)
apply(fastforce simp: WTrtFAssNT)
apply(fastforce simp: WTrtCall)
apply(fastforce simp: WTrtCallNT)
apply(fastforce)
apply(fastforce simp add: WTrtSeq)
apply(fastforce simp add: WTrtCond)
apply(fastforce simp add: WTrtWhile)
apply(fastforce simp add: WTrtThrow)
apply(fastforce simp: WTrtTry)
apply(simp add: WTrtNil)
apply(simp add: WTrtCons)
done
(*>*)


lemma WT_implies_WTrt: "P,E \<turnstile> e :: T ==> P,E,h \<turnstile> e : T"
and WTs_implies_WTrts: "P,E \<turnstile> es [::] Ts ==> P,E,h \<turnstile> es [:] Ts"
(*<*)
apply(induct rule: WT_WTs_inducts)
apply fast
apply (fast)
apply(fastforce dest:typeof_lit_typeof)
apply(simp)
apply(fastforce)
apply(fastforce)
apply(fastforce)
apply(fastforce simp: WTrtFAcc has_visible_field)
apply(fastforce simp: WTrtFAss dest: has_visible_field)
apply(fastforce simp: WTrtCall)
apply(fastforce)
apply(fastforce)
apply(fastforce simp: WTrtCond)
apply(fastforce)
apply(fastforce)
apply(fastforce)
apply(simp)
apply(simp)
done
(*>*)


end