src/HOL/Bali/WellType.thy
author schirmer
Mon Jan 28 17:00:19 2002 +0100 (2002-01-28)
changeset 12854 00d4a435777f
child 12857 a4386cc9b1c3
permissions -rw-r--r--
Isabelle/Bali sources;
schirmer@12854
     1
(*  Title:      isabelle/Bali/WellType.thy
schirmer@12854
     2
    ID:         $Id$
schirmer@12854
     3
    Author:     David von Oheimb
schirmer@12854
     4
    Copyright   1997 Technische Universitaet Muenchen
schirmer@12854
     5
*)
schirmer@12854
     6
header {* Well-typedness of Java programs *}
schirmer@12854
     7
schirmer@12854
     8
theory WellType = DeclConcepts:
schirmer@12854
     9
schirmer@12854
    10
text {*
schirmer@12854
    11
improvements over Java Specification 1.0:
schirmer@12854
    12
\begin{itemize}
schirmer@12854
    13
\item methods of Object can be called upon references of interface or array type
schirmer@12854
    14
\end{itemize}
schirmer@12854
    15
simplifications:
schirmer@12854
    16
\begin{itemize}
schirmer@12854
    17
\item the type rules include all static checks on statements and expressions, 
schirmer@12854
    18
      e.g. definedness of names (of parameters, locals, fields, methods)
schirmer@12854
    19
\end{itemize}
schirmer@12854
    20
design issues:
schirmer@12854
    21
\begin{itemize}
schirmer@12854
    22
\item unified type judgment for statements, variables, expressions, 
schirmer@12854
    23
      expression lists
schirmer@12854
    24
\item statements are typed like expressions with dummy type Void
schirmer@12854
    25
\item the typing rules take an extra argument that is capable of determining 
schirmer@12854
    26
  the dynamic type of objects. Therefore, they can be used for both 
schirmer@12854
    27
  checking static types and determining runtime types in transition semantics.
schirmer@12854
    28
\end{itemize}
schirmer@12854
    29
*}
schirmer@12854
    30
schirmer@12854
    31
types	lenv
schirmer@12854
    32
	= "(lname, ty) table"   (* local variables, including This and Result *)
schirmer@12854
    33
schirmer@12854
    34
record env = 
schirmer@12854
    35
         prg:: "prog"    (* program *)
schirmer@12854
    36
         cls:: "qtname"  (* current package and class name *)
schirmer@12854
    37
         lcl:: "lenv"    (* local environment *)     
schirmer@12854
    38
  
schirmer@12854
    39
translations
schirmer@12854
    40
  "lenv" <= (type) "(lname, ty) table"
schirmer@12854
    41
  "lenv" <= (type) "lname \<Rightarrow> ty option"
schirmer@12854
    42
  "env" <= (type) "\<lparr>prg::prog,cls::qtname,lcl::lenv\<rparr>"
schirmer@12854
    43
  "env" <= (type) "\<lparr>prg::prog,cls::qtname,lcl::lenv,\<dots>::'a\<rparr>"
schirmer@12854
    44
schirmer@12854
    45
schirmer@12854
    46
schirmer@12854
    47
syntax
schirmer@12854
    48
  pkg :: "env \<Rightarrow> pname" (* select the current package from an environment *)
schirmer@12854
    49
translations
schirmer@12854
    50
  "pkg e" == "pid (cls e)"
schirmer@12854
    51
schirmer@12854
    52
section "Static overloading: maximally specific methods "
schirmer@12854
    53
schirmer@12854
    54
types
schirmer@12854
    55
  emhead = "ref_ty \<times> mhead"
schirmer@12854
    56
schirmer@12854
    57
(* Some mnemotic selectors for emhead *)
schirmer@12854
    58
constdefs 
schirmer@12854
    59
  "declrefT" :: "emhead \<Rightarrow> ref_ty"
schirmer@12854
    60
  "declrefT \<equiv> fst"
schirmer@12854
    61
schirmer@12854
    62
  "mhd"     :: "emhead \<Rightarrow> mhead"
schirmer@12854
    63
  "mhd \<equiv> snd"
schirmer@12854
    64
schirmer@12854
    65
lemma declrefT_simp[simp]:"declrefT (r,m) = r"
schirmer@12854
    66
by (simp add: declrefT_def)
schirmer@12854
    67
schirmer@12854
    68
lemma mhd_simp[simp]:"mhd (r,m) = m"
schirmer@12854
    69
by (simp add: mhd_def)
schirmer@12854
    70
schirmer@12854
    71
lemma static_mhd_simp[simp]: "static (mhd m) = is_static m"
schirmer@12854
    72
by (cases m) (simp add: member_is_static_simp mhd_def)
schirmer@12854
    73
schirmer@12854
    74
lemma mhd_resTy_simp [simp]: "resTy (mhd m) = resTy m"
schirmer@12854
    75
by (cases m) simp
schirmer@12854
    76
schirmer@12854
    77
lemma mhd_is_static_simp [simp]: "is_static (mhd m) = is_static m"
schirmer@12854
    78
by (cases m) simp
schirmer@12854
    79
schirmer@12854
    80
lemma mhd_accmodi_simp [simp]: "accmodi (mhd m) = accmodi m"
schirmer@12854
    81
by (cases m) simp
schirmer@12854
    82
schirmer@12854
    83
consts
schirmer@12854
    84
  cmheads        :: "prog \<Rightarrow> qtname \<Rightarrow> qtname \<Rightarrow> sig \<Rightarrow> emhead set"
schirmer@12854
    85
  Objectmheads   :: "prog \<Rightarrow> qtname           \<Rightarrow> sig \<Rightarrow> emhead set"
schirmer@12854
    86
  accObjectmheads:: "prog \<Rightarrow> qtname \<Rightarrow> ref_ty \<Rightarrow> sig \<Rightarrow> emhead set"
schirmer@12854
    87
  mheads         :: "prog \<Rightarrow> qtname \<Rightarrow> ref_ty \<Rightarrow> sig \<Rightarrow> emhead set"
schirmer@12854
    88
defs
schirmer@12854
    89
 cmheads_def:
schirmer@12854
    90
"cmheads G S C 
schirmer@12854
    91
  \<equiv> \<lambda>sig. (\<lambda>(Cls,mthd). (ClassT Cls,(mhead mthd))) ` o2s (accmethd G S C sig)"
schirmer@12854
    92
  Objectmheads_def:
schirmer@12854
    93
"Objectmheads G S  
schirmer@12854
    94
  \<equiv> \<lambda>sig. (\<lambda>(Cls,mthd). (ClassT Cls,(mhead mthd))) 
schirmer@12854
    95
    ` o2s (filter_tab (\<lambda>sig m. accmodi m \<noteq> Private) (accmethd G S Object) sig)"
