Theory WellType

(*  Title:      Jinja/J/WellType.thy

    Author:     Tobias Nipkow
    Copyright   2003 Technische Universitaet Muenchen
*)

section ‹Well-typedness of Jinja expressions›

theory WellType
imports "../Common/Objects" Expr
begin

type_synonym
  env  = "vname  ty"

inductive
  WT :: "[J_prog,env, expr     , ty     ]  bool"
         ("_,_  _ :: _"   [51,51,51]50)
  and WTs :: "[J_prog,env, expr list, ty list]  bool"
         ("_,_  _ [::] _" [51,51,51]50)
  for P :: J_prog
where
  
  WTNew:
  "is_class P C  
  P,E  new C :: Class C"

| WTCast:
  " P,E  e :: Class D;  is_class P C;  P  C * D  P  D * C 
   P,E  Cast C e :: Class C"

| WTVal:
  "typeof v = Some T 
  P,E  Val v :: T"

| WTVar:
  "E V = Some T 
  P,E  Var V :: T"
(*
WTBinOp:
  "⟦ P,E ⊢ e1 :: T1;  P,E ⊢ e2 :: T2;
     case bop of Eq ⇒ (P ⊢ T1 ≤ T2 ∨ P ⊢ T2 ≤ T1) ∧ T = Boolean
               | Add ⇒ T1 = Integer ∧ T2 = Integer ∧ T = Integer ⟧
  ⟹ P,E ⊢ e1 «bop» e2 :: T"
*)
| WTBinOpEq:
  " P,E  e1 :: T1;  P,E  e2 :: T2; P  T1  T2  P  T2  T1 
   P,E  e1 «Eq» e2 :: Boolean"

| WTBinOpAdd:
  " P,E  e1 :: Integer;  P,E  e2 :: Integer 
   P,E  e1 «Add» e2 :: Integer"

| WTLAss:
  " E V = Some T;  P,E  e :: T';  P  T'  T;  V  this 
   P,E  V:=e :: Void"

| WTFAcc:
  " P,E  e :: Class C;  P  C sees F:T in D 
   P,E  eF{D} :: T"

| WTFAss:
  " P,E  e1 :: Class C;  P  C sees F:T in D;  P,E  e2 :: T';  P  T'  T 
   P,E  e1F{D}:=e2 :: Void"

| WTCall:
  " P,E  e :: Class C;  P  C sees M:Ts  T = (pns,body) in D;
     P,E  es [::] Ts';  P  Ts' [≤] Ts 
   P,E  eM(es) :: T"

| WTBlock:
  " is_type P T;  P,E(V  T)  e :: T' 
    P,E  {V:T; e} :: T'"

| WTSeq:
  " P,E  e1::T1;  P,E  e2::T2 
    P,E  e1;;e2 :: T2"
| WTCond:
  " P,E  e :: Boolean;  P,E  e1::T1;  P,E  e2::T2;
     P  T1  T2  P  T2  T1;  P  T1  T2  T = T2;  P  T2  T1  T = T1 
   P,E  if (e) e1 else e2 :: T"

| WTWhile:
  " P,E  e :: Boolean;  P,E  c::T 
   P,E  while (e) c :: Void"

| WTThrow:
  "P,E  e :: Class C   
  P,E  throw e :: Void"

| WTTry:
  " P,E  e1 :: T;  P,E(V  Class C)  e2 :: T; is_class P C 
   P,E  try e1 catch(C V) e2 :: T"

― ‹well-typed expression lists›

| WTNil:
  "P,E  [] [::] []"

| WTCons:
  " P,E  e :: T;  P,E  es [::] Ts 
    P,E  e#es [::] T#Ts"

(*<*)
(*
lemmas [intro!] = WTNew WTCast WTVal WTVar WTBinOp WTLAss WTFAcc WTFAss WTCall WTBlock WTSeq
                  WTWhile WTThrow WTTry WTNil WTCons
lemmas [intro]  = WTCond1 WTCond2
*)
declare WT_WTs.intros[intro!] (* WTNil[iff] *)

