src/HOL/MicroJava/J/WellForm.thy
author wenzelm
Sat Nov 01 14:20:38 2014 +0100 (2014-11-01)
changeset 58860 fee7cfa69c50
parent 56073 29e308b56d23
child 58886 8a6cac7c7247
permissions -rw-r--r--
eliminated spurious semicolons;
     1 (*  Title:      HOL/MicroJava/J/WellForm.thy
     2     Author:     David von Oheimb
     3     Copyright   1999 Technische Universitaet Muenchen
     4 *)
     5 
     6 header {* \isaheader{Well-formedness of Java programs} *}
     7 
     8 theory WellForm
     9 imports TypeRel SystemClasses
    10 begin
    11 
    12 text {*
    13 for static checks on expressions and statements, see WellType.
    14 
    15 \begin{description}
    16 \item[improvements over Java Specification 1.0 (cf. 8.4.6.3, 8.4.6.4, 9.4.1):]\ \\
    17 \begin{itemize}
    18 \item a method implementing or overwriting another method may have a result type
    19 that widens to the result type of the other method (instead of identical type)
    20 \end{itemize}
    21 
    22 \item[simplifications:]\ \\
    23 \begin{itemize}
    24 \item for uniformity, Object is assumed to be declared like any other class
    25 \end{itemize}
    26 \end{description}
    27 *}
    28 type_synonym 'c wf_mb = "'c prog => cname => 'c mdecl => bool"
    29 
    30 definition wf_syscls :: "'c prog => bool" where
    31 "wf_syscls G == let cs = set G in Object \<in> fst ` cs \<and> (\<forall>x. Xcpt x \<in> fst ` cs)"
    32 
    33 definition wf_fdecl :: "'c prog => fdecl => bool" where
    34 "wf_fdecl G == \<lambda>(fn,ft). is_type G ft"
    35 
    36 definition wf_mhead :: "'c prog => sig => ty => bool" where
    37 "wf_mhead G == \<lambda>(mn,pTs) rT. (\<forall>T\<in>set pTs. is_type G T) \<and> is_type G rT"
    38 
    39 definition ws_cdecl :: "'c prog => 'c cdecl => bool" where
    40 "ws_cdecl G ==
    41    \<lambda>(C,(D,fs,ms)).
    42   (\<forall>f\<in>set fs. wf_fdecl G         f) \<and>  unique fs \<and>
    43   (\<forall>(sig,rT,mb)\<in>set ms. wf_mhead G sig rT) \<and> unique ms \<and>
    44   (C \<noteq> Object \<longrightarrow> is_class G D \<and>  \<not>G\<turnstile>D\<preceq>C C)"
    45 
    46 definition ws_prog :: "'c prog => bool" where
    47 "ws_prog G == 
    48   wf_syscls G \<and> (\<forall>c\<in>set G. ws_cdecl G c) \<and> unique G"
    49 
    50 definition wf_mrT   :: "'c prog => 'c cdecl => bool" where
    51 "wf_mrT G ==
    52    \<lambda>(C,(D,fs,ms)).
    53   (C \<noteq> Object \<longrightarrow> (\<forall>(sig,rT,b)\<in>set ms. \<forall>D' rT' b'.
    54                       method(G,D) sig = Some(D',rT',b') --> G\<turnstile>rT\<preceq>rT'))"
    55 
    56 definition wf_cdecl_mdecl :: "'c wf_mb => 'c prog => 'c cdecl => bool" where
    57 "wf_cdecl_mdecl wf_mb G ==
    58    \<lambda>(C,(D,fs,ms)). (\<forall>m\<in>set ms. wf_mb G C m)"
    59 
    60 definition wf_prog :: "'c wf_mb => 'c prog => bool" where
    61 "wf_prog wf_mb G == 
    62      ws_prog G \<and> (\<forall>c\<in> set G. wf_mrT G c \<and> wf_cdecl_mdecl wf_mb G c)"
    63 
    64 definition wf_mdecl :: "'c wf_mb => 'c wf_mb" where
    65 "wf_mdecl wf_mb G C == \<lambda>(sig,rT,mb). wf_mhead G sig rT \<and> wf_mb G C (sig,rT,mb)"
    66 
    67 definition wf_cdecl :: "'c wf_mb => 'c prog => 'c cdecl => bool" where
    68 "wf_cdecl wf_mb G ==
    69    \<lambda>(C,(D,fs,ms)).
    70   (\<forall>f\<in>set fs. wf_fdecl G         f) \<and>  unique fs \<and>
    71   (\<forall>m\<in>set ms. wf_mdecl wf_mb G C m) \<and>  unique ms \<and>
    72   (C \<noteq> Object \<longrightarrow> is_class G D \<and>  \<not>G\<turnstile>D\<preceq>C C \<and>
    73                    (\<forall>(sig,rT,b)\<in>set ms. \<forall>D' rT' b'.
    74                       method(G,D) sig = Some(D',rT',b') --> G\<turnstile>rT\<preceq>rT'))"
    75 
    76 lemma wf_cdecl_mrT_cdecl_mdecl:
    77   "(wf_cdecl wf_mb G c) = (ws_cdecl G c \<and> wf_mrT G c \<and> wf_cdecl_mdecl wf_mb G c)"
    78 apply (rule iffI)
    79 apply (simp add: wf_cdecl_def ws_cdecl_def wf_mrT_def wf_cdecl_mdecl_def 
    80   wf_mdecl_def wf_mhead_def split_beta)+
    81 done
    82 
    83 lemma wf_cdecl_ws_cdecl [intro]: "wf_cdecl wf_mb G cd \<Longrightarrow> ws_cdecl G cd"
    84 by (simp add: wf_cdecl_mrT_cdecl_mdecl)
    85 
    86 lemma wf_prog_ws_prog [intro]: "wf_prog wf_mb G \<Longrightarrow> ws_prog G"
    87 by (simp add: wf_prog_def ws_prog_def)
    88 
    89 lemma wf_prog_wf_mdecl: 
    90   "\<lbrakk> wf_prog wf_mb G; (C,S,fs,mdecls) \<in> set G; ((mn,pTs),rT,code) \<in> set mdecls\<rbrakk>
    91   \<Longrightarrow> wf_mdecl wf_mb G C ((mn,pTs),rT,code)"
    92 by (auto simp add: wf_prog_def ws_prog_def wf_mdecl_def  
    93   wf_cdecl_mdecl_def ws_cdecl_def)
    94 
    95 lemma class_wf: 
    96  "[|class G C = Some c; wf_prog wf_mb G|] 
    97   ==> wf_cdecl wf_mb G (C,c) \<and> wf_mrT G (C,c)"
    98 apply (unfold wf_prog_def ws_prog_def wf_cdecl_def class_def)
    99 apply clarify
   100 apply (drule_tac x="(C,c)" in bspec, fast dest: map_of_SomeD)
   101 apply (drule_tac x="(C,c)" in bspec, fast dest: map_of_SomeD)
   102 apply (simp add: wf_cdecl_def ws_cdecl_def wf_mdecl_def
   103   wf_cdecl_mdecl_def wf_mrT_def split_beta)
   104 done
   105 
   106 lemma class_wf_struct: 
   107  "[|class G C = Some c; ws_prog G|] 
   108   ==> ws_cdecl G (C,c)"
   109 apply (unfold ws_prog_def class_def)
   110 apply (fast dest: map_of_SomeD)
   111 done
   112 
   113 lemma class_Object [simp]: 
   114   "ws_prog G ==> \<exists>X fs ms. class G Object = Some (X,fs,ms)"
   115 apply (unfold ws_prog_def wf_syscls_def class_def)
   116 apply (auto simp: map_of_SomeI)
   117 done
   118 
   119 lemma class_Object_syscls [simp]: 
   120   "wf_syscls G ==> unique G \<Longrightarrow> \<exists>X fs ms. class G Object = Some (X,fs,ms)"
   121 apply (unfold wf_syscls_def class_def)
   122 apply (auto simp: map_of_SomeI)
   123 done
   124 
   125 lemma is_class_Object [simp]: "ws_prog G ==> is_class G Object"
   126   by (simp add: is_class_def)
   127 
   128 lemma is_class_xcpt [simp]: "ws_prog G \<Longrightarrow> is_class G (Xcpt x)"
   129   apply (simp add: ws_prog_def wf_syscls_def)
   130   apply (simp add: is_class_def class_def)
   131   apply clarify
   132   apply (erule_tac x = x in allE)
   133   apply clarify
   134   apply (auto intro!: map_of_SomeI)
   135   done
   136 
   137 lemma subcls1_wfD: "[|G\<turnstile>C\<prec>C1D; ws_prog G|] ==> D \<noteq> C \<and> (D, C) \<notin> (subcls1 G)^+"
   138 apply( frule trancl.r_into_trancl [where r="subcls1 G"])
   139 apply( drule subcls1D)
   140 apply(clarify)
   141 apply( drule (1) class_wf_struct)
   142 apply( unfold ws_cdecl_def)
   143 apply(force simp add: reflcl_trancl [THEN sym] simp del: reflcl_trancl)
   144 done
   145 
   146 lemma wf_cdecl_supD: 
   147 "!!r. \<lbrakk>ws_cdecl G (C,D,r); C \<noteq> Object\<rbrakk> \<Longrightarrow> is_class G D"
   148 apply (unfold ws_cdecl_def)
   149 apply (auto split add: option.split_asm)
   150 done
   151 
   152 lemma subcls_asym: "[|ws_prog G; (C, D) \<in> (subcls1 G)^+|] ==> (D, C) \<notin> (subcls1 G)^+"
   153 apply(erule trancl.cases)
   154 apply(fast dest!: subcls1_wfD )
   155 apply(fast dest!: subcls1_wfD intro: trancl_trans)
   156 done
   157 
   158 lemma subcls_irrefl: "[|ws_prog G; (C, D) \<in> (subcls1 G)^+|] ==> C \<noteq> D"
   159 apply (erule trancl_trans_induct)
   160 apply  (auto dest: subcls1_wfD subcls_asym)
   161 done
   162 
   163 lemma acyclic_subcls1: "ws_prog G ==> acyclic (subcls1 G)"
   164 apply (simp add: acyclic_def)
   165 apply (fast dest: subcls_irrefl)
   166 done
   167 
   168 lemma wf_subcls1: "ws_prog G ==> wf ((subcls1 G)^-1)"
   169 apply (rule finite_acyclic_wf)
   170 apply ( subst finite_converse)
   171 apply ( rule finite_subcls1)
   172 apply (subst acyclic_converse)
   173 apply (erule acyclic_subcls1)
   174 done
   175 
   176 lemma subcls_induct_struct: 
   177 "[|ws_prog G; !!C. \<forall>D. (C, D) \<in> (subcls1 G)^+ --> P D ==> P C|] ==> P C"
   178 (is "?A \<Longrightarrow> PROP ?P \<Longrightarrow> _")
   179 proof -
   180   assume p: "PROP ?P"
   181   assume ?A thus ?thesis apply -
   182 apply(drule wf_subcls1)
   183 apply(drule wf_trancl)
   184 apply(simp only: trancl_converse)
   185 apply(erule_tac a = C in wf_induct)
   186 apply(rule p)
   187 apply(auto)
   188 done
   189 qed
   190 
   191 lemma subcls_induct: 
   192 "[|wf_prog wf_mb G; !!C. \<forall>D. (C, D) \<in> (subcls1 G)^+ --> P D ==> P C|] ==> P C"
   193 (is "?A \<Longrightarrow> PROP ?P \<Longrightarrow> _")
   194 by (fact subcls_induct_struct [OF wf_prog_ws_prog])
   195 
   196 lemma subcls1_induct:
   197 "[|is_class G C; wf_prog wf_mb G; P Object;  
   198    !!C D fs ms. [|C \<noteq> Object; is_class G C; class G C = Some (D,fs,ms) \<and>  
   199     wf_cdecl wf_mb G (C,D,fs,ms) \<and> G\<turnstile>C\<prec>C1D \<and> is_class G D \<and> P D|] ==> P C 
   200  |] ==> P C"
   201 (is "?A \<Longrightarrow> ?B \<Longrightarrow> ?C \<Longrightarrow> PROP ?P \<Longrightarrow> _")
   202 proof -
   203   assume p: "PROP ?P"
   204   assume ?A ?B ?C thus ?thesis apply -
   205 apply(unfold is_class_def)
   206 apply( rule impE)
   207 prefer 2
   208 apply(   assumption)
   209 prefer 2
   210 apply(  assumption)
   211 apply( erule thin_rl)
   212 apply( rule subcls_induct)
   213 apply(  assumption)
   214 apply( rule impI)
   215 apply( case_tac "C = Object")
   216 apply(  fast)
   217 apply auto
   218 apply( frule (1) class_wf) apply (erule conjE)+
   219 apply (frule wf_cdecl_ws_cdecl)
   220 apply( frule (1) wf_cdecl_supD)
   221 
   222 apply( subgoal_tac "G\<turnstile>C\<prec>C1a")
   223 apply( erule_tac [2] subcls1I)
   224 apply(  rule p)
   225 apply (unfold is_class_def)
   226 apply auto
   227 done
   228 qed
   229 
   230 lemma subcls1_induct_struct:
   231 "[|is_class G C; ws_prog G; P Object;  
   232    !!C D fs ms. [|C \<noteq> Object; is_class G C; class G C = Some (D,fs,ms) \<and>  
   233     ws_cdecl G (C,D,fs,ms) \<and> G\<turnstile>C\<prec>C1D \<and> is_class G D \<and> P D|] ==> P C 
   234  |] ==> P C"
   235 (is "?A \<Longrightarrow> ?B \<Longrightarrow> ?C \<Longrightarrow> PROP ?P \<Longrightarrow> _")
   236 proof -
   237   assume p: "PROP ?P"
   238   assume ?A ?B ?C thus ?thesis apply -
   239 apply(unfold is_class_def)
   240 apply( rule impE)
   241 prefer 2
   242 apply(   assumption)
   243 prefer 2
   244 apply(  assumption)
   245 apply( erule thin_rl)
   246 apply( rule subcls_induct_struct)
   247 apply(  assumption)
   248 apply( rule impI)
   249 apply( case_tac "C = Object")
   250 apply(  fast)
   251 apply auto
   252 apply( frule (1) class_wf_struct)
   253 apply( frule (1) wf_cdecl_supD)
   254 
   255 apply( subgoal_tac "G\<turnstile>C\<prec>C1a")
   256 apply( erule_tac [2] subcls1I)
   257 apply(  rule p)
   258 apply (unfold is_class_def)
   259 apply auto
   260 done
   261 qed
   262 
   263 lemmas method_rec = wf_subcls1 [THEN [2] method_rec_lemma]
   264 
   265 lemmas fields_rec = wf_subcls1 [THEN [2] fields_rec_lemma]
   266 
   267 lemma field_rec: "\<lbrakk>class G C = Some (D, fs, ms); ws_prog G\<rbrakk>
   268 \<Longrightarrow> field (G, C) =
   269    (if C = Object then empty else field (G, D)) ++
   270    map_of (map (\<lambda>(s, f). (s, C, f)) fs)"
   271 apply (simp only: field_def)
   272 apply (frule fields_rec, assumption)
   273 apply (rule HOL.trans)
   274 apply (simp add: o_def)
   275 apply (simp (no_asm_use) add: split_beta split_def o_def)
   276 done
   277 
   278 lemma method_Object [simp]:
   279   "method (G, Object) sig = Some (D, mh, code) \<Longrightarrow> ws_prog G \<Longrightarrow> D = Object"  
   280   apply (frule class_Object, clarify)
   281   apply (drule method_rec, assumption)
   282   apply (auto dest: map_of_SomeD)
   283   done
   284 
   285 
   286 lemma fields_Object [simp]: "\<lbrakk> ((vn, C), T) \<in> set (fields (G, Object)); ws_prog G \<rbrakk>
   287   \<Longrightarrow> C = Object"
   288 apply (frule class_Object)
   289 apply clarify
   290 apply (subgoal_tac "fields (G, Object) = map (\<lambda>(fn,ft). ((fn,Object),ft)) fs")
   291 apply (simp add: image_iff split_beta)
   292 apply auto
   293 apply (rule trans)
   294 apply (rule fields_rec, assumption+)
   295 apply simp
   296 done
   297 
   298 lemma subcls_C_Object: "[|is_class G C; ws_prog G|] ==> G\<turnstile>C\<preceq>C Object"
   299 apply(erule subcls1_induct_struct)
   300 apply(  assumption)
   301 apply( fast)
   302 apply(auto dest!: wf_cdecl_supD)
   303 done
   304 
   305 lemma is_type_rTI: "wf_mhead G sig rT ==> is_type G rT"
   306 apply (unfold wf_mhead_def)
   307 apply auto
   308 done
   309 
   310 lemma widen_fields_defpl': "[|is_class G C; ws_prog G|] ==>  
   311   \<forall>((fn,fd),fT)\<in>set (fields (G,C)). G\<turnstile>C\<preceq>C fd"
   312 apply( erule subcls1_induct_struct)
   313 apply(   assumption)
   314 apply(  frule class_Object)
   315 apply(  clarify)
   316 apply(  frule fields_rec, assumption)
   317 apply(  fastforce)
   318 apply( tactic "safe_tac (put_claset HOL_cs @{context})")
   319 apply( subst fields_rec)
   320 apply(   assumption)
   321 apply(  assumption)
   322 apply( simp (no_asm) split del: split_if)
   323 apply( rule ballI)
   324 apply( simp (no_asm_simp) only: split_tupled_all)
   325 apply( simp (no_asm))
   326 apply( erule UnE)
   327 apply(  force)
   328 apply( erule r_into_rtrancl [THEN rtrancl_trans])
   329 apply auto
   330 done
   331 
   332 lemma widen_fields_defpl: 
   333   "[|((fn,fd),fT) \<in> set (fields (G,C)); ws_prog G; is_class G C|] ==>  
   334   G\<turnstile>C\<preceq>C fd"
   335 apply( drule (1) widen_fields_defpl')
   336 apply (fast)
   337 done
   338 
   339 lemma unique_fields: 
   340   "[|is_class G C; ws_prog G|] ==> unique (fields (G,C))"
   341 apply( erule subcls1_induct_struct)
   342 apply(   assumption)
   343 apply(  frule class_Object)
   344 apply(  clarify)
   345 apply(  frule fields_rec, assumption)
   346 apply(  drule class_wf_struct, assumption)
   347 apply(  simp add: ws_cdecl_def)
   348 apply(  rule unique_map_inj)
   349 apply(   simp)
   350 apply(  rule inj_onI)
   351 apply(  simp)
   352 apply( safe dest!: wf_cdecl_supD)
   353 apply( drule subcls1_wfD)
   354 apply(  assumption)
   355 apply( subst fields_rec)
   356 apply   auto
   357 apply( rotate_tac -1)
   358 apply( frule class_wf_struct)
   359 apply  auto
   360 apply( simp add: ws_cdecl_def)
   361 apply( erule unique_append)
   362 apply(  rule unique_map_inj)
   363 apply(   clarsimp)
   364 apply  (rule inj_onI)
   365 apply(  simp)
   366 apply(auto dest!: widen_fields_defpl)
   367 done
   368 
   369 lemma fields_mono_lemma [rule_format (no_asm)]: 
   370   "[|ws_prog G; (C', C) \<in> (subcls1 G)^*|] ==>  
   371   x \<in> set (fields (G,C)) --> x \<in> set (fields (G,C'))"
   372 apply(erule converse_rtrancl_induct)
   373 apply( safe dest!: subcls1D)
   374 apply(subst fields_rec)
   375 apply(  auto)
   376 done
   377 
   378 lemma fields_mono: 
   379 "\<lbrakk>map_of (fields (G,C)) fn = Some f; G\<turnstile>D\<preceq>C C; is_class G D; ws_prog G\<rbrakk> 
   380   \<Longrightarrow> map_of (fields (G,D)) fn = Some f"
   381 apply (rule map_of_SomeI)
   382 apply  (erule (1) unique_fields)
   383 apply (erule (1) fields_mono_lemma)
   384 apply (erule map_of_SomeD)
   385 done
   386 
   387 lemma widen_cfs_fields: 
   388 "[|field (G,C) fn = Some (fd, fT); G\<turnstile>D\<preceq>C C; ws_prog G|]==>  
   389   map_of (fields (G,D)) (fn, fd) = Some fT"
   390 apply (drule field_fields)
   391 apply (drule rtranclD)
   392 apply safe
   393 apply (frule subcls_is_class)
   394 apply (drule trancl_into_rtrancl)
   395 apply (fast dest: fields_mono)
   396 done
   397 
   398 lemma method_wf_mdecl [rule_format (no_asm)]: 
   399   "wf_prog wf_mb G ==> is_class G C \<Longrightarrow>   
   400      method (G,C) sig = Some (md,mh,m) 
   401    --> G\<turnstile>C\<preceq>C md \<and> wf_mdecl wf_mb G md (sig,(mh,m))"
   402 apply (frule wf_prog_ws_prog)
   403 apply( erule subcls1_induct)
   404 apply(   assumption)
   405 apply(  clarify) 
   406 apply(  frule class_Object)
   407 apply(  clarify)
   408 apply(  frule method_rec, assumption)
   409 apply(  drule class_wf, assumption)
   410 apply(  simp add: wf_cdecl_def)
   411 apply(  drule map_of_SomeD)
   412 apply(  subgoal_tac "md = Object")
   413 apply(   fastforce) 
   414 apply(  fastforce)
   415 apply( clarify)
   416 apply( frule_tac C = C in method_rec)
   417 apply(  assumption)
   418 apply( rotate_tac -1)
   419 apply( simp)
   420 apply( drule map_add_SomeD)
   421 apply( erule disjE)
   422 apply(  erule_tac V = "?P --> ?Q" in thin_rl)
   423 apply (frule map_of_SomeD)
   424 apply (clarsimp simp add: wf_cdecl_def)
   425 apply( clarify)
   426 apply( rule rtrancl_trans)
   427 prefer 2
   428 apply(  assumption)
   429 apply( rule r_into_rtrancl)
   430 apply( fast intro: subcls1I)
   431 done
   432 
   433 
   434 lemma method_wf_mhead [rule_format (no_asm)]: 
   435   "ws_prog G ==> is_class G C \<Longrightarrow>   
   436      method (G,C) sig = Some (md,rT,mb) 
   437    --> G\<turnstile>C\<preceq>C md \<and> wf_mhead G sig rT"
   438 apply( erule subcls1_induct_struct)
   439 apply(   assumption)
   440 apply(  clarify) 
   441 apply(  frule class_Object)
   442 apply(  clarify)
   443 apply(  frule method_rec, assumption)
   444 apply(  drule class_wf_struct, assumption)
   445 apply(  simp add: ws_cdecl_def)
   446 apply(  drule map_of_SomeD)
   447 apply(  subgoal_tac "md = Object")
   448 apply(   fastforce)
   449 apply(  fastforce)
   450 apply( clarify)
   451 apply( frule_tac C = C in method_rec)
   452 apply(  assumption)
   453 apply( rotate_tac -1)
   454 apply( simp)
   455 apply( drule map_add_SomeD)
   456 apply( erule disjE)
   457 apply(  erule_tac V = "?P --> ?Q" in thin_rl)
   458 apply (frule map_of_SomeD)
   459 apply (clarsimp simp add: ws_cdecl_def)
   460 apply blast
   461 apply clarify
   462 apply( rule rtrancl_trans)
   463 prefer 2
   464 apply(  assumption)
   465 apply( rule r_into_rtrancl)
   466 apply( fast intro: subcls1I)
   467 done
   468 
   469 lemma subcls_widen_methd [rule_format (no_asm)]: 
   470   "[|G\<turnstile>T'\<preceq>C T; wf_prog wf_mb G|] ==>  
   471    \<forall>D rT b. method (G,T) sig = Some (D,rT ,b) --> 
   472   (\<exists>D' rT' b'. method (G,T') sig = Some (D',rT',b') \<and> G\<turnstile>D'\<preceq>C D \<and> G\<turnstile>rT'\<preceq>rT)"
   473 apply( drule rtranclD)
   474 apply( erule disjE)
   475 apply(  fast)
   476 apply( erule conjE)
   477 apply( erule trancl_trans_induct)
   478 prefer 2
   479 apply(  clarify)
   480 apply(  drule spec, drule spec, drule spec, erule (1) impE)
   481 apply(  fast elim: widen_trans rtrancl_trans)
   482 apply( clarify)
   483 apply( drule subcls1D)
   484 apply( clarify)
   485 apply( subst method_rec)
   486 apply(  assumption)
   487 apply( unfold map_add_def)
   488 apply( simp (no_asm_simp) add: wf_prog_ws_prog del: split_paired_Ex)
   489 apply( case_tac "\<exists>z. map_of(map (\<lambda>(s,m). (s, ?C, m)) ms) sig = Some z")
   490 apply(  erule exE)
   491 apply(  rotate_tac -1, frule ssubst, erule_tac [2] asm_rl)
   492 prefer 2
   493 apply(  rotate_tac -1, frule ssubst, erule_tac [2] asm_rl)
   494 apply(  tactic "asm_full_simp_tac
   495   (put_simpset HOL_ss @{context} addsimps [@{thm not_None_eq} RS sym]) 1")
   496 apply(  simp_all (no_asm_simp) del: split_paired_Ex)
   497 apply( frule (1) class_wf)
   498 apply( simp (no_asm_simp) only: split_tupled_all)
   499 apply( unfold wf_cdecl_def)
   500 apply( drule map_of_SomeD)
   501 apply (auto simp add: wf_mrT_def)
   502 apply (rule rtrancl_trans)
   503 defer
   504 apply (rule method_wf_mhead [THEN conjunct1])
   505 apply (simp only: wf_prog_def)
   506 apply (simp add: is_class_def)
   507 apply assumption
   508 apply (auto intro: subcls1I)
   509 done
   510 
   511 
   512 lemma subtype_widen_methd: 
   513  "[| G\<turnstile> C\<preceq>C D; wf_prog wf_mb G;  
   514      method (G,D) sig = Some (md, rT, b) |]  
   515   ==> \<exists>mD' rT' b'. method (G,C) sig= Some(mD',rT',b') \<and> G\<turnstile>rT'\<preceq>rT"
   516 apply(auto dest: subcls_widen_methd 
   517            simp add: wf_mdecl_def wf_mhead_def split_def)
   518 done
   519 
   520 
   521 lemma method_in_md [rule_format (no_asm)]: 
   522   "ws_prog G ==> is_class G C \<Longrightarrow> \<forall>D. method (G,C) sig = Some(D,mh,code) 
   523   --> is_class G D \<and> method (G,D) sig = Some(D,mh,code)"
   524 apply (erule (1) subcls1_induct_struct)
   525  apply clarify
   526  apply (frule method_Object, assumption)
   527  apply hypsubst
   528  apply simp
   529 apply (erule conjE)
   530 apply (simplesubst method_rec, assumption+)
   531 apply (clarify)
   532 apply (erule_tac x = "Da" in allE)
   533 apply (clarsimp)
   534  apply (simp add: map_of_map)
   535  apply (clarify)
   536  apply (subst method_rec, assumption+)
   537  apply (simp add: map_add_def map_of_map split add: option.split)
   538 done
   539 
   540 
   541 lemma method_in_md_struct [rule_format (no_asm)]: 
   542   "ws_prog G ==> is_class G C \<Longrightarrow> \<forall>D. method (G,C) sig = Some(D,mh,code) 
   543   --> is_class G D \<and> method (G,D) sig = Some(D,mh,code)"
   544 apply (erule (1) subcls1_induct_struct)
   545  apply clarify
   546  apply (frule method_Object, assumption)
   547  apply hypsubst
   548  apply simp
   549 apply (erule conjE)
   550 apply (simplesubst method_rec, assumption+)
   551 apply (clarify)
   552 apply (erule_tac x = "Da" in allE)
   553 apply (clarsimp)
   554  apply (simp add: map_of_map)
   555  apply (clarify)
   556  apply (subst method_rec, assumption+)
   557  apply (simp add: map_add_def map_of_map split add: option.split)
   558 done
   559 
   560 lemma fields_in_fd [rule_format (no_asm)]: "\<lbrakk> wf_prog wf_mb G; is_class G C\<rbrakk>
   561   \<Longrightarrow> \<forall> vn D T. (((vn,D),T) \<in> set (fields (G,C))
   562   \<longrightarrow> (is_class G D \<and> ((vn,D),T) \<in> set (fields (G,D))))"
   563 apply (erule (1) subcls1_induct)
   564 
   565 apply clarify
   566 apply (frule wf_prog_ws_prog)
   567 apply (frule fields_Object, assumption+)
   568 apply (simp only: is_class_Object)
   569 
   570 apply clarify
   571 apply (frule fields_rec)
   572 apply (simp (no_asm_simp) add: wf_prog_ws_prog)
   573 
   574 apply (case_tac "Da=C")
   575 apply blast                     (* case Da=C *)
   576 
   577 apply (subgoal_tac "((vn, Da), T) \<in> set (fields (G, D))") apply blast
   578 apply (erule thin_rl)
   579 apply (rotate_tac 1)
   580 apply (erule thin_rl, erule thin_rl, erule thin_rl, 
   581       erule thin_rl, erule thin_rl, erule thin_rl)
   582 apply auto
   583 done
   584 
   585 lemma field_in_fd [rule_format (no_asm)]: "\<lbrakk> wf_prog wf_mb G; is_class G C\<rbrakk>
   586   \<Longrightarrow> \<forall> vn D T. (field (G,C) vn = Some(D,T) 
   587   \<longrightarrow> is_class G D \<and> field (G,D) vn = Some(D,T))"
   588 apply (erule (1) subcls1_induct)
   589 
   590 apply clarify
   591 apply (frule field_fields)
   592 apply (drule map_of_SomeD)
   593 apply (frule wf_prog_ws_prog)
   594 apply (drule fields_Object, assumption+)
   595 apply simp
   596 
   597 apply clarify
   598 apply (subgoal_tac "((field (G, D)) ++ map_of (map (\<lambda>(s, f). (s, C, f)) fs)) vn = Some (Da, T)")
   599 apply (simp (no_asm_use) only: map_add_Some_iff)
   600 apply (erule disjE)
   601 apply (simp (no_asm_use) add: map_of_map) apply blast
   602 apply blast
   603 apply (rule trans [THEN sym], rule sym, assumption)
   604 apply (rule_tac x=vn in fun_cong)
   605 apply (rule trans, rule field_rec, assumption+)
   606 apply (simp (no_asm_simp) add: wf_prog_ws_prog) 
   607 apply (simp (no_asm_use)) apply blast
   608 done
   609 
   610 
   611 lemma widen_methd: 
   612 "[| method (G,C) sig = Some (md,rT,b); wf_prog wf_mb G; G\<turnstile>T''\<preceq>C C|] 
   613   ==> \<exists>md' rT' b'. method (G,T'') sig = Some (md',rT',b') \<and> G\<turnstile>rT'\<preceq>rT"
   614 apply( drule subcls_widen_methd)
   615 apply   auto
   616 done
   617 
   618 lemma widen_field: "\<lbrakk> (field (G,C) fn) = Some (fd, fT); wf_prog wf_mb G; is_class G C \<rbrakk>
   619   \<Longrightarrow> G\<turnstile>C\<preceq>C fd"
   620 apply (rule widen_fields_defpl)
   621 apply (simp add: field_def)
   622 apply (rule map_of_SomeD)
   623 apply (rule table_of_remap_SomeD) 
   624 apply assumption+
   625 apply (simp (no_asm_simp) add: wf_prog_ws_prog)+
   626 done
   627 
   628 lemma Call_lemma: 
   629 "[|method (G,C) sig = Some (md,rT,b); G\<turnstile>T''\<preceq>C C; wf_prog wf_mb G;  
   630   class G C = Some y|] ==> \<exists>T' rT' b. method (G,T'') sig = Some (T',rT',b) \<and>  
   631   G\<turnstile>rT'\<preceq>rT \<and> G\<turnstile>T''\<preceq>C T' \<and> wf_mhead G sig rT' \<and> wf_mb G T' (sig,rT',b)"
   632 apply( drule (2) widen_methd)
   633 apply( clarify)
   634 apply( frule subcls_is_class2)
   635 apply (unfold is_class_def)
   636 apply (simp (no_asm_simp))
   637 apply( drule method_wf_mdecl)
   638 apply( unfold wf_mdecl_def)
   639 apply( unfold is_class_def)
   640 apply auto
   641 done
   642 
   643 lemma fields_is_type_lemma [rule_format (no_asm)]: 
   644   "[|is_class G C; ws_prog G|] ==>  
   645   \<forall>f\<in>set (fields (G,C)). is_type G (snd f)"
   646 apply( erule (1) subcls1_induct_struct)
   647 apply(  frule class_Object)
   648 apply(  clarify)
   649 apply(  frule fields_rec, assumption)
   650 apply(  drule class_wf_struct, assumption)
   651 apply(  simp add: ws_cdecl_def wf_fdecl_def)
   652 apply(  fastforce)
   653 apply( subst fields_rec)
   654 apply(   fast)
   655 apply(  assumption)
   656 apply( clarsimp)
   657 apply( safe)
   658 prefer 2
   659 apply(  force)
   660 apply( drule (1) class_wf_struct)
   661 apply( unfold ws_cdecl_def)
   662 apply( clarsimp)
   663 apply( drule (1) bspec)
   664 apply( unfold wf_fdecl_def)
   665 apply auto
   666 done
   667 
   668 
   669 lemma fields_is_type: 
   670   "[|map_of (fields (G,C)) fn = Some f; ws_prog G; is_class G C|] ==>  
   671   is_type G f"
   672 apply(drule map_of_SomeD)
   673 apply(drule (2) fields_is_type_lemma)
   674 apply(auto)
   675 done
   676 
   677 
   678 lemma field_is_type: "\<lbrakk> ws_prog G; is_class G C; field (G, C) fn = Some (fd, fT) \<rbrakk>
   679   \<Longrightarrow> is_type G fT"
   680 apply (frule_tac f="((fn, fd), fT)" in fields_is_type_lemma)
   681 apply (auto simp add: field_def dest: map_of_SomeD)
   682 done
   683 
   684 
   685 lemma methd:
   686   "[| ws_prog G; (C,S,fs,mdecls) \<in> set G; (sig,rT,code) \<in> set mdecls |]
   687   ==> method (G,C) sig = Some(C,rT,code) \<and> is_class G C"
   688 proof -
   689   assume wf: "ws_prog G" and C:  "(C,S,fs,mdecls) \<in> set G" and
   690          m: "(sig,rT,code) \<in> set mdecls"
   691   moreover
   692   from wf C have "class G C = Some (S,fs,mdecls)"
   693     by (auto simp add: ws_prog_def class_def is_class_def intro: map_of_SomeI)
   694   moreover
   695   from wf C 
   696   have "unique mdecls" by (unfold ws_prog_def ws_cdecl_def) auto
   697   hence "unique (map (\<lambda>(s,m). (s,C,m)) mdecls)" by (induct mdecls, auto)  
   698   with m 
   699   have "map_of (map (\<lambda>(s,m). (s,C,m)) mdecls) sig = Some (C,rT,code)"
   700     by (force intro: map_of_SomeI)
   701   ultimately
   702   show ?thesis by (auto simp add: is_class_def dest: method_rec)
   703 qed
   704 
   705 
   706 lemma wf_mb'E:
   707   "\<lbrakk> wf_prog wf_mb G; \<And>C S fs ms m.\<lbrakk>(C,S,fs,ms) \<in> set G; m \<in> set ms\<rbrakk> \<Longrightarrow> wf_mb' G C m \<rbrakk>
   708   \<Longrightarrow> wf_prog wf_mb' G"
   709   apply (simp only: wf_prog_def)
   710   apply auto
   711   apply (simp add: wf_cdecl_mdecl_def)
   712   apply safe
   713   apply (drule bspec, assumption) apply simp
   714   done
   715 
   716 
   717 lemma fst_mono: "A \<subseteq> B \<Longrightarrow> fst ` A \<subseteq> fst ` B" by fast
   718 
   719 lemma wf_syscls:
   720   "set SystemClasses \<subseteq> set G \<Longrightarrow> wf_syscls G"
   721   apply (drule fst_mono)
   722   apply (simp add: SystemClasses_def wf_syscls_def)
   723   apply (simp add: ObjectC_def) 
   724   apply (rule allI, case_tac x)
   725   apply (auto simp add: NullPointerC_def ClassCastC_def OutOfMemoryC_def)
   726   done
   727 
   728 end