schirmer@12854
    96
  accObjectmheads_def:
schirmer@12854
    97
"accObjectmheads G S T
schirmer@12854
    98
   \<equiv> if G\<turnstile>RefT T accessible_in (pid S)
schirmer@12854
    99
        then Objectmheads G S
schirmer@12854
   100
        else \<lambda>sig. {}"
schirmer@12854
   101
primrec
schirmer@12854
   102
"mheads G S  NullT     = (\<lambda>sig. {})"
schirmer@12854
   103
"mheads G S (IfaceT I) = (\<lambda>sig. (\<lambda>(I,h).(IfaceT I,h)) 
schirmer@12854
   104
                         ` accimethds G (pid S) I sig \<union> 
schirmer@12854
   105
                           accObjectmheads G S (IfaceT I) sig)"
schirmer@12854
   106
"mheads G S (ClassT C) = cmheads G S C"
schirmer@12854
   107
"mheads G S (ArrayT T) = accObjectmheads G S (ArrayT T)"
schirmer@12854
   108
schirmer@12854
   109
schirmer@12854
   110
(* more detailed than necessary for type-safety, see below. *)
schirmer@12854
   111
constdefs
schirmer@12854
   112
  (* applicable methods, cf. 15.11.2.1 *)
schirmer@12854
   113
  appl_methds   :: "prog \<Rightarrow> qtname \<Rightarrow>  ref_ty \<Rightarrow> sig \<Rightarrow> (emhead \<times> ty list)\<spacespace> set"
schirmer@12854
   114
 "appl_methds G S rt \<equiv> \<lambda> sig. 
schirmer@12854
   115
      {(mh,pTs') |mh pTs'. mh \<in> mheads G S rt \<lparr>name=name sig,parTs=pTs'\<rparr> \<and> 
schirmer@12854
   116
                           G\<turnstile>(parTs sig)[\<preceq>]pTs'}"
schirmer@12854
   117
schirmer@12854
   118
  (* more specific methods, cf. 15.11.2.2 *)
schirmer@12854
   119
  more_spec     :: "prog \<Rightarrow> emhead \<times> ty list \<Rightarrow> emhead \<times> ty list \<Rightarrow> bool"
schirmer@12854
   120
 "more_spec G \<equiv> \<lambda>(mh,pTs). \<lambda>(mh',pTs'). G\<turnstile>pTs[\<preceq>]pTs'"
schirmer@12854
   121
(*more_spec G \<equiv>\<lambda>((d,h),pTs). \<lambda>((d',h'),pTs'). G\<turnstile>RefT d\<preceq>RefT d'\<and>G\<turnstile>pTs[\<preceq>]pTs'*)
schirmer@12854
   122
schirmer@12854
   123
  (* maximally specific methods, cf. 15.11.2.2 *)
schirmer@12854
   124
   max_spec     :: "prog \<Rightarrow> qtname \<Rightarrow> ref_ty \<Rightarrow> sig \<Rightarrow> (emhead \<times> ty list)\<spacespace> set"
schirmer@12854
   125
schirmer@12854
   126
 "max_spec G S rt sig \<equiv>{m. m \<in>appl_methds G S rt sig \<and>
schirmer@12854
   127
		      (\<forall>m'\<in>appl_methds G S rt sig. more_spec G m' m \<longrightarrow> m'=m)}"
schirmer@12854
   128
(*
schirmer@12854
   129
rules (* all properties of more_spec, appl_methods and max_spec we actually need
schirmer@12854
   130
         these can easily be proven from the above definitions *)
schirmer@12854
   131
schirmer@12854
   132
max_spec2mheads "max_spec G S rt (mn, pTs) = insert (mh, pTs') A \<Longrightarrow>
schirmer@12854
   133
      mh\<in>mheads G S rt (mn, pTs') \<and> G\<turnstile>pTs[\<preceq>]pTs'"
schirmer@12854
   134
*)
schirmer@12854
   135
schirmer@12854
   136
lemma max_spec2appl_meths: 
schirmer@12854
   137
  "x \<in> max_spec G S T sig \<Longrightarrow> x \<in> appl_methds G S T sig" 
schirmer@12854
   138
by (auto simp: max_spec_def)
schirmer@12854
   139
schirmer@12854
   140
lemma appl_methsD: "(mh,pTs')\<in>appl_methds G S T \<lparr>name=mn,parTs=pTs\<rparr> \<Longrightarrow>  
schirmer@12854
   141
   mh \<in> mheads G S T \<lparr>name=mn,parTs=pTs'\<rparr> \<and> G\<turnstile>pTs[\<preceq>]pTs'"
schirmer@12854
   142
by (auto simp: appl_methds_def)
schirmer@12854
   143
schirmer@12854
   144
lemma max_spec2mheads: 
schirmer@12854
   145
"max_spec G S rt \<lparr>name=mn,parTs=pTs\<rparr> = insert (mh, pTs') A 
schirmer@12854
   146
 \<Longrightarrow> mh \<in> mheads G S rt \<lparr>name=mn,parTs=pTs'\<rparr> \<and> G\<turnstile>pTs[\<preceq>]pTs'"
schirmer@12854
   147
apply (auto dest: equalityD2 subsetD max_spec2appl_meths appl_methsD)
schirmer@12854
   148
done
schirmer@12854
   149
schirmer@12854
   150
schirmer@12854
   151
constdefs
schirmer@12854
   152
  empty_dt :: "dyn_ty"
schirmer@12854
   153
 "empty_dt \<equiv> \<lambda>a. None"
schirmer@12854
   154
schirmer@12854
   155
  invmode :: "('a::type)member_scheme \<Rightarrow> expr \<Rightarrow> inv_mode"
schirmer@12854
   156
"invmode m e \<equiv> if static m then Static else if e=Super then SuperM else IntVir"
schirmer@12854
   157
schirmer@12854
   158
lemma invmode_nonstatic [simp]: 
schirmer@12854
   159
  "invmode \<lparr>access=a,static=False,\<dots>=x\<rparr> (Acc (LVar e)) = IntVir"
schirmer@12854
   160
apply (unfold invmode_def)
schirmer@12854
   161
apply (simp (no_asm))
schirmer@12854
   162
done
schirmer@12854
   163
schirmer@12854
   164
schirmer@12854
   165
lemma invmode_Static_eq [simp]: "(invmode m e = Static) = static m"
schirmer@12854
   166
apply (unfold invmode_def)
schirmer@12854
   167
apply (simp (no_asm))
schirmer@12854
   168
done
schirmer@12854
   169
schirmer@12854
   170
schirmer@12854
   171
lemma invmode_IntVir_eq: "(invmode m e = IntVir) = (\<not>(static m) \<and> e\<noteq>Super)"
schirmer@12854
   172
apply (unfold invmode_def)
schirmer@12854
   173
apply (simp (no_asm))
schirmer@12854
   174
done
schirmer@12854
   175
schirmer@12854
   176
lemma Null_staticD: 
schirmer@12854
   177
  "a'=Null \<longrightarrow> (static m) \<Longrightarrow> invmode m e = IntVir \<longrightarrow> a' \<noteq> Null"
schirmer@12854
   178
apply (clarsimp simp add: invmode_IntVir_eq)
schirmer@12854
   179
done
schirmer@12854
   180
schirmer@12854
   181
schirmer@12854
   182
types tys  =        "ty + ty list"
schirmer@12854
   183
translations
schirmer@12854
   184
  "tys"   <= (type) "ty + ty list"
schirmer@12854
   185
schirmer@12854
   186
consts
schirmer@12854
   187
  wt    :: "(env\<spacespace> \<times> dyn_ty\<spacespace> \<times>  term \<times> tys) set"
schirmer@12854
   188
(*wt    :: " env \<Rightarrow> dyn_ty \<Rightarrow> (term \<times> tys) set" not feasible because of 
schirmer@12854
   189
					      \<spacespace>  changing env in Try stmt *)
schirmer@12854
   190
schirmer@12854
   191
syntax
schirmer@12854
   192
wt      :: "env \<Rightarrow> dyn_ty \<Rightarrow> [term,tys]  \<Rightarrow> bool" ("_,_|=_::_" [51,51,51,51] 50)
schirmer@12854
   193
wt_stmt :: "env \<Rightarrow> dyn_ty \<Rightarrow>  stmt       \<Rightarrow> bool" ("_,_|=_:<>" [51,51,51   ] 50)
schirmer@12854
   194
ty_expr :: "env \<Rightarrow> dyn_ty \<Rightarrow> [expr ,ty ] \<Rightarrow> bool" ("_,_|=_:-_" [51,51,51,51] 50)
schirmer@12854
   195
ty_var  :: "env \<Rightarrow> dyn_ty \<Rightarrow> [var  ,ty ] \<Rightarrow> bool" ("_,_|=_:=_" [51,51,51,51] 50)
schirmer@12854
   196
ty_exprs:: "env \<Rightarrow> dyn_ty \<Rightarrow> [expr list,
schirmer@12854
   197
	         \<spacespace>        \<spacespace>  ty   list] \<Rightarrow> bool" ("_,_|=_:#_" [51,51,51,51] 50)
schirmer@12854
   198
schirmer@12854
   199
syntax (xsymbols)
schirmer@12854
   200
wt      :: "env \<Rightarrow> dyn_ty \<Rightarrow> [term,tys] \<Rightarrow> bool" ("_,_\<Turnstile>_\<Colon>_"  [51,51,51,51] 50)
schirmer@12854
   201
wt_stmt :: "env \<Rightarrow> dyn_ty \<Rightarrow>  stmt       \<Rightarrow> bool" ("_,_\<Turnstile>_\<Colon>\<surd>"  [51,51,51   ] 50)
schirmer@12854
   202
ty_expr :: "env \<Rightarrow> dyn_ty \<Rightarrow> [expr ,ty ] \<Rightarrow> bool" ("_,_\<Turnstile>_\<Colon>-_" [51,51,51,51] 50)
schirmer@12854
   203
ty_var  :: "env \<Rightarrow> dyn_ty \<Rightarrow> [var  ,ty ] \<Rightarrow> bool" ("_,_\<Turnstile>_\<Colon>=_" [51,51,51,51] 50)
schirmer@12854
   204
ty_exprs:: "env \<Rightarrow> dyn_ty \<Rightarrow> [expr list,
schirmer@12854
   205
		  \<spacespace>        \<spacespace>  ty   list] \<Rightarrow> bool"("_,_\<Turnstile>_\<Colon>\<doteq>_" [51,51,51,51] 50)
schirmer@12854
   206
schirmer@12854
   207
translations
schirmer@12854
   208
	"E,dt\<Turnstile>t\<Colon>T" == "(E,dt,t,T) \<in> wt"
schirmer@12854
   209
	"E,dt\<Turnstile>s\<Colon>\<surd>"  == "E,dt\<Turnstile>In1r s\<Colon>Inl (PrimT Void)"
schirmer@12854
   210
	"E,dt\<Turnstile>e\<Colon>-T" == "E,dt\<Turnstile>In1l e\<Colon>Inl T"
schirmer@12854
   211
	"E,dt\<Turnstile>e\<Colon>=T" == "E,dt\<Turnstile>In2  e\<Colon>Inl T"
schirmer@12854
   212
	"E,dt\<Turnstile>e\<Colon>\<doteq>T" == "E,dt\<Turnstile>In3  e\<Colon>Inr T"
schirmer@12854
   213
schirmer@12854
   214
syntax (* for purely static typing *)
schirmer@12854
   215
  wt_      :: "env \<Rightarrow> [term,tys] \<Rightarrow> bool" ("_|-_::_" [51,51,51] 50)
schirmer@12854
   216
  wt_stmt_ :: "env \<Rightarrow>  stmt       \<Rightarrow> bool" ("_|-_:<>" [51,51   ] 50)
schirmer@12854
   217
  ty_expr_ :: "env \<Rightarrow> [expr ,ty ] \<Rightarrow> bool" ("_|-_:-_" [51,51,51] 50)
schirmer@12854
   218
  ty_var_  :: "env \<Rightarrow> [var  ,ty ] \<Rightarrow> bool" ("_|-_:=_" [51,51,51] 50)
schirmer@12854
   219
  ty_exprs_:: "env \<Rightarrow> [expr list,
schirmer@12854
   220
		     \<spacespace> ty   list] \<Rightarrow> bool" ("_|-_:#_" [51,51,51] 50)
schirmer@12854
   221
schirmer@12854
   222
syntax (xsymbols)
schirmer@12854
   223
  wt_      :: "env \<Rightarrow> [term,tys] \<Rightarrow> bool" ("_\<turnstile>_\<Colon>_"  [51,51,51] 50)
schirmer@12854
   224
  wt_stmt_ ::  "env \<Rightarrow>  stmt       \<Rightarrow> bool" ("_\<turnstile>_\<Colon>\<surd>"  [51,51   ] 50)
schirmer@12854
   225
  ty_expr_ :: "env \<Rightarrow> [expr ,ty ] \<Rightarrow> bool" ("_\<turnstile>_\<Colon>-_" [51,51,51] 50)
schirmer@12854
   226
  ty_var_  :: "env \<Rightarrow> [var  ,ty ] \<Rightarrow> bool" ("_\<turnstile>_\<Colon>=_" [51,51,51] 50)
schirmer@12854
   227
  ty_exprs_ :: "env \<Rightarrow> [expr list,
schirmer@12854
   228
		    \<spacespace>  ty   list] \<Rightarrow> bool" ("_\<turnstile>_\<Colon>\<doteq>_" [51,51,51] 50)
schirmer@12854
   229
schirmer@12854
   230
translations
schirmer@12854
   231
	"E\<turnstile>t\<Colon> T" == "E,empty_dt\<Turnstile>t\<Colon> T"
schirmer@12854
   232
	"E\<turnstile>s\<Colon>\<surd>" == "E,empty_dt\<Turnstile>s\<Colon>\<surd>"
schirmer@12854
   233
	"E\<turnstile>e\<Colon>-T" == "E,empty_dt\<Turnstile>e\<Colon>-T"
schirmer@12854
   234
	"E\<turnstile>e\<Colon>=T" == "E,empty_dt\<Turnstile>e\<Colon>=T"
schirmer@12854
   235
	"E\<turnstile>e\<Colon>\<doteq>T" == "E,empty_dt\<Turnstile>e\<Colon>\<doteq>T"
schirmer@12854
   236
schirmer@12854
   237
schirmer@12854
   238
inductive wt intros 
schirmer@12854
   239
schirmer@12854
   240
schirmer@12854
   241
(* well-typed statements *)
schirmer@12854
   242
schirmer@12854
   243
  Skip:					"E,dt\<Turnstile>Skip\<Colon>\<surd>"
schirmer@12854
   244
schirmer@12854
   245
  Expr:	"\<lbrakk>E,dt\<Turnstile>e\<Colon>-T\<rbrakk> \<Longrightarrow>
schirmer@12854
   246
					 E,dt\<Turnstile>Expr e\<Colon>\<surd>"
schirmer@12854
   247
  (* cf. 14.6 *)
schirmer@12854
   248
  Lab:  "E,dt\<Turnstile>c\<Colon>\<surd> \<Longrightarrow>                   
schirmer@12854
   249
                                         E,dt\<Turnstile>l\<bullet> c\<Colon>\<surd>" 
schirmer@12854
   250
schirmer@12854
   251
  Comp:	"\<lbrakk>E,dt\<Turnstile>c1\<Colon>\<surd>; 
schirmer@12854
   252
	  E,dt\<Turnstile>c2\<Colon>\<surd>\<rbrakk> \<Longrightarrow>
schirmer@12854
   253
					 E,dt\<Turnstile>c1;; c2\<Colon>\<surd>"
schirmer@12854
   254
schirmer@12854
   255
  (* cf. 14.8 *)
schirmer@12854
   256
  If:	"\<lbrakk>E,dt\<Turnstile>e\<Colon>-PrimT Boolean;
schirmer@12854
   257
	  E,dt\<Turnstile>c1\<Colon>\<surd>;
schirmer@12854
   258
	  E,dt\<Turnstile>c2\<Colon>\<surd>\<rbrakk> \<Longrightarrow>
schirmer@12854
   259
					 E,dt\<Turnstile>If(e) c1 Else c2\<Colon>\<surd>"
schirmer@12854
   260
schirmer@12854
   261
  (* cf. 14.10 *)
schirmer@12854
   262
  Loop:	"\<lbrakk>E,dt\<Turnstile>e\<Colon>-PrimT Boolean;
schirmer@12854
   263
	  E,dt\<Turnstile>c\<Colon>\<surd>\<rbrakk> \<Longrightarrow>
schirmer@12854
   264
					 E,dt\<Turnstile>l\<bullet> While(e) c\<Colon>\<surd>"
schirmer@12854
   265
  (* cf. 14.13, 14.15, 14.16 *)
schirmer@12854
   266
  Do:                                   "E,dt\<Turnstile>Do jump\<Colon>\<surd>"
schirmer@12854
   267
schirmer@12854
   268
  (* cf. 14.16 *)
schirmer@12854
   269
  Throw: "\<lbrakk>E,dt\<Turnstile>e\<Colon>-Class tn;
schirmer@12854
   270
	  prg E\<turnstile>tn\<preceq>\<^sub>C SXcpt Throwable\<rbrakk> \<Longrightarrow>
schirmer@12854
   271
					 E,dt\<Turnstile>Throw e\<Colon>\<surd>"
schirmer@12854
   272
  (* cf. 14.18 *)
schirmer@12854
   273
  Try:	"\<lbrakk>E,dt\<Turnstile>c1\<Colon>\<surd>; prg E\<turnstile>tn\<preceq>\<^sub>C SXcpt Throwable;
schirmer@12854
   274
	  lcl E (VName vn)=None; E \<lparr>lcl := lcl E(VName vn\<mapsto>Class tn)\<rparr>,dt\<Turnstile>c2\<Colon>\<surd>\<rbrakk>
schirmer@12854
   275
          \<Longrightarrow>
schirmer@12854
   276
					 E,dt\<Turnstile>Try c1 Catch(tn vn) c2\<Colon>\<surd>"
schirmer@12854
   277
schirmer@12854
   278
  (* cf. 14.18 *)
schirmer@12854
   279
  Fin:	"\<lbrakk>E,dt\<Turnstile>c1\<Colon>\<surd>; E,dt\<Turnstile>c2\<Colon>\<surd>\<rbrakk> \<Longrightarrow>
schirmer@12854
   280
					 E,dt\<Turnstile>c1 Finally c2\<Colon>\<surd>"
schirmer@12854
   281
schirmer@12854
   282
  Init:	"\<lbrakk>is_class (prg E) C\<rbrakk> \<Longrightarrow>
schirmer@12854
   283
					 E,dt\<Turnstile>Init C\<Colon>\<surd>"
schirmer@12854
   284
  (* Init is created on the fly during evaluation (see Eval.thy). The class
schirmer@12854
   285
   * isn't necessarily accessible from the points Init is called. Therefor
schirmer@12854
   286
   * we only demand is_class and not is_acc_class here 
schirmer@12854
   287
   *)
schirmer@12854
   288
schirmer@12854
   289
(* well-typed expressions *)
schirmer@12854
   290
schirmer@12854
   291
  (* cf. 15.8 *)
schirmer@12854
   292
  NewC:	"\<lbrakk>is_acc_class (prg E) (pkg E) C\<rbrakk> \<Longrightarrow>
schirmer@12854
   293
					 E,dt\<Turnstile>NewC C\<Colon>-Class C"
schirmer@12854
   294
  (* cf. 15.9 *)
schirmer@12854
   295
  NewA:	"\<lbrakk>is_acc_type (prg E) (pkg E) T;
schirmer@12854
   296
	  E,dt\<Turnstile>i\<Colon>-PrimT Integer\<rbrakk> \<Longrightarrow>
schirmer@12854
   297
					 E,dt\<Turnstile>New T[i]\<Colon>-T.[]"
schirmer@12854
   298
schirmer@12854
   299
  (* cf. 15.15 *)
schirmer@12854
   300
  Cast:	"\<lbrakk>E,dt\<Turnstile>e\<Colon>-T; is_acc_type (prg E) (pkg E) T';
schirmer@12854
   301
	  prg E\<turnstile>T\<preceq>? T'\<rbrakk> \<Longrightarrow>
schirmer@12854
   302
					 E,dt\<Turnstile>Cast T' e\<Colon>-T'"
schirmer@12854
   303
schirmer@12854
   304
  (* cf. 15.19.2 *)
schirmer@12854
   305
  Inst:	"\<lbrakk>E,dt\<Turnstile>e\<Colon>-RefT T; is_acc_type (prg E) (pkg E) (RefT T');
schirmer@12854
   306
	  prg E\<turnstile>RefT T\<preceq>? RefT T'\<rbrakk> \<Longrightarrow>
schirmer@12854
   307
					 E,dt\<Turnstile>e InstOf T'\<Colon>-PrimT Boolean"
schirmer@12854
   308
schirmer@12854
   309
  (* cf. 15.7.1 *)
schirmer@12854
   310
  Lit:	"\<lbrakk>typeof dt x = Some T\<rbrakk> \<Longrightarrow>
schirmer@12854
   311
					 E,dt\<Turnstile>Lit x\<Colon>-T"
schirmer@12854
   312
schirmer@12854
   313
  (* cf. 15.10.2, 15.11.1 *)
schirmer@12854
   314
  Super: "\<lbrakk>lcl E This = Some (Class C); C \<noteq> Object;
schirmer@12854
   315
	  class (prg E) C = Some c\<rbrakk> \<Longrightarrow>
schirmer@12854
   316
					 E,dt\<Turnstile>Super\<Colon>-Class (super c)"
schirmer@12854
   317
schirmer@12854
   318
  (* cf. 15.13.1, 15.10.1, 15.12 *)
schirmer@12854
   319
  Acc:	"\<lbrakk>E,dt\<Turnstile>va\<Colon>=T\<rbrakk> \<Longrightarrow>
schirmer@12854
   320
					 E,dt\<Turnstile>Acc va\<Colon>-T"
schirmer@12854
   321
schirmer@12854
   322
  (* cf. 15.25, 15.25.1 *)
schirmer@12854
   323
  Ass:	"\<lbrakk>E,dt\<Turnstile>va\<Colon>=T; va \<noteq> LVar This;
schirmer@12854
   324
	  E,dt\<Turnstile>v \<Colon>-T';
schirmer@12854
   325
	  prg E\<turnstile>T'\<preceq>T\<rbrakk> \<Longrightarrow>
schirmer@12854
   326
					 E,dt\<Turnstile>va:=v\<Colon>-T'"
schirmer@12854
   327
schirmer@12854
   328
  (* cf. 15.24 *)
schirmer@12854
   329
  Cond:	"\<lbrakk>E,dt\<Turnstile>e0\<Colon>-PrimT Boolean;
schirmer@12854
   330
	  E,dt\<Turnstile>e1\<Colon>-T1; E,dt\<Turnstile>e2\<Colon>-T2;
schirmer@12854
   331
	  prg E\<turnstile>T1\<preceq>T2 \<and> T = T2  \<or>  prg E\<turnstile>T2\<preceq>T1 \<and> T = T1\<rbrakk> \<Longrightarrow>
schirmer@12854
   332
					 E,dt\<Turnstile>e0 ? e1 : e2\<Colon>-T"
schirmer@12854
   333
schirmer@12854
   334
  (* cf. 15.11.1, 15.11.2, 15.11.3 *)
schirmer@12854
   335
  Call:	"\<lbrakk>E,dt\<Turnstile>e\<Colon>-RefT statT;
schirmer@12854
   336
	  E,dt\<Turnstile>ps\<Colon>\<doteq>pTs;
schirmer@12854
   337
	  max_spec (prg E) (cls E) statT \<lparr>name=mn,parTs=pTs\<rparr> 
schirmer@12854
   338
            = {((statDeclT,m),pTs')}
schirmer@12854
   339
         \<rbrakk> \<Longrightarrow>
schirmer@12854
   340
		   E,dt\<Turnstile>{statT,invmode m e}e\<cdot>mn({pTs'}ps)\<Colon>-(resTy m)"
schirmer@12854
   341
schirmer@12854
   342
  Methd: "\<lbrakk>is_class (prg E) C;
schirmer@12854
   343
	  methd (prg E) C sig = Some m;
schirmer@12854
   344
	  E,dt\<Turnstile>Body (declclass m) (stmt (mbody (mthd m)))\<Colon>-T\<rbrakk> \<Longrightarrow>
schirmer@12854
   345
					 E,dt\<Turnstile>Methd C sig\<Colon>-T"
schirmer@12854
   346
 (* The class C is the dynamic class of the method call (cf. Eval.thy). 
schirmer@12854
   347
  * It hasn't got to be directly accessible from the current package (pkg E). 
schirmer@12854
   348
  * Only the static class must be accessible (enshured indirectly by Call). 
schirmer@12854
   349
  *)
schirmer@12854
   350
schirmer@12854
   351
  Body:	"\<lbrakk>is_class (prg E) D;
schirmer@12854
   352
	  E,dt\<Turnstile>blk\<Colon>\<surd>;
schirmer@12854
   353
	  (lcl E) Result = Some T;
schirmer@12854
   354
          is_type (prg E) T\<rbrakk> \<Longrightarrow>
schirmer@12854
   355
   					 E,dt\<Turnstile>Body D blk\<Colon>-T"
schirmer@12854
   356
  (* the class D implementing the method must not directly be accessible 
schirmer@12854
   357
   * from the current package (pkg E), but can also be indirectly accessible 
schirmer@12854
   358
   * due to inheritance (enshured in Call)
schirmer@12854
   359
   * The result type hasn't got to be accessible in Java! (If it is not 
schirmer@12854
   360
   * accessible you can only assign it to Object) 
schirmer@12854
   361
   *)
schirmer@12854
   362
schirmer@12854
   363
(* well-typed variables *)
schirmer@12854
   364
schirmer@12854
   365
  (* cf. 15.13.1 *)
schirmer@12854
   366
  LVar:	"\<lbrakk>lcl E vn = Some T; is_acc_type (prg E) (pkg E) T\<rbrakk> \<Longrightarrow>
schirmer@12854
   367
					 E,dt\<Turnstile>LVar vn\<Colon>=T"
schirmer@12854
   368
  (* cf. 15.10.1 *)
schirmer@12854
   369
  FVar:	"\<lbrakk>E,dt\<Turnstile>e\<Colon>-Class C; 
schirmer@12854
   370
	  accfield (prg E) (cls E) C fn = Some (fd,f)\<rbrakk> \<Longrightarrow>
schirmer@12854
   371
			                 E,dt\<Turnstile>{fd,static f}e..fn\<Colon>=(type f)"
schirmer@12854
   372
  (* cf. 15.12 *)
schirmer@12854
   373
  AVar:	"\<lbrakk>E,dt\<Turnstile>e\<Colon>-T.[]; 
schirmer@12854
   374
	  E,dt\<Turnstile>i\<Colon>-PrimT Integer\<rbrakk> \<Longrightarrow>
schirmer@12854
   375
					 E,dt\<Turnstile>e.[i]\<Colon>=T"
schirmer@12854
   376
schirmer@12854
   377
schirmer@12854
   378
(* well-typed expression lists *)
schirmer@12854
   379
schirmer@12854
   380
  (* cf. 15.11.??? *)
schirmer@12854
   381
  Nil:					"E,dt\<Turnstile>[]\<Colon>\<doteq>[]"
schirmer@12854
   382
schirmer@12854
   383
  (* cf. 15.11.??? *)
schirmer@12854
   384
  Cons:	"\<lbrakk>E,dt\<Turnstile>e \<Colon>-T;
schirmer@12854
   385
	  E,dt\<Turnstile>es\<Colon>\<doteq>Ts\<rbrakk> \<Longrightarrow>
schirmer@12854
   386
					 E,dt\<Turnstile>e#es\<Colon>\<doteq>T#Ts"
schirmer@12854
   387
schirmer@12854
   388
schirmer@12854
   389
declare not_None_eq [simp del] 
schirmer@12854
   390
declare split_if [split del] split_if_asm [split del]
schirmer@12854
   391
declare split_paired_All [simp del] split_paired_Ex [simp del]
schirmer@12854
   392
ML_setup {*
schirmer@12854
   393
simpset_ref() := simpset() delloop "split_all_tac"
schirmer@12854
   394
*}
schirmer@12854
   395
inductive_cases wt_stmt_cases: "E,dt\<Turnstile>c\<Colon>\<surd>"
schirmer@12854
   396
inductive_cases wt_elim_cases:
schirmer@12854
   397
	"E,dt\<Turnstile>In2  (LVar vn)               \<Colon>T"
schirmer@12854
   398
	"E,dt\<Turnstile>In2  ({fd,s}e..fn)           \<Colon>T"
schirmer@12854
   399
	"E,dt\<Turnstile>In2  (e.[i])                 \<Colon>T"
schirmer@12854
   400
	"E,dt\<Turnstile>In1l (NewC C)                \<Colon>T"
schirmer@12854
   401
	"E,dt\<Turnstile>In1l (New T'[i])             \<Colon>T"
schirmer@12854
   402
	"E,dt\<Turnstile>In1l (Cast T' e)             \<Colon>T"
schirmer@12854
   403
	"E,dt\<Turnstile>In1l (e InstOf T')           \<Colon>T"
schirmer@12854
   404
	"E,dt\<Turnstile>In1l (Lit x)                 \<Colon>T"
schirmer@12854
   405
	"E,dt\<Turnstile>In1l (Super)                 \<Colon>T"
schirmer@12854
   406
	"E,dt\<Turnstile>In1l (Acc va)                \<Colon>T"
schirmer@12854
   407
	"E,dt\<Turnstile>In1l (Ass va v)              \<Colon>T"
schirmer@12854
   408
	"E,dt\<Turnstile>In1l (e0 ? e1 : e2)          \<Colon>T"
schirmer@12854
   409
	"E,dt\<Turnstile>In1l ({statT,mode}e\<cdot>mn({pT'}p))\<Colon>T"
schirmer@12854
   410
	"E,dt\<Turnstile>In1l (Methd C sig)           \<Colon>T"
schirmer@12854
   411
	"E,dt\<Turnstile>In1l (Body D blk)            \<Colon>T"
schirmer@12854
   412
	"E,dt\<Turnstile>In3  ([])                    \<Colon>Ts"
schirmer@12854
   413
	"E,dt\<Turnstile>In3  (e#es)                  \<Colon>Ts"
schirmer@12854
   414
	"E,dt\<Turnstile>In1r  Skip                   \<Colon>x"
schirmer@12854
   415
	"E,dt\<Turnstile>In1r (Expr e)                \<Colon>x"
schirmer@12854
   416
	"E,dt\<Turnstile>In1r (c1;; c2)               \<Colon>x"
schirmer@12854
   417
        "E,dt\<Turnstile>In1r (l\<bullet> c)                  \<Colon>x" 
schirmer@12854
   418
	"E,dt\<Turnstile>In1r (If(e) c1 Else c2)      \<Colon>x"
schirmer@12854
   419
	"E,dt\<Turnstile>In1r (l\<bullet> While(e) c)         \<Colon>x"
schirmer@12854
   420
        "E,dt\<Turnstile>In1r (Do jump)               \<Colon>x"
schirmer@12854
   421
	"E,dt\<Turnstile>In1r (Throw e)               \<Colon>x"
schirmer@12854
   422
	"E,dt\<Turnstile>In1r (Try c1 Catch(tn vn) c2)\<Colon>x"
schirmer@12854
   423
	"E,dt\<Turnstile>In1r (c1 Finally c2)         \<Colon>x"
schirmer@12854
   424
	"E,dt\<Turnstile>In1r (Init C)                \<Colon>x"
schirmer@12854
   425
declare not_None_eq [simp] 
schirmer@12854
   426
declare split_if [split] split_if_asm [split]
schirmer@12854
   427
declare split_paired_All [simp] split_paired_Ex [simp]
schirmer@12854
   428
ML_setup {*
schirmer@12854
   429
simpset_ref() := simpset() addloop ("split_all_tac", split_all_tac)
schirmer@12854
   430
*}
schirmer@12854
   431
schirmer@12854
   432
lemma is_acc_class_is_accessible: 
schirmer@12854
   433
  "is_acc_class G P C \<Longrightarrow> G\<turnstile>(Class C) accessible_in P"
schirmer@12854
   434
by (auto simp add: is_acc_class_def)
schirmer@12854
   435
schirmer@12854
   436
lemma is_acc_iface_is_iface: "is_acc_iface G P I \<Longrightarrow> is_iface G I"
schirmer@12854
   437
by (auto simp add: is_acc_iface_def)
schirmer@12854
   438
schirmer@12854
   439
lemma is_acc_iface_is_accessible: 
schirmer@12854
   440
  "is_acc_iface G P I \<Longrightarrow> G\<turnstile>(Iface I) accessible_in P"
schirmer@12854
   441
by (auto simp add: is_acc_iface_def)
schirmer@12854
   442
schirmer@12854
   443
lemma is_acc_type_is_type: "is_acc_type G P T \<Longrightarrow> is_type G T"
schirmer@12854
   444
by (auto simp add: is_acc_type_def)
schirmer@12854
   445
schirmer@12854
   446
lemma is_acc_iface_is_accessible: "is_acc_type G P T \<Longrightarrow> G\<turnstile>T accessible_in P"
schirmer@12854
   447
by (auto simp add: is_acc_type_def)
schirmer@12854
   448
schirmer@12854
   449
lemma wt_Methd_is_methd: 
schirmer@12854
   450
  "E\<turnstile>In1l (Methd C sig)\<Colon>T \<Longrightarrow> is_methd (prg E) C sig"
schirmer@12854
   451
apply (erule_tac wt_elim_cases)
schirmer@12854
   452
apply clarsimp
schirmer@12854
   453
apply (erule is_methdI, assumption)
schirmer@12854
   454
done
schirmer@12854
   455
schirmer@12854
   456
(* Special versions of some typing rules, better suited to pattern match the
schirmer@12854
   457
 * conclusion (no selectors in the conclusion\<dots>)
schirmer@12854
   458
 *)
schirmer@12854
   459
schirmer@12854
   460
lemma wt_Super:
schirmer@12854
   461
"\<lbrakk>lcl E This = Some (Class C); C \<noteq> Object;
schirmer@12854
   462
  class (prg E) C = Some c;D=super c\<rbrakk> 
schirmer@12854
   463
 \<Longrightarrow> E,dt\<Turnstile>Super\<Colon>-Class D"
schirmer@12854
   464
by (auto elim: wt.Super)
schirmer@12854
   465
 
schirmer@12854
   466
lemma wt_Call: 
schirmer@12854
   467
"\<lbrakk>E,dt\<Turnstile>e\<Colon>-RefT statT; E,dt\<Turnstile>ps\<Colon>\<doteq>pTs;  
schirmer@12854
   468
  max_spec (prg E) (cls E) statT \<lparr>name=mn,parTs=pTs\<rparr> 
schirmer@12854
   469
    = {((statDeclC,m),pTs')};rT=(resTy m);   
schirmer@12854
   470
 mode = invmode m e\<rbrakk> \<Longrightarrow> E,dt\<Turnstile>{statT,mode}e\<cdot>mn({pTs'}ps)\<Colon>-rT"
schirmer@12854
   471
by (auto elim: wt.Call)
schirmer@12854
   472
schirmer@12854
   473
schirmer@12854
   474
schirmer@12854
   475
lemma invocationTypeExpr_noClassD: 
schirmer@12854
   476
"\<lbrakk> E\<turnstile>e\<Colon>-RefT statT\<rbrakk>
schirmer@12854
   477
 \<Longrightarrow> (\<forall> statC. statT \<noteq> ClassT statC) \<longrightarrow> invmode m e \<noteq> SuperM"
schirmer@12854
   478
proof -
schirmer@12854
   479
  assume wt: "E\<turnstile>e\<Colon>-RefT statT"
schirmer@12854
   480
  show ?thesis
schirmer@12854
   481
  proof (cases "e=Super")
schirmer@12854
   482
    case True
schirmer@12854
   483
    with wt obtain "C" where "statT = ClassT C" by (blast elim: wt_elim_cases)
schirmer@12854
   484
    then show ?thesis by blast
schirmer@12854
   485
  next 
schirmer@12854
   486
    case False then show ?thesis 
schirmer@12854
   487
      by (auto simp add: invmode_def split: split_if_asm)
schirmer@12854
   488
  qed
schirmer@12854
   489
qed
schirmer@12854
   490
schirmer@12854
   491
lemma wt_Super: 
schirmer@12854
   492
"\<lbrakk>lcl E This = Some (Class C); C \<noteq> Object; class (prg E) C = Some c; D=super c\<rbrakk> 
schirmer@12854
   493
\<Longrightarrow> E,dt\<Turnstile>Super\<Colon>-Class D"
schirmer@12854
   494
by (auto elim: wt.Super)
schirmer@12854
   495
schirmer@12854
   496
schirmer@12854
   497
lemma wt_FVar:	
schirmer@12854
   498
"\<lbrakk>E,dt\<Turnstile>e\<Colon>-Class C; accfield (prg E) (cls E) C fn = Some (fd,f);
schirmer@12854
   499
  sf=static f; fT=(type f)\<rbrakk> \<Longrightarrow> E,dt\<Turnstile>{fd,sf}e..fn\<Colon>=fT"
schirmer@12854
   500
by (auto elim: wt.FVar)
schirmer@12854
   501
schirmer@12854
   502
lemma wt_init [iff]: "E,dt\<Turnstile>Init C\<Colon>\<surd> = is_class (prg E) C"
schirmer@12854
   503
by (auto elim: wt_elim_cases intro: "wt.Init")
schirmer@12854
   504
schirmer@12854
   505
declare wt.Skip [iff]
schirmer@12854
   506
schirmer@12854
   507
lemma wt_StatRef: 
schirmer@12854
   508
  "is_acc_type (prg E) (pkg E) (RefT rt) \<Longrightarrow> E\<turnstile>StatRef rt\<Colon>-RefT rt"
schirmer@12854
   509
apply (rule wt.Cast)
schirmer@12854
   510
apply  (rule wt.Lit)
schirmer@12854
   511
apply   (simp (no_asm))
schirmer@12854
   512
apply  (simp (no_asm_simp))
schirmer@12854
   513
apply (rule cast.widen)
schirmer@12854
   514
apply (simp (no_asm))
schirmer@12854
   515
done
schirmer@12854
   516
schirmer@12854
   517
lemma wt_Inj_elim: 
schirmer@12854
   518
  "\<And>E. E,dt\<Turnstile>t\<Colon>U \<Longrightarrow> case t of 
schirmer@12854
   519
                       In1 ec \<Rightarrow> (case ec of 
schirmer@12854
   520
                                    Inl e \<Rightarrow> \<exists>T. U=Inl T  
schirmer@12854
   521
                                  | Inr s \<Rightarrow> U=Inl (PrimT Void))  
schirmer@12854
   522
                     | In2 e \<Rightarrow> (\<exists>T. U=Inl T) 
schirmer@12854
   523
                     | In3 e \<Rightarrow> (\<exists>T. U=Inr T)"
schirmer@12854
   524
apply (erule wt.induct)
schirmer@12854
   525
apply auto
schirmer@12854
   526
done
schirmer@12854
   527
schirmer@12854
   528
ML {*
schirmer@12854
   529
fun wt_fun name inj rhs =
schirmer@12854
   530
let
schirmer@12854
   531
  val lhs = "E,dt\<Turnstile>" ^ inj ^ " t\<Colon>U"
schirmer@12854
   532
  val () = qed_goal name (the_context()) (lhs ^ " = (" ^ rhs ^ ")") 
schirmer@12854
   533
	(K [Auto_tac, ALLGOALS (ftac (thm "wt_Inj_elim")) THEN Auto_tac])
schirmer@12854
   534
  fun is_Inj (Const (inj,_) $ _) = true
schirmer@12854
   535
    | is_Inj _                   = false
schirmer@12854
   536
  fun pred (t as (_ $ (Const ("Pair",_) $
schirmer@12854
   537
     _ $ (Const ("Pair", _) $ _ $ (Const ("Pair", _) $ _ $
schirmer@12854
   538
       x))) $ _ )) = is_Inj x
schirmer@12854
   539
in
schirmer@12854
   540
  make_simproc name lhs pred (thm name)
schirmer@12854
   541
end
schirmer@12854
   542
schirmer@12854
   543
val wt_expr_proc  = wt_fun "wt_expr_eq"  "In1l" "\<exists>T.  U=Inl T  \<and> E,dt\<Turnstile>t\<Colon>-T"
schirmer@12854
   544
val wt_var_proc   = wt_fun "wt_var_eq"   "In2"  "\<exists>T.  U=Inl T  \<and> E,dt\<Turnstile>t\<Colon>=T"
schirmer@12854
   545
val wt_exprs_proc = wt_fun "wt_exprs_eq" "In3"  "\<exists>Ts. U=Inr Ts \<and> E,dt\<Turnstile>t\<Colon>\<doteq>Ts"
schirmer@12854
   546
val wt_stmt_proc  = wt_fun "wt_stmt_eq"  "In1r" "U=Inl(PrimT Void)\<and>E,dt\<Turnstile>t\<Colon>\<surd>"
schirmer@12854
   547
*}
schirmer@12854
   548
schirmer@12854
   549
ML {*
schirmer@12854
   550
Addsimprocs [wt_expr_proc,wt_var_proc,wt_exprs_proc,wt_stmt_proc]
schirmer@12854
   551
*}
schirmer@12854
   552
schirmer@12854
   553
lemma Inj_eq_lemma [simp]: 
schirmer@12854
   554
  "(\<forall>T. (\<exists>T'. T = Inj T' \<and> P T') \<longrightarrow> Q T) = (\<forall>T'. P T' \<longrightarrow> Q (Inj T'))"
schirmer@12854
   555
by auto
schirmer@12854
   556
schirmer@12854
   557
(* unused *)
schirmer@12854
   558
lemma single_valued_tys_lemma [rule_format (no_asm)]: 
schirmer@12854
   559
  "\<forall>S T. G\<turnstile>S\<preceq>T \<longrightarrow> G\<turnstile>T\<preceq>S \<longrightarrow> S = T \<Longrightarrow> E,dt\<Turnstile>t\<Colon>T \<Longrightarrow>  
schirmer@12854
   560
     G = prg E \<longrightarrow> (\<forall>T'. E,dt\<Turnstile>t\<Colon>T' \<longrightarrow> T  = T')"
schirmer@12854
   561
apply (cases "E", erule wt.induct)
schirmer@12854
   562
apply (safe del: disjE)
schirmer@12854
   563
apply (simp_all (no_asm_use) split del: split_if_asm)
schirmer@12854
   564
apply (safe del: disjE)
schirmer@12854
   565
(* 17 subgoals *)
schirmer@12854
   566
apply (tactic {* ALLGOALS (fn i => if i = 9 then EVERY'[thin_tac "?E,dt\<Turnstile>e0\<Colon>-PrimT Boolean", thin_tac "?E,dt\<Turnstile>e1\<Colon>-?T1", thin_tac "?E,dt\<Turnstile>e2\<Colon>-?T2"] i else thin_tac "All ?P" i) *})
schirmer@12854
   567
(*apply (safe del: disjE elim!: wt_elim_cases)*)
schirmer@12854
   568
apply (tactic {*ALLGOALS (eresolve_tac (thms "wt_elim_cases"))*})
schirmer@12854
   569
apply (simp_all (no_asm_use) split del: split_if_asm)
schirmer@12854
   570
apply (erule_tac [10] V = "All ?P" in thin_rl) (* Call *)
schirmer@12854
   571
apply ((blast del: equalityCE dest: sym [THEN trans])+)
schirmer@12854
   572
done
schirmer@12854
   573
schirmer@12854
   574
(* unused *)
schirmer@12854
   575
lemma single_valued_tys: 
schirmer@12854
   576
"ws_prog (prg E) \<Longrightarrow> single_valued {(t,T). E,dt\<Turnstile>t\<Colon>T}"
schirmer@12854
   577
apply (unfold single_valued_def)
schirmer@12854
   578
apply clarsimp
schirmer@12854
   579
apply (rule single_valued_tys_lemma)
schirmer@12854
   580
apply (auto intro!: widen_antisym)
schirmer@12854
   581
done
schirmer@12854
   582
schirmer@12854
   583
lemma typeof_empty_is_type [rule_format (no_asm)]: 
schirmer@12854
   584
  "typeof (\<lambda>a. None) v = Some T \<longrightarrow> is_type G T"
schirmer@12854
   585
apply (rule val.induct)
schirmer@12854
   586
apply    	auto
schirmer@12854
   587
done
schirmer@12854
   588
schirmer@12854
   589
(* unused *)
schirmer@12854
   590
lemma typeof_is_type [rule_format (no_asm)]: 
schirmer@12854
   591
 "(\<forall>a. v \<noteq> Addr a) \<longrightarrow> (\<exists>T. typeof dt v = Some T \<and> is_type G T)"
schirmer@12854
   592
apply (rule val.induct)
schirmer@12854
   593
prefer 5 
schirmer@12854
   594
apply     fast
schirmer@12854
   595
apply  (simp_all (no_asm))
schirmer@12854
   596
done
schirmer@12854
   597
schirmer@12854
   598
end