lemmas WT_WTs_induct = WT_WTs.induct [split_format (complete)]
  and WT_WTs_inducts = WT_WTs.inducts [split_format (complete)]
(*>*)

lemma [iff]: "(P,E  [] [::] Ts) = (Ts = [])"
(*<*)by (rule iffI) (auto elim: WTs.cases)(*>*)

lemma [iff]: "(P,E  e#es [::] T#Ts) = (P,E  e :: T  P,E  es [::] Ts)"
(*<*)by (rule iffI) (auto elim: WTs.cases)(*>*)

lemma [iff]: "(P,E  (e#es) [::] Ts) =
  (U Us. Ts = U#Us  P,E  e :: U  P,E  es [::] Us)"
(*<*)by (rule iffI) (auto elim: WTs.cases)(*>*)

lemma [iff]: "Ts. (P,E  es1 @ es2 [::] Ts) =
  (Ts1 Ts2. Ts = Ts1 @ Ts2  P,E  es1 [::] Ts1  P,E  es2[::]Ts2)"
(*<*)
proof(induct es1 type:list)
  case (Cons a list)
  let ?lhs = "(U Us. Ts = U # Us  P,E  a :: U 
        (Ts1 Ts2. Us = Ts1 @ Ts2  P,E  list [::] Ts1  P,E  es2 [::] Ts2))"
  let ?rhs = "(Ts1 Ts2. Ts = Ts1 @ Ts2 
        (U Us. Ts1 = U # Us  P,E  a :: U  P,E  list [::] Us)  P,E  es2 [::] Ts2)"
  { assume ?lhs
    then have ?rhs by (auto intro: Cons_eq_appendI)
  }
  moreover {
    assume ?rhs
    then have ?lhs by fastforce
  }
  ultimately have "?lhs = ?rhs" by(rule iffI)
  then show ?case by (clarsimp simp: Cons)
qed simp
(*>*)

lemma [iff]: "P,E  Val v :: T = (typeof v = Some T)"
(*<*)proof(rule iffI) qed (auto elim: WT.cases)(*>*)

lemma [iff]: "P,E  Var V :: T = (E V = Some T)"
(*<*)proof(rule iffI) qed (auto elim: WT.cases)(*>*)

lemma [iff]: "P,E  e1;;e2 :: T2 = (T1. P,E  e1::T1  P,E  e2::T2)"
(*<*)proof(rule iffI) qed (auto elim: WT.cases)(*>*)

lemma [iff]: "(P,E  {V:T; e} :: T') = (is_type P T  P,E(VT)  e :: T')"
(*<*)proof(rule iffI) qed (auto elim: WT.cases)(*>*)

(*<*)
inductive_cases WT_elim_cases[elim!]:
  "P,E  V :=e :: T"
  "P,E  if (e) e1 else e2 :: T"
  "P,E  while (e) c :: T"
  "P,E  throw e :: T"
  "P,E  try e1 catch(C V) e2 :: T"
  "P,E  Cast D e :: T"
  "P,E  aF{D} :: T"
  "P,E  aF{D} := v :: T"
  "P,E  e1 «bop» e2 :: T"
  "P,E  new C :: T"
  "P,E  eM(ps) :: T"
(*>*)


lemma wt_env_mono:
  "P,E  e :: T  (E'. E m E'  P,E'  e :: T)" and 
  "P,E  es [::] Ts  (E'. E m E'  P,E'  es [::] Ts)"
(*<*)
proof(induct rule: WT_WTs_inducts)
  case WTVar then show ?case by(simp add: map_le_def dom_def)
next
  case WTLAss then show ?case by(force simp:map_le_def)
qed fastforce+
(*>*)


lemma WT_fv: "P,E  e :: T  fv e  dom E"
and "P,E  es [::] Ts  fvs es  dom E"
(*<*)
proof(induct rule:WT_WTs.inducts)
  case WTVar then show ?case by fastforce
next
  case WTLAss then show ?case by fastforce
next
  case WTBlock then show ?case by fastforce
next
  case WTTry then show ?case by fastforce
qed simp_all

end
(*>*)