src/HOL/Bali/TypeSafe.thy
author wenzelm
Mon Feb 27 17:40:59 2012 +0100 (2012-02-27)
changeset 46714 a7ca72710dfe
parent 44890 22f665a2e91c
child 51703 f2e92fc0c8aa
permissions -rw-r--r--
tuned proofs;
wenzelm@12857
     1
(*  Title:      HOL/Bali/TypeSafe.thy
schirmer@12925
     2
    Author:     David von Oheimb and Norbert Schirmer
schirmer@12854
     3
*)
schirmer@12854
     4
header {* The type soundness proof for Java *}
schirmer@12854
     5
haftmann@23019
     6
theory TypeSafe
haftmann@23019
     7
imports DefiniteAssignmentCorrect Conform
haftmann@23019
     8
begin
schirmer@12854
     9
schirmer@12925
    10
section "error free"
schirmer@12925
    11
 
schirmer@12925
    12
lemma error_free_halloc:
wenzelm@12937
    13
  assumes halloc: "G\<turnstile>s0 \<midarrow>halloc oi\<succ>a\<rightarrow> s1" and
schirmer@12925
    14
          error_free_s0: "error_free s0"
wenzelm@12937
    15
  shows "error_free s1"
schirmer@12925
    16
proof -
schirmer@12925
    17
  from halloc error_free_s0
schirmer@12925
    18
  obtain abrupt0 store0 abrupt1 store1
schirmer@12925
    19
    where eqs: "s0=(abrupt0,store0)" "s1=(abrupt1,store1)" and
schirmer@12925
    20
          halloc': "G\<turnstile>(abrupt0,store0) \<midarrow>halloc oi\<succ>a\<rightarrow> (abrupt1,store1)" and
schirmer@12925
    21
          error_free_s0': "error_free (abrupt0,store0)"
schirmer@12925
    22
    by (cases s0,cases s1) auto
schirmer@12925
    23
  from halloc' error_free_s0'
schirmer@12925
    24
  have "error_free (abrupt1,store1)"
schirmer@12925
    25
  proof (induct)
schirmer@12925
    26
    case Abrupt 
schirmer@13688
    27
    then show ?case .
schirmer@12925
    28
  next
schirmer@12925
    29
    case New
schirmer@12925
    30
    then show ?case
wenzelm@46714
    31
      by auto
schirmer@12925
    32
  qed
schirmer@12925
    33
  with eqs 
schirmer@12925
    34
  show ?thesis
schirmer@12925
    35
    by simp
schirmer@12925
    36
qed
schirmer@12925
    37
schirmer@12925
    38
lemma error_free_sxalloc:
wenzelm@12937
    39
  assumes sxalloc: "G\<turnstile>s0 \<midarrow>sxalloc\<rightarrow> s1" and error_free_s0: "error_free s0"
wenzelm@12937
    40
  shows "error_free s1"
schirmer@12925
    41
proof -
schirmer@12925
    42
  from sxalloc error_free_s0
schirmer@12925
    43
  obtain abrupt0 store0 abrupt1 store1
schirmer@12925
    44
    where eqs: "s0=(abrupt0,store0)" "s1=(abrupt1,store1)" and
schirmer@12925
    45
          sxalloc': "G\<turnstile>(abrupt0,store0) \<midarrow>sxalloc\<rightarrow> (abrupt1,store1)" and
schirmer@12925
    46
          error_free_s0': "error_free (abrupt0,store0)"
schirmer@12925
    47
    by (cases s0,cases s1) auto
schirmer@12925
    48
  from sxalloc' error_free_s0'
schirmer@12925
    49
  have "error_free (abrupt1,store1)"
schirmer@12925
    50
  proof (induct)
schirmer@12925
    51
  qed (auto)
schirmer@12925
    52
  with eqs 
schirmer@12925
    53
  show ?thesis 
schirmer@12925
    54
    by simp
schirmer@12925
    55
qed
schirmer@12925
    56
schirmer@12925
    57
lemma error_free_check_field_access_eq:
schirmer@12925
    58
 "error_free (check_field_access G accC statDeclC fn stat a s)
schirmer@12925
    59
 \<Longrightarrow> (check_field_access G accC statDeclC fn stat a s) = s"
schirmer@12925
    60
apply (cases s)
schirmer@12925
    61
apply (auto simp add: check_field_access_def Let_def error_free_def 
schirmer@12925
    62
                      abrupt_if_def 
schirmer@12925
    63
            split: split_if_asm)
schirmer@12925
    64
done
schirmer@12925
    65
schirmer@12925
    66
lemma error_free_check_method_access_eq:
schirmer@12925
    67
"error_free (check_method_access G accC statT mode sig a' s)
schirmer@12925
    68
 \<Longrightarrow> (check_method_access G accC statT mode sig a' s) = s"
schirmer@12925
    69
apply (cases s)
schirmer@12925
    70
apply (auto simp add: check_method_access_def Let_def error_free_def 
wenzelm@46714
    71
                      abrupt_if_def)
schirmer@12925
    72
done
schirmer@12925
    73
schirmer@12925
    74
lemma error_free_FVar_lemma: 
schirmer@12925
    75
     "error_free s 
schirmer@12925
    76
       \<Longrightarrow> error_free (abupd (if stat then id else np a) s)"
wenzelm@46714
    77
  by (case_tac s) auto
schirmer@12925
    78
schirmer@12925
    79
lemma error_free_init_lvars [simp,intro]:
schirmer@12925
    80
"error_free s \<Longrightarrow> 
schirmer@12925
    81
  error_free (init_lvars G C sig mode a pvs s)"
wenzelm@46714
    82
by (cases s) (auto simp add: init_lvars_def Let_def)
schirmer@12925
    83
schirmer@12925
    84
lemma error_free_LVar_lemma:   
schirmer@12925
    85
"error_free s \<Longrightarrow> error_free (assign (\<lambda>v. supd lupd(vn\<mapsto>v)) w s)"
schirmer@12925
    86
by (cases s) simp
schirmer@12925
    87
schirmer@12925
    88
lemma error_free_throw [simp,intro]:
schirmer@12925
    89
  "error_free s \<Longrightarrow> error_free (abupd (throw x) s)"
schirmer@12925
    90
by (cases s) (simp add: throw_def)
schirmer@12925
    91
schirmer@12854
    92
schirmer@12854
    93
section "result conformance"
schirmer@12854
    94
wenzelm@37956
    95
definition
wenzelm@37956
    96
  assign_conforms :: "st \<Rightarrow> (val \<Rightarrow> state \<Rightarrow> state) \<Rightarrow> ty \<Rightarrow> env' \<Rightarrow> bool" ("_\<le>|_\<preceq>_\<Colon>\<preceq>_" [71,71,71,71] 70)
wenzelm@37956
    97
where
wenzelm@37956
    98
  "s\<le>|f\<preceq>T\<Colon>\<preceq>E =
wenzelm@37956
    99
   ((\<forall>s' w. Norm s'\<Colon>\<preceq>E \<longrightarrow> fst E,s'\<turnstile>w\<Colon>\<preceq>T \<longrightarrow> s\<le>|s' \<longrightarrow> assign f w (Norm s')\<Colon>\<preceq>E) \<and>
wenzelm@37956
   100
    (\<forall>s' w. error_free s' \<longrightarrow> (error_free (assign f w s'))))"
schirmer@12854
   101
schirmer@13688
   102
wenzelm@37956
   103
definition
wenzelm@37956
   104
  rconf :: "prog \<Rightarrow> lenv \<Rightarrow> st \<Rightarrow> term \<Rightarrow> vals \<Rightarrow> tys \<Rightarrow> bool" ("_,_,_\<turnstile>_\<succ>_\<Colon>\<preceq>_" [71,71,71,71,71,71] 70)
wenzelm@37956
   105
where
wenzelm@37956
   106
  "G,L,s\<turnstile>t\<succ>v\<Colon>\<preceq>T =
wenzelm@37956
   107
    (case T of
wenzelm@37956
   108
      Inl T  \<Rightarrow> if (\<exists> var. t=In2 var)
wenzelm@37956
   109
                then (\<forall> n. (the_In2 t) = LVar n 
wenzelm@37956
   110
                       \<longrightarrow> (fst (the_In2 v) = the (locals s n)) \<and>
wenzelm@37956
   111
                           (locals s n \<noteq> None \<longrightarrow> G,s\<turnstile>fst (the_In2 v)\<Colon>\<preceq>T)) \<and>
wenzelm@37956
   112
                    (\<not> (\<exists> n. the_In2 t=LVar n) \<longrightarrow> (G,s\<turnstile>fst (the_In2 v)\<Colon>\<preceq>T))\<and>
wenzelm@37956
   113
                    (s\<le>|snd (the_In2 v)\<preceq>T\<Colon>\<preceq>(G,L))
wenzelm@37956
   114
                else G,s\<turnstile>the_In1 v\<Colon>\<preceq>T
wenzelm@37956
   115
    | Inr Ts \<Rightarrow> list_all2 (conf G s) (the_In3 v) Ts)"
schirmer@12854
   116
schirmer@13688
   117
text {*
schirmer@13688
   118
 With @{term rconf} we describe the conformance of the result value of a term.
schirmer@13688
   119
 This definition gets rather complicated because of the relations between the
schirmer@13688
   120
 injections of the different terms, types and values. The main case distinction
schirmer@13688
   121
 is between single values and value lists. In case of value lists, every 
schirmer@13688
   122
 value has to conform to its type. For single values we have to do a further
schirmer@13688
   123
 case distinction, between values of variables @{term "\<exists>var. t=In2 var" } and
schirmer@13688
   124
 ordinary values. Values of variables are modelled as pairs consisting of the
schirmer@13688
   125
 current value and an update function which will perform an assignment to the
schirmer@13688
   126
 variable. This stems form the decision, that we only have one evaluation rule
schirmer@13688
   127
 for each kind of variable. The decision if we read or write to the 
schirmer@13688
   128
 variable is made by syntactic enclosing rules. So conformance of 
schirmer@13688
   129
 variable-values must ensure that both the current value and an update will 
schirmer@13688
   130
 conform to the type. With the introduction of definite assignment of local
schirmer@13688
   131
 variables we have to do another case distinction. For the notion of conformance
schirmer@13688
   132
 local variables are allowed to be @{term None}, since the definedness is not 
schirmer@13688
   133
 ensured by conformance but by definite assignment. Field and array variables 
schirmer@13688
   134
 must contain a value. 
schirmer@13688
   135
*}
schirmer@13688
   136
 
schirmer@13688
   137
schirmer@13688
   138
schirmer@12854
   139
lemma rconf_In1 [simp]: 
schirmer@12854
   140
 "G,L,s\<turnstile>In1 ec\<succ>In1 v \<Colon>\<preceq>Inl T  =  G,s\<turnstile>v\<Colon>\<preceq>T"
schirmer@12854
   141
apply (unfold rconf_def)
schirmer@12854
   142
apply (simp (no_asm))
schirmer@12854
   143
done
schirmer@12854
   144
schirmer@13688
   145
lemma rconf_In2_no_LVar [simp]: 
schirmer@13688
   146
 "\<forall> n. va\<noteq>LVar n \<Longrightarrow> 
schirmer@13688
   147
   G,L,s\<turnstile>In2 va\<succ>In2 vf\<Colon>\<preceq>Inl T  = (G,s\<turnstile>fst vf\<Colon>\<preceq>T \<and> s\<le>|snd vf\<preceq>T\<Colon>\<preceq>(G,L))"
schirmer@12854
   148
apply (unfold rconf_def)
schirmer@13688
   149
apply auto
schirmer@12854
   150
done
schirmer@12854
   151
schirmer@13688
   152
lemma rconf_In2_LVar [simp]: 
schirmer@13688
   153
 "va=LVar n \<Longrightarrow> 
schirmer@13688
   154
   G,L,s\<turnstile>In2 va\<succ>In2 vf\<Colon>\<preceq>Inl T  
schirmer@13688
   155
    = ((fst vf = the (locals s n)) \<and>
schirmer@13688
   156
       (locals s n \<noteq> None \<longrightarrow> G,s\<turnstile>fst vf\<Colon>\<preceq>T) \<and> s\<le>|snd vf\<preceq>T\<Colon>\<preceq>(G,L))"
schirmer@13688
   157
apply (unfold rconf_def)
schirmer@13688
   158
by simp
schirmer@13688
   159
schirmer@12854
   160
lemma rconf_In3 [simp]: 
schirmer@12854
   161
 "G,L,s\<turnstile>In3 es\<succ>In3 vs\<Colon>\<preceq>Inr Ts = list_all2 (\<lambda>v T. G,s\<turnstile>v\<Colon>\<preceq>T) vs Ts"
schirmer@12854
   162
apply (unfold rconf_def)
schirmer@12854
   163
apply (simp (no_asm))
schirmer@12854
   164
done
schirmer@12854
   165
schirmer@12854
   166
section "fits and conf"
schirmer@12854
   167
schirmer@12854
   168
(* unused *)
schirmer@12854
   169
lemma conf_fits: "G,s\<turnstile>v\<Colon>\<preceq>T \<Longrightarrow> G,s\<turnstile>v fits T"
schirmer@12854
   170
apply (unfold fits_def)
schirmer@12854
   171
apply clarify
wenzelm@18585
   172
apply (erule contrapos_np, simp (no_asm_use))
schirmer@12854
   173
apply (drule conf_RefTD)
schirmer@12854
   174
apply auto
schirmer@12854
   175
done
schirmer@12854
   176
schirmer@12854
   177
lemma fits_conf: 
schirmer@12854
   178
  "\<lbrakk>G,s\<turnstile>v\<Colon>\<preceq>T; G\<turnstile>T\<preceq>? T'; G,s\<turnstile>v fits T'; ws_prog G\<rbrakk> \<Longrightarrow> G,s\<turnstile>v\<Colon>\<preceq>T'"
schirmer@12854
   179
apply (auto dest!: fitsD cast_PrimT2 cast_RefT2)
schirmer@12854
   180
apply (force dest: conf_RefTD intro: conf_AddrI)
schirmer@12854
   181
done
schirmer@12854
   182
schirmer@12854
   183
lemma fits_Array: 
schirmer@12854
   184
 "\<lbrakk>G,s\<turnstile>v\<Colon>\<preceq>T; G\<turnstile>T'.[]\<preceq>T.[]; G,s\<turnstile>v fits T'; ws_prog G\<rbrakk> \<Longrightarrow> G,s\<turnstile>v\<Colon>\<preceq>T'"
schirmer@12854
   185
apply (auto dest!: fitsD widen_ArrayPrimT widen_ArrayRefT)
schirmer@12854
   186
apply (force dest: conf_RefTD intro: conf_AddrI)
schirmer@12854
   187
done
schirmer@12854
   188
schirmer@12854
   189
schirmer@12854
   190
schirmer@12854
   191
section "gext"
schirmer@12854
   192
schirmer@12854
   193
lemma halloc_gext: "\<And>s1 s2. G\<turnstile>s1 \<midarrow>halloc oi\<succ>a\<rightarrow> s2 \<Longrightarrow> snd s1\<le>|snd s2"
schirmer@12854
   194
apply (simp (no_asm_simp) only: split_tupled_all)
schirmer@12854
   195
apply (erule halloc.induct)
schirmer@12854
   196
apply  (auto dest!: new_AddrD)
schirmer@12854
   197
done
schirmer@12854
   198
schirmer@12854
   199
lemma sxalloc_gext: "\<And>s1 s2. G\<turnstile>s1 \<midarrow>sxalloc\<rightarrow> s2 \<Longrightarrow> snd s1\<le>|snd s2"
schirmer@12854
   200
apply (simp (no_asm_simp) only: split_tupled_all)
schirmer@12854
   201
apply (erule sxalloc.induct)
schirmer@12854
   202
apply   (auto dest!: halloc_gext)
schirmer@12854
   203
done
schirmer@12854
   204
schirmer@12854
   205
lemma eval_gext_lemma [rule_format (no_asm)]: 
schirmer@12854
   206
 "G\<turnstile>s \<midarrow>t\<succ>\<rightarrow> (w,s') \<Longrightarrow> snd s\<le>|snd s' \<and> (case w of  
schirmer@12854
   207
    In1 v \<Rightarrow> True  
schirmer@12854
   208
  | In2 vf \<Rightarrow> normal s \<longrightarrow> (\<forall>v x s. s\<le>|snd (assign (snd vf) v (x,s)))  
schirmer@12854
   209
  | In3 vs \<Rightarrow> True)"
schirmer@12854
   210
apply (erule eval_induct)
schirmer@13337
   211
prefer 26 
schirmer@12854
   212
  apply (case_tac "inited C (globs s0)", clarsimp, erule thin_rl) (* Init *)
schirmer@12854
   213
apply (auto del: conjI  dest!: not_initedD gext_new sxalloc_gext halloc_gext
schirmer@12925
   214
 simp  add: lvar_def fvar_def2 avar_def2 init_lvars_def2 
schirmer@12925
   215
            check_field_access_def check_method_access_def Let_def
schirmer@12854
   216
 split del: split_if_asm split add: sum3.split)
schirmer@12854
   217
(* 6 subgoals *)
schirmer@12854
   218
apply force+
schirmer@12854
   219
done
schirmer@12854
   220
schirmer@12854
   221
lemma evar_gext_f: 
schirmer@12854
   222
  "G\<turnstile>Norm s1 \<midarrow>e=\<succ>vf \<rightarrow> s2 \<Longrightarrow> s\<le>|snd (assign (snd vf) v (x,s))"
schirmer@12854
   223
apply (drule eval_gext_lemma [THEN conjunct2])
schirmer@12854
   224
apply auto
schirmer@12854
   225
done
schirmer@12854
   226
schirmer@12854
   227
lemmas eval_gext = eval_gext_lemma [THEN conjunct1]
schirmer@12854
   228
berghofe@21765
   229
lemma eval_gext': "G\<turnstile>(x1,s1) \<midarrow>t\<succ>\<rightarrow> (w,(x2,s2)) \<Longrightarrow> s1\<le>|s2"
schirmer@12854
   230
apply (drule eval_gext)
schirmer@12854
   231
apply auto
schirmer@12854
   232
done
schirmer@12854
   233
schirmer@12854
   234
lemma init_yields_initd: "G\<turnstile>Norm s1 \<midarrow>Init C\<rightarrow> s2 \<Longrightarrow> initd C s2"
schirmer@12854
   235
apply (erule eval_cases , auto split del: split_if_asm)
schirmer@12854
   236
apply (case_tac "inited C (globs s1)")
schirmer@12854
   237
apply  (clarsimp split del: split_if_asm)+
schirmer@12854
   238
apply (drule eval_gext')+
schirmer@12854
   239
apply (drule init_class_obj_inited)
schirmer@12854
   240
apply (erule inited_gext)
schirmer@12854
   241
apply (simp (no_asm_use))
schirmer@12854
   242
done
schirmer@12854
   243
schirmer@12854
   244
schirmer@12854
   245
section "Lemmas"
schirmer@12854
   246
schirmer@12854
   247
lemma obj_ty_obj_class1: 
schirmer@12854
   248
 "\<lbrakk>wf_prog G; is_type G (obj_ty obj)\<rbrakk> \<Longrightarrow> is_class G (obj_class obj)"
schirmer@12854
   249
apply (case_tac "tag obj")
schirmer@12854
   250
apply (auto simp add: obj_ty_def obj_class_def)
schirmer@12854
   251
done
schirmer@12854
   252
schirmer@12854
   253
lemma oconf_init_obj: 
schirmer@12854
   254
 "\<lbrakk>wf_prog G;  
schirmer@12854
   255
 (case r of Heap a \<Rightarrow> is_type G (obj_ty obj) | Stat C \<Rightarrow> is_class G C)
schirmer@12854
   256
\<rbrakk> \<Longrightarrow> G,s\<turnstile>obj \<lparr>values:=init_vals (var_tys G (tag obj) r)\<rparr>\<Colon>\<preceq>\<surd>r"
schirmer@12854
   257
apply (auto intro!: oconf_init_obj_lemma unique_fields)
schirmer@12854
   258
done
schirmer@12854
   259
schirmer@12854
   260
lemma conforms_newG: "\<lbrakk>globs s oref = None; (x, s)\<Colon>\<preceq>(G,L);   
schirmer@12854
   261
  wf_prog G; case oref of Heap a \<Rightarrow> is_type G (obj_ty \<lparr>tag=oi,values=vs\<rparr>)  
schirmer@12854
   262
                        | Stat C \<Rightarrow> is_class G C\<rbrakk> \<Longrightarrow>  
schirmer@12854
   263
  (x, init_obj G oi oref s)\<Colon>\<preceq>(G, L)"
schirmer@12854
   264
apply (unfold init_obj_def)
schirmer@12854
   265
apply (auto elim!: conforms_gupd dest!: oconf_init_obj 
schirmer@15217
   266
            )
schirmer@12854
   267
done
schirmer@12854
   268
schirmer@12854
   269
lemma conforms_init_class_obj: 
schirmer@12854
   270
 "\<lbrakk>(x,s)\<Colon>\<preceq>(G, L); wf_prog G; class G C=Some y; \<not> inited C (globs s)\<rbrakk> \<Longrightarrow> 
schirmer@12854
   271
  (x,init_class_obj G C s)\<Colon>\<preceq>(G, L)"
schirmer@12854
   272
apply (rule not_initedD [THEN conforms_newG])
schirmer@12854
   273
apply    (auto)
schirmer@12854
   274
done
schirmer@12854
   275
schirmer@12854
   276
schirmer@12854
   277
lemma fst_init_lvars[simp]: 
schirmer@12854
   278
 "fst (init_lvars G C sig (invmode m e) a' pvs (x,s)) = 
schirmer@12925
   279
  (if is_static m then x else (np a') x)"
schirmer@12854
   280
apply (simp (no_asm) add: init_lvars_def2)
schirmer@12854
   281
done
schirmer@12854
   282
schirmer@12854
   283
schirmer@12854
   284
lemma halloc_conforms: "\<And>s1. \<lbrakk>G\<turnstile>s1 \<midarrow>halloc oi\<succ>a\<rightarrow> s2; wf_prog G; s1\<Colon>\<preceq>(G, L); 
schirmer@12854
   285
  is_type G (obj_ty \<lparr>tag=oi,values=fs\<rparr>)\<rbrakk> \<Longrightarrow> s2\<Colon>\<preceq>(G, L)"
schirmer@12854
   286
apply (simp (no_asm_simp) only: split_tupled_all)
schirmer@12854
   287
apply (case_tac "aa")
schirmer@12854
   288
apply  (auto elim!: halloc_elim_cases dest!: new_AddrD 
schirmer@12854
   289
       intro!: conforms_newG [THEN conforms_xconf] conf_AddrI)
schirmer@12854
   290
done
schirmer@12854
   291
schirmer@12925
   292
lemma halloc_type_sound: 
schirmer@12925
   293
"\<And>s1. \<lbrakk>G\<turnstile>s1 \<midarrow>halloc oi\<succ>a\<rightarrow> (x,s); wf_prog G; s1\<Colon>\<preceq>(G, L);
schirmer@12854
   294
  T = obj_ty \<lparr>tag=oi,values=fs\<rparr>; is_type G T\<rbrakk> \<Longrightarrow>  
schirmer@12854
   295
  (x,s)\<Colon>\<preceq>(G, L) \<and> (x = None \<longrightarrow> G,s\<turnstile>Addr a\<Colon>\<preceq>T)"
schirmer@12854
   296
apply (auto elim!: halloc_conforms)
schirmer@12854
   297
apply (case_tac "aa")
schirmer@12854
   298
apply (subst obj_ty_eq)
schirmer@12854
   299
apply  (auto elim!: halloc_elim_cases dest!: new_AddrD intro!: conf_AddrI)
schirmer@12854
   300
done
schirmer@12854
   301
schirmer@12854
   302
lemma sxalloc_type_sound: 
schirmer@13688
   303
 "\<And>s1 s2. \<lbrakk>G\<turnstile>s1 \<midarrow>sxalloc\<rightarrow> s2; wf_prog G\<rbrakk> \<Longrightarrow> 
schirmer@13688
   304
  case fst s1 of  
schirmer@13688
   305
    None \<Rightarrow> s2 = s1 
schirmer@13688
   306
  | Some abr \<Rightarrow> (case abr of
schirmer@13688
   307
                   Xcpt x \<Rightarrow> (\<exists>a. fst s2 = Some(Xcpt (Loc a)) \<and> 
schirmer@13688
   308
                                  (\<forall>L. s1\<Colon>\<preceq>(G,L) \<longrightarrow> s2\<Colon>\<preceq>(G,L)))
schirmer@13688
   309
                 | Jump j \<Rightarrow> s2 = s1
schirmer@13688
   310
                 | Error e \<Rightarrow> s2 = s1)"
schirmer@12854
   311
apply (simp (no_asm_simp) only: split_tupled_all)
schirmer@12854
   312
apply (erule sxalloc.induct)
schirmer@12854
   313
apply   auto
schirmer@12854
   314
apply (rule halloc_conforms [THEN conforms_xconf])
schirmer@12854
   315
apply     (auto elim!: halloc_elim_cases dest!: new_AddrD intro!: conf_AddrI)
schirmer@12854
   316
done
schirmer@12854
   317
schirmer@12854
   318
lemma wt_init_comp_ty: 
schirmer@12854
   319
"is_acc_type G (pid C) T \<Longrightarrow> \<lparr>prg=G,cls=C,lcl=L\<rparr>\<turnstile>init_comp_ty T\<Colon>\<surd>"
schirmer@12854
   320
apply (unfold init_comp_ty_def)
schirmer@12854
   321
apply (clarsimp simp add: accessible_in_RefT_simp 
schirmer@12854
   322
                          is_acc_type_def is_acc_class_def)
schirmer@12854
   323
done
schirmer@12854
   324
schirmer@12854
   325
schirmer@12854
   326
declare fun_upd_same [simp]
schirmer@12854
   327
schirmer@12854
   328
declare fun_upd_apply [simp del]
schirmer@12854
   329
wenzelm@37956
   330
definition
wenzelm@37956
   331
  DynT_prop :: "[prog,inv_mode,qtname,ref_ty] \<Rightarrow> bool" ("_\<turnstile>_\<rightarrow>_\<preceq>_"[71,71,71,71]70)
wenzelm@37956
   332
where
wenzelm@37956
   333
  "G\<turnstile>mode\<rightarrow>D\<preceq>t = (mode = IntVir \<longrightarrow> is_class G D \<and> 
wenzelm@37956
   334
                     (if (\<exists>T. t=ArrayT T) then D=Object else G\<turnstile>Class D\<preceq>RefT t))"
schirmer@12854
   335
schirmer@12854
   336
lemma DynT_propI: 
schirmer@12854
   337
 "\<lbrakk>(x,s)\<Colon>\<preceq>(G, L); G,s\<turnstile>a'\<Colon>\<preceq>RefT statT; wf_prog G; mode = IntVir \<longrightarrow> a' \<noteq> Null\<rbrakk> 
schirmer@12854
   338
  \<Longrightarrow>  G\<turnstile>mode\<rightarrow>invocation_class mode s a' statT\<preceq>statT"
schirmer@12854
   339
proof (unfold DynT_prop_def)
schirmer@12854
   340
  assume state_conform: "(x,s)\<Colon>\<preceq>(G, L)"
schirmer@12854
   341
     and      statT_a': "G,s\<turnstile>a'\<Colon>\<preceq>RefT statT"
schirmer@12854
   342
     and            wf: "wf_prog G"
schirmer@12854
   343
     and          mode: "mode = IntVir \<longrightarrow> a' \<noteq> Null"
schirmer@12854
   344
  let ?invCls = "(invocation_class mode s a' statT)"
schirmer@12854
   345
  let ?IntVir = "mode = IntVir"
schirmer@12854
   346
  let ?Concl  = "\<lambda>invCls. is_class G invCls \<and>
schirmer@12854
   347
                          (if \<exists>T. statT = ArrayT T
schirmer@12854
   348
                                  then invCls = Object
schirmer@12854
   349
                                  else G\<turnstile>Class invCls\<preceq>RefT statT)"
schirmer@12854
   350
  show "?IntVir \<longrightarrow> ?Concl ?invCls"
schirmer@12854
   351
  proof  
schirmer@12854
   352
    assume modeIntVir: ?IntVir 
schirmer@12854
   353
    with mode have not_Null: "a' \<noteq> Null" ..
schirmer@12854
   354
    from statT_a' not_Null state_conform 
schirmer@12854
   355
    obtain a obj 
schirmer@12854
   356
      where obj_props:  "a' = Addr a" "globs s (Inl a) = Some obj"   
schirmer@12854
   357
                        "G\<turnstile>obj_ty obj\<preceq>RefT statT" "is_type G (obj_ty obj)"
schirmer@12854
   358
      by (blast dest: conforms_RefTD)
schirmer@12854
   359
    show "?Concl ?invCls"
schirmer@12854
   360
    proof (cases "tag obj")
schirmer@12854
   361
      case CInst
schirmer@12854
   362
      with modeIntVir obj_props
schirmer@12854
   363
      show ?thesis 
wenzelm@46714
   364
        by (auto dest!: widen_Array2)
schirmer@12854
   365
    next
schirmer@12854
   366
      case Arr
wenzelm@46714
   367
      from Arr obtain T where "obj_ty obj = T.[]" by blast
schirmer@12854
   368
      moreover from Arr have "obj_class obj = Object" 
wenzelm@46714
   369
        by blast
schirmer@12854
   370
      moreover note modeIntVir obj_props wf 
schirmer@12854
   371
      ultimately show ?thesis by (auto dest!: widen_Array )
schirmer@12854
   372
    qed
schirmer@12854
   373
  qed
schirmer@12854
   374
qed
schirmer@12854
   375
schirmer@12854
   376
lemma invocation_methd:
schirmer@12854
   377
"\<lbrakk>wf_prog G; statT \<noteq> NullT; 
schirmer@12854
   378
 (\<forall> statC. statT = ClassT statC \<longrightarrow> is_class G statC);
schirmer@12854
   379
 (\<forall>     I. statT = IfaceT I \<longrightarrow> is_iface G I \<and> mode \<noteq> SuperM);
schirmer@12854
   380
 (\<forall>     T. statT = ArrayT T \<longrightarrow> mode \<noteq> SuperM);
schirmer@12854
   381
 G\<turnstile>mode\<rightarrow>invocation_class mode s a' statT\<preceq>statT;  
schirmer@12854
   382
 dynlookup G statT (invocation_class mode s a' statT) sig = Some m \<rbrakk> 
schirmer@12854
   383
\<Longrightarrow> methd G (invocation_declclass G mode s a' statT sig) sig = Some m"
schirmer@12854
   384
proof -
schirmer@12854
   385
  assume         wf: "wf_prog G"
schirmer@12854
   386
     and  not_NullT: "statT \<noteq> NullT"
schirmer@12854
   387
     and statC_prop: "(\<forall> statC. statT = ClassT statC \<longrightarrow> is_class G statC)"
schirmer@12854
   388
     and statI_prop: "(\<forall> I. statT = IfaceT I \<longrightarrow> is_iface G I \<and> mode \<noteq> SuperM)"
schirmer@12854
   389
     and statA_prop: "(\<forall>     T. statT = ArrayT T \<longrightarrow> mode \<noteq> SuperM)"
schirmer@12854
   390
     and  invC_prop: "G\<turnstile>mode\<rightarrow>invocation_class mode s a' statT\<preceq>statT"
schirmer@12854
   391
     and  dynlookup: "dynlookup G statT (invocation_class mode s a' statT) sig 
schirmer@12854
   392
                      = Some m"
schirmer@12854
   393
  show ?thesis
schirmer@12854
   394
  proof (cases statT)
schirmer@12854
   395
    case NullT
schirmer@12854
   396
    with not_NullT show ?thesis by simp
schirmer@12854
   397
  next
schirmer@12854
   398
    case IfaceT
schirmer@12854
   399
    with statI_prop obtain I 
schirmer@12854
   400
      where    statI: "statT = IfaceT I" and 
schirmer@12854
   401
            is_iface: "is_iface G I"     and
schirmer@12854
   402
          not_SuperM: "mode \<noteq> SuperM" by blast            
schirmer@12854
   403
    
schirmer@12854
   404
    show ?thesis 
schirmer@12854
   405
    proof (cases mode)
schirmer@12854
   406
      case Static
schirmer@12854
   407
      with wf dynlookup statI is_iface 
schirmer@12854
   408
      show ?thesis
wenzelm@32960
   409
        by (auto simp add: invocation_declclass_def dynlookup_def 
schirmer@12854
   410
                           dynimethd_def dynmethd_C_C 
wenzelm@32960
   411
                    intro: dynmethd_declclass
wenzelm@32960
   412
                    dest!: wf_imethdsD
wenzelm@46714
   413
                     dest: table_of_map_SomeI)
wenzelm@32960
   414
    next        
schirmer@12854
   415
      case SuperM
schirmer@12854
   416
      with not_SuperM show ?thesis ..
schirmer@12854
   417
    next
schirmer@12854
   418
      case IntVir
schirmer@12854
   419
      with wf dynlookup IfaceT invC_prop show ?thesis 
wenzelm@32960
   420
        by (auto simp add: invocation_declclass_def dynlookup_def dynimethd_def
schirmer@12854
   421
                           DynT_prop_def
wenzelm@46714
   422
                    intro: methd_declclass dynmethd_declclass)
schirmer@12854
   423
    qed
schirmer@12854
   424
  next
schirmer@12854
   425
    case ClassT
schirmer@12854
   426
    show ?thesis
schirmer@12854
   427
    proof (cases mode)
schirmer@12854
   428
      case Static
schirmer@12854
   429
      with wf ClassT dynlookup statC_prop 
schirmer@12854
   430
      show ?thesis by (auto simp add: invocation_declclass_def dynlookup_def
schirmer@12854
   431
                               intro: dynmethd_declclass)
schirmer@12854
   432
    next
schirmer@12854
   433
      case SuperM
schirmer@12854
   434
      with wf ClassT dynlookup statC_prop 
schirmer@12854
   435
      show ?thesis by (auto simp add: invocation_declclass_def dynlookup_def
schirmer@12854
   436
                               intro: dynmethd_declclass)
schirmer@12854
   437
    next
schirmer@12854
   438
      case IntVir
schirmer@12854
   439
      with wf ClassT dynlookup statC_prop invC_prop 
schirmer@12854
   440
      show ?thesis
wenzelm@32960
   441
        by (auto simp add: invocation_declclass_def dynlookup_def dynimethd_def
schirmer@12854
   442
                           DynT_prop_def
wenzelm@32960
   443
                    intro: dynmethd_declclass)
schirmer@12854
   444
    qed
schirmer@12854
   445
  next
schirmer@12854
   446
    case ArrayT
schirmer@12854
   447
    show ?thesis
schirmer@12854
   448
    proof (cases mode)
schirmer@12854
   449
      case Static
schirmer@12854
   450
      with wf ArrayT dynlookup show ?thesis
wenzelm@32960
   451
        by (auto simp add: invocation_declclass_def dynlookup_def 
schirmer@12854
   452
                           dynimethd_def dynmethd_C_C
schirmer@12854
   453
                    intro: dynmethd_declclass
schirmer@12854
   454
                     dest: table_of_map_SomeI)
schirmer@12854
   455
    next
schirmer@12854
   456
      case SuperM
schirmer@12854
   457
      with ArrayT statA_prop show ?thesis by blast
schirmer@12854
   458
    next
schirmer@12854
   459
      case IntVir
schirmer@12854
   460
      with wf ArrayT dynlookup invC_prop show ?thesis
wenzelm@32960
   461
        by (auto simp add: invocation_declclass_def dynlookup_def dynimethd_def
schirmer@12854
   462
                           DynT_prop_def dynmethd_C_C
schirmer@12854
   463
                    intro: dynmethd_declclass
schirmer@12854
   464
                     dest: table_of_map_SomeI)
schirmer@12854
   465
    qed
schirmer@12854
   466
  qed
schirmer@12854
   467
qed
schirmer@12925
   468
schirmer@12854
   469
lemma DynT_mheadsD: 
schirmer@12925
   470
"\<lbrakk>G\<turnstile>invmode sm e\<rightarrow>invC\<preceq>statT; 
schirmer@12854
   471
  wf_prog G; \<lparr>prg=G,cls=C,lcl=L\<rparr>\<turnstile>e\<Colon>-RefT statT; 
schirmer@12925
   472
  (statDeclT,sm) \<in> mheads G C statT sig; 
schirmer@12925
   473
  invC = invocation_class (invmode sm e) s a' statT;
schirmer@12925
   474
  declC =invocation_declclass G (invmode sm e) s a' statT sig
schirmer@12854
   475
 \<rbrakk> \<Longrightarrow> 
schirmer@12854
   476
  \<exists> dm. 
schirmer@12925
   477
  methd G declC sig = Some dm \<and> dynlookup G statT invC sig = Some dm  \<and> 
schirmer@12925
   478
  G\<turnstile>resTy (mthd dm)\<preceq>resTy sm \<and> 
schirmer@12854
   479
  wf_mdecl G declC (sig, mthd dm) \<and>
schirmer@12854
   480
  declC = declclass dm \<and>
schirmer@12854
   481
  is_static dm = is_static sm \<and>  
schirmer@12854
   482
  is_class G invC \<and> is_class G declC  \<and> G\<turnstile>invC\<preceq>\<^sub>C declC \<and>  
schirmer@12925
   483
  (if invmode sm e = IntVir
schirmer@12854
   484
      then (\<forall> statC. statT=ClassT statC \<longrightarrow> G\<turnstile>invC \<preceq>\<^sub>C statC)
schirmer@12854
   485
      else (  (\<exists> statC. statT=ClassT statC \<and> G\<turnstile>statC\<preceq>\<^sub>C declC)
schirmer@12854
   486
            \<or> (\<forall> statC. statT\<noteq>ClassT statC \<and> declC=Object)) \<and> 
schirmer@12925
   487
            statDeclT = ClassT (declclass dm))"
schirmer@12854
   488
proof -
schirmer@12925
   489
  assume invC_prop: "G\<turnstile>invmode sm e\<rightarrow>invC\<preceq>statT" 
schirmer@12854
   490
     and        wf: "wf_prog G" 
schirmer@12854
   491
     and      wt_e: "\<lparr>prg=G,cls=C,lcl=L\<rparr>\<turnstile>e\<Colon>-RefT statT"
schirmer@12925
   492
     and        sm: "(statDeclT,sm) \<in> mheads G C statT sig" 
schirmer@12925
   493
     and      invC: "invC = invocation_class (invmode sm e) s a' statT"
schirmer@12854
   494
     and     declC: "declC = 
schirmer@12925
   495
                    invocation_declclass G (invmode sm e) s a' statT sig"
schirmer@12854
   496
  from wt_e wf have type_statT: "is_type G (RefT statT)"
schirmer@12854
   497
    by (auto dest: ty_expr_is_type)
schirmer@12854
   498
  from sm have not_Null: "statT \<noteq> NullT" by auto
schirmer@12854
   499
  from type_statT 
schirmer@12854
   500
  have wf_C: "(\<forall> statC. statT = ClassT statC \<longrightarrow> is_class G statC)"
schirmer@12854
   501
    by (auto)
schirmer@12854
   502
  from type_statT wt_e 
schirmer@12854
   503
  have wf_I: "(\<forall>I. statT = IfaceT I \<longrightarrow> is_iface G I \<and> 
schirmer@12925
   504
                                        invmode sm e \<noteq> SuperM)"
schirmer@12854
   505
    by (auto dest: invocationTypeExpr_noClassD)
schirmer@12854
   506
  from wt_e
schirmer@12925
   507
  have wf_A: "(\<forall>     T. statT = ArrayT T \<longrightarrow> invmode sm e \<noteq> SuperM)"
schirmer@12854
   508
    by (auto dest: invocationTypeExpr_noClassD)
schirmer@12854
   509
  show ?thesis
schirmer@12925
   510
  proof (cases "invmode sm e = IntVir")
schirmer@12854
   511
    case True
schirmer@12854
   512
    with invC_prop not_Null
schirmer@12854
   513
    have invC_prop': " is_class G invC \<and> 
schirmer@12854
   514
                      (if (\<exists>T. statT=ArrayT T) then invC=Object 
schirmer@12854
   515
                                              else G\<turnstile>Class invC\<preceq>RefT statT)"
schirmer@12854
   516
      by (auto simp add: DynT_prop_def) 
schirmer@12854
   517
    from True 
schirmer@12854
   518
    have "\<not> is_static sm"
schirmer@12925
   519
      by (simp add: invmode_IntVir_eq member_is_static_simp)
schirmer@12854
   520
    with invC_prop' not_Null
schirmer@12854
   521
    have "G,statT \<turnstile> invC valid_lookup_cls_for (is_static sm)"
schirmer@12854
   522
      by (cases statT) auto
schirmer@12854
   523
    with sm wf type_statT obtain dm where
schirmer@12854
   524
           dm: "dynlookup G statT invC sig = Some dm" and
schirmer@12925
   525
      resT_dm: "G\<turnstile>resTy (mthd dm)\<preceq>resTy sm"      and
schirmer@12854
   526
       static: "is_static dm = is_static sm"
schirmer@12925
   527
      by  - (drule dynamic_mheadsD,force+)
schirmer@12854
   528
    with declC invC not_Null 
schirmer@12854
   529
    have declC': "declC = (declclass dm)" 
schirmer@12854
   530
      by (auto simp add: invocation_declclass_def)
schirmer@12854
   531
    with wf invC declC not_Null wf_C wf_I wf_A invC_prop dm 
schirmer@12854
   532
    have dm': "methd G declC sig = Some dm"
schirmer@12854
   533
      by - (drule invocation_methd,auto)
schirmer@12854
   534
    from wf dm invC_prop' declC' type_statT 
schirmer@12854
   535
    have declC_prop: "G\<turnstile>invC \<preceq>\<^sub>C declC \<and> is_class G declC"
schirmer@12854
   536
      by (auto dest: dynlookup_declC)
schirmer@12854
   537
    from wf dm' declC_prop declC' 
schirmer@12854
   538
    have wf_dm: "wf_mdecl G declC (sig,(mthd dm))"
schirmer@12854
   539
      by (auto dest: methd_wf_mdecl)
schirmer@12854
   540
    from invC_prop' 
schirmer@12854
   541
    have statC_prop: "(\<forall> statC. statT=ClassT statC \<longrightarrow> G\<turnstile>invC \<preceq>\<^sub>C statC)"
schirmer@12854
   542
      by auto
schirmer@12854
   543
    from True dm' resT_dm wf_dm invC_prop' declC_prop statC_prop declC' static
schirmer@12925
   544
         dm
schirmer@12854
   545
    show ?thesis by auto
schirmer@12854
   546
  next
schirmer@12854
   547
    case False
schirmer@12854
   548
    with type_statT wf invC not_Null wf_I wf_A
schirmer@12854
   549
    have invC_prop': "is_class G invC \<and>  
schirmer@12854
   550
                     ((\<exists> statC. statT=ClassT statC \<and> invC=statC) \<or>
schirmer@12925
   551
                      (\<forall> statC. statT\<noteq>ClassT statC \<and> invC=Object))"
schirmer@12854
   552
        by (case_tac "statT") (auto simp add: invocation_class_def 
schirmer@12854
   553
                                       split: inv_mode.splits)
schirmer@12854
   554
    with not_Null wf
schirmer@12854
   555
    have dynlookup_static: "dynlookup G statT invC sig = methd G invC sig"
schirmer@12854
   556
      by (case_tac "statT") (auto simp add: dynlookup_def dynmethd_C_C
schirmer@12854
   557
                                            dynimethd_def)
schirmer@12854
   558
    from sm wf wt_e not_Null False invC_prop' obtain "dm" where
schirmer@12854
   559
                    dm: "methd G invC sig = Some dm"          and
wenzelm@32960
   560
        eq_declC_sm_dm:"statDeclT = ClassT (declclass dm)"  and
wenzelm@32960
   561
             eq_mheads:"sm=mhead (mthd dm) "
schirmer@12925
   562
      by - (drule static_mheadsD, (force dest: accmethd_SomeD)+)
schirmer@12925
   563
    then have static: "is_static dm = is_static sm" by - (auto)
schirmer@12854
   564
    with declC invC dynlookup_static dm
schirmer@12854
   565
    have declC': "declC = (declclass dm)"  
schirmer@12854
   566
      by (auto simp add: invocation_declclass_def)
schirmer@12854
   567
    from invC_prop' wf declC' dm 
schirmer@12854
   568
    have dm': "methd G declC sig = Some dm"
schirmer@12854
   569
      by (auto intro: methd_declclass)
schirmer@12925
   570
    from dynlookup_static dm 
schirmer@12925
   571
    have dm'': "dynlookup G statT invC sig = Some dm"
schirmer@12925
   572
      by simp
schirmer@12854
   573
    from wf dm invC_prop' declC' type_statT 
schirmer@12854
   574
    have declC_prop: "G\<turnstile>invC \<preceq>\<^sub>C declC \<and> is_class G declC"
schirmer@12854
   575
      by (auto dest: methd_declC )
schirmer@12854
   576
    then have declC_prop1: "invC=Object \<longrightarrow> declC=Object"  by auto
schirmer@12854
   577
    from wf dm' declC_prop declC' 
schirmer@12854
   578
    have wf_dm: "wf_mdecl G declC (sig,(mthd dm))"
schirmer@12854
   579
      by (auto dest: methd_wf_mdecl)
schirmer@12854
   580
    from invC_prop' declC_prop declC_prop1
schirmer@12854
   581
    have statC_prop: "(   (\<exists> statC. statT=ClassT statC \<and> G\<turnstile>statC\<preceq>\<^sub>C declC)
schirmer@12854
   582
                       \<or>  (\<forall> statC. statT\<noteq>ClassT statC \<and> declC=Object))" 
schirmer@12854
   583
      by auto
schirmer@12925
   584
    from False dm' dm'' wf_dm invC_prop' declC_prop statC_prop declC' 
schirmer@12854
   585
         eq_declC_sm_dm eq_mheads static
schirmer@12854
   586
    show ?thesis by auto
schirmer@12854
   587
  qed
schirmer@13688
   588
qed
schirmer@13688
   589
schirmer@13688
   590
corollary DynT_mheadsE [consumes 7]: 
schirmer@13688
   591
--{* Same as @{text DynT_mheadsD} but better suited for application in 
schirmer@13688
   592
typesafety proof   *}
schirmer@13688
   593
 assumes invC_compatible: "G\<turnstile>mode\<rightarrow>invC\<preceq>statT" 
schirmer@13688
   594
     and wf: "wf_prog G" 
schirmer@13688
   595
     and wt_e: "\<lparr>prg=G,cls=C,lcl=L\<rparr>\<turnstile>e\<Colon>-RefT statT"
schirmer@13688
   596
     and mheads: "(statDeclT,sm) \<in> mheads G C statT sig"
schirmer@13688
   597
     and mode: "mode=invmode sm e" 
schirmer@13688
   598
     and invC: "invC = invocation_class mode s a' statT"
schirmer@13688
   599
     and declC: "declC =invocation_declclass G mode s a' statT sig"
schirmer@13688
   600
     and dm: "\<And> dm. \<lbrakk>methd G declC sig = Some dm; 
schirmer@13688
   601
                      dynlookup G statT invC sig = Some dm; 
schirmer@13688
   602
                      G\<turnstile>resTy (mthd dm)\<preceq>resTy sm; 
schirmer@13688
   603
                      wf_mdecl G declC (sig, mthd dm);
schirmer@13688
   604
                      declC = declclass dm;
schirmer@13688
   605
                      is_static dm = is_static sm;  
schirmer@13688
   606
                      is_class G invC; is_class G declC; G\<turnstile>invC\<preceq>\<^sub>C declC;  
schirmer@13688
   607
                      (if invmode sm e = IntVir
schirmer@13688
   608
                      then (\<forall> statC. statT=ClassT statC \<longrightarrow> G\<turnstile>invC \<preceq>\<^sub>C statC)
schirmer@13688
   609
                      else (  (\<exists> statC. statT=ClassT statC \<and> G\<turnstile>statC\<preceq>\<^sub>C declC)
schirmer@13688
   610
                             \<or> (\<forall> statC. statT\<noteq>ClassT statC \<and> declC=Object)) \<and>
schirmer@13688
   611
                             statDeclT = ClassT (declclass dm))\<rbrakk> \<Longrightarrow> P"
schirmer@13688
   612
   shows "P"
schirmer@13688
   613
proof -
schirmer@13688
   614
    from invC_compatible mode have "G\<turnstile>invmode sm e\<rightarrow>invC\<preceq>statT" by simp 
schirmer@13688
   615
    moreover note wf wt_e mheads
schirmer@13688
   616
    moreover from invC mode 
schirmer@13688
   617
    have "invC = invocation_class (invmode sm e) s a' statT" by simp
schirmer@13688
   618
    moreover from declC mode 
schirmer@13688
   619
    have "declC =invocation_declclass G (invmode sm e) s a' statT sig" by simp
schirmer@13688
   620
    ultimately show ?thesis
schirmer@13688
   621
      by (rule DynT_mheadsD [THEN exE,rule_format])
schirmer@13688
   622
         (elim conjE,rule dm)
schirmer@13688
   623
qed
schirmer@13688
   624
   
schirmer@12854
   625
schirmer@12854
   626
lemma DynT_conf: "\<lbrakk>G\<turnstile>invocation_class mode s a' statT \<preceq>\<^sub>C declC; wf_prog G;
schirmer@12854
   627
 isrtype G (statT);
schirmer@12854
   628
 G,s\<turnstile>a'\<Colon>\<preceq>RefT statT; mode = IntVir \<longrightarrow> a' \<noteq> Null;  
schirmer@12854
   629
  mode \<noteq> IntVir \<longrightarrow>    (\<exists> statC. statT=ClassT statC \<and> G\<turnstile>statC\<preceq>\<^sub>C declC)
schirmer@12854
   630
                    \<or>  (\<forall> statC. statT\<noteq>ClassT statC \<and> declC=Object)\<rbrakk> 
schirmer@12854
   631
 \<Longrightarrow>G,s\<turnstile>a'\<Colon>\<preceq> Class declC"
schirmer@12854
   632
apply (case_tac "mode = IntVir")
schirmer@12854
   633
apply (drule conf_RefTD)
schirmer@12854
   634
apply (force intro!: conf_AddrI 
schirmer@12854
   635
            simp add: obj_class_def split add: obj_tag.split_asm)
schirmer@12854
   636
apply  clarsimp
schirmer@12854
   637
apply  safe
schirmer@12854
   638
apply    (erule (1) widen.subcls [THEN conf_widen])
schirmer@12854
   639
apply    (erule wf_ws_prog)
schirmer@12854
   640
schirmer@12854
   641
apply    (frule widen_Object) apply (erule wf_ws_prog)
schirmer@12854
   642
apply    (erule (1) conf_widen) apply (erule wf_ws_prog)
schirmer@12854
   643
done
schirmer@12854
   644
schirmer@12925
   645
lemma Ass_lemma:
schirmer@12925
   646
"\<lbrakk> G\<turnstile>Norm s0 \<midarrow>var=\<succ>(w, f)\<rightarrow> Norm s1; G\<turnstile>Norm s1 \<midarrow>e-\<succ>v\<rightarrow> Norm s2;
schirmer@12925
   647
   G,s2\<turnstile>v\<Colon>\<preceq>eT;s1\<le>|s2 \<longrightarrow> assign f v (Norm s2)\<Colon>\<preceq>(G, L)\<rbrakk>
schirmer@12925
   648
\<Longrightarrow> assign f v (Norm s2)\<Colon>\<preceq>(G, L) \<and>
schirmer@12925
   649
      (normal (assign f v (Norm s2)) \<longrightarrow> G,store (assign f v (Norm s2))\<turnstile>v\<Colon>\<preceq>eT)"
schirmer@12854
   650
apply (drule_tac x = "None" and s = "s2" and v = "v" in evar_gext_f)
schirmer@12854
   651
apply (drule eval_gext', clarsimp)
schirmer@12854
   652
apply (erule conf_gext)
schirmer@12854
   653
apply simp
schirmer@12854
   654
done
schirmer@12854
   655
schirmer@12854
   656
lemma Throw_lemma: "\<lbrakk>G\<turnstile>tn\<preceq>\<^sub>C SXcpt Throwable; wf_prog G; (x1,s1)\<Colon>\<preceq>(G, L);  
schirmer@12854
   657
    x1 = None \<longrightarrow> G,s1\<turnstile>a'\<Colon>\<preceq> Class tn\<rbrakk> \<Longrightarrow> (throw a' x1, s1)\<Colon>\<preceq>(G, L)"
schirmer@12854
   658
apply (auto split add: split_abrupt_if simp add: throw_def2)
schirmer@12854
   659
apply (erule conforms_xconf)
schirmer@12854
   660
apply (frule conf_RefTD)
schirmer@12854
   661
apply (auto elim: widen.subcls [THEN conf_widen])
schirmer@12854
   662
done
schirmer@12854
   663
schirmer@12854
   664
lemma Try_lemma: "\<lbrakk>G\<turnstile>obj_ty (the (globs s1' (Heap a)))\<preceq> Class tn; 
schirmer@12854
   665
 (Some (Xcpt (Loc a)), s1')\<Colon>\<preceq>(G, L); wf_prog G\<rbrakk> 
schirmer@12854
   666
 \<Longrightarrow> Norm (lupd(vn\<mapsto>Addr a) s1')\<Colon>\<preceq>(G, L(vn\<mapsto>Class tn))"
schirmer@12854
   667
apply (rule conforms_allocL)
schirmer@12854
   668
apply  (erule conforms_NormI)
schirmer@12854
   669
apply (drule conforms_XcptLocD [THEN conf_RefTD],rule HOL.refl)
schirmer@12854
   670
apply (auto intro!: conf_AddrI)
schirmer@12854
   671
done
schirmer@12854
   672
schirmer@12854
   673
lemma Fin_lemma: 
schirmer@13688
   674
"\<lbrakk>G\<turnstile>Norm s1 \<midarrow>c2\<rightarrow> (x2,s2); wf_prog G; (Some a, s1)\<Colon>\<preceq>(G, L); (x2,s2)\<Colon>\<preceq>(G, L);
schirmer@13688
   675
  dom (locals s1) \<subseteq> dom (locals s2)\<rbrakk> 
schirmer@12854
   676
\<Longrightarrow>  (abrupt_if True (Some a) x2, s2)\<Colon>\<preceq>(G, L)"
schirmer@13688
   677
apply (auto elim: eval_gext' conforms_xgext split add: split_abrupt_if)
schirmer@12854
   678
done
schirmer@12854
   679
schirmer@12925
   680
lemma FVar_lemma1: 
schirmer@12925
   681
"\<lbrakk>table_of (DeclConcepts.fields G statC) (fn, statDeclC) = Some f ; 
schirmer@12925
   682
  x2 = None \<longrightarrow> G,s2\<turnstile>a\<Colon>\<preceq> Class statC; wf_prog G; G\<turnstile>statC\<preceq>\<^sub>C statDeclC; 
schirmer@12925
   683
  statDeclC \<noteq> Object; 
schirmer@12925
   684
  class G statDeclC = Some y; (x2,s2)\<Colon>\<preceq>(G, L); s1\<le>|s2; 
schirmer@12925
   685
  inited statDeclC (globs s1); 
schirmer@12854
   686
  (if static f then id else np a) x2 = None\<rbrakk> 
schirmer@12854
   687
 \<Longrightarrow>  
schirmer@12925
   688
  \<exists>obj. globs s2 (if static f then Inr statDeclC else Inl (the_Addr a)) 
schirmer@12925
   689
                  = Some obj \<and> 
schirmer@12925
   690
  var_tys G (tag obj)  (if static f then Inr statDeclC else Inl(the_Addr a)) 
schirmer@12925
   691
          (Inl(fn,statDeclC)) = Some (type f)"
schirmer@12854
   692
apply (drule initedD)
schirmer@12854
   693
apply (frule subcls_is_class2, simp (no_asm_simp))
schirmer@12854
   694
apply (case_tac "static f")
schirmer@12854
   695
apply  clarsimp
schirmer@12854
   696
apply  (drule (1) rev_gext_objD, clarsimp)
schirmer@12854
   697
apply  (frule fields_declC, erule wf_ws_prog, simp (no_asm_simp))
schirmer@12854
   698
apply  (rule var_tys_Some_eq [THEN iffD2])
schirmer@12854
   699
apply  clarsimp
schirmer@12854
   700
apply  (erule fields_table_SomeI, simp (no_asm))
schirmer@12854
   701
apply clarsimp
schirmer@12854
   702
apply (drule conf_RefTD, clarsimp, rule var_tys_Some_eq [THEN iffD2])
schirmer@12854
   703
apply (auto dest!: widen_Array split add: obj_tag.split)
schirmer@12854
   704
apply (rule fields_table_SomeI)
schirmer@12854
   705
apply (auto elim!: fields_mono subcls_is_class2)
schirmer@12854
   706
done
schirmer@12854
   707
schirmer@12925
   708
lemma FVar_lemma2: "error_free state
schirmer@12925
   709
       \<Longrightarrow> error_free
schirmer@12925
   710
           (assign
schirmer@12925
   711
             (\<lambda>v. supd
schirmer@12925
   712
                   (upd_gobj
schirmer@12925
   713
                     (if static field then Inr statDeclC
schirmer@12925
   714
                      else Inl (the_Addr a))
schirmer@12925
   715
                     (Inl (fn, statDeclC)) v))
schirmer@12925
   716
             w state)"
schirmer@12925
   717
proof -
schirmer@12925
   718
  assume error_free: "error_free state"
schirmer@12925
   719
  obtain a s where "state=(a,s)"
wenzelm@23350
   720
    by (cases state)
schirmer@12925
   721
  with error_free
schirmer@12925
   722
  show ?thesis
schirmer@12925
   723
    by (cases a) auto
schirmer@12925
   724
qed
schirmer@12925
   725
schirmer@12925
   726
declare split_paired_All [simp del] split_paired_Ex [simp del] 
schirmer@12925
   727
declare split_if     [split del] split_if_asm     [split del] 
schirmer@12925
   728
        option.split [split del] option.split_asm [split del]
wenzelm@24019
   729
declaration {* K (Simplifier.map_ss (fn ss => ss delloop "split_all_tac")) *}
wenzelm@24019
   730
declaration {* K (Classical.map_cs (fn cs => cs delSWrapper "split_all_tac")) *}
wenzelm@24019
   731
schirmer@12854
   732
lemma FVar_lemma: 
schirmer@12925
   733
"\<lbrakk>((v, f), Norm s2') = fvar statDeclC (static field) fn a (x2, s2); 
schirmer@12925
   734
  G\<turnstile>statC\<preceq>\<^sub>C statDeclC;  
schirmer@12925
   735
  table_of (DeclConcepts.fields G statC) (fn, statDeclC) = Some field; 
schirmer@12925
   736
  wf_prog G;   
schirmer@12925
   737
  x2 = None \<longrightarrow> G,s2\<turnstile>a\<Colon>\<preceq>Class statC; 
schirmer@12925
   738
  statDeclC \<noteq> Object; class G statDeclC = Some y;   
schirmer@12925
   739
  (x2, s2)\<Colon>\<preceq>(G, L); s1\<le>|s2; inited statDeclC (globs s1)\<rbrakk> \<Longrightarrow>  
schirmer@12854
   740
  G,s2'\<turnstile>v\<Colon>\<preceq>type field \<and> s2'\<le>|f\<preceq>type field\<Colon>\<preceq>(G, L)"
schirmer@12854
   741
apply (unfold assign_conforms_def)
schirmer@12854
   742
apply (drule sym)
schirmer@12854
   743
apply (clarsimp simp add: fvar_def2)
schirmer@12854
   744
apply (drule (9) FVar_lemma1)
schirmer@12854
   745
apply (clarsimp)
schirmer@12854
   746
apply (drule (2) conforms_globsD [THEN oconf_lconf, THEN lconfD])
schirmer@12854
   747
apply clarsimp
schirmer@12925
   748
apply (rule conjI)
schirmer@12925
   749
apply   clarsimp
schirmer@12925
   750
apply   (drule (1) rev_gext_objD)
schirmer@12925
   751
apply   (force elim!: conforms_upd_gobj)
schirmer@12925
   752
schirmer@12925
   753
apply   (blast intro: FVar_lemma2)
schirmer@12854
   754
done
schirmer@12925
   755
declare split_paired_All [simp] split_paired_Ex [simp] 
schirmer@12925
   756
declare split_if     [split] split_if_asm     [split] 
schirmer@12925
   757
        option.split [split] option.split_asm [split]
wenzelm@24019
   758
declaration {* K (Classical.map_cs (fn cs => cs addSbefore ("split_all_tac", split_all_tac))) *}
wenzelm@24019
   759
declaration {* K (Simplifier.map_ss (fn ss => ss addloop ("split_all_tac", split_all_tac))) *}
schirmer@12854
   760
schirmer@12854
   761
schirmer@12854
   762
lemma AVar_lemma1: "\<lbrakk>globs s (Inl a) = Some obj;tag obj=Arr ty i; 
schirmer@12854
   763
 the_Intg i' in_bounds i; wf_prog G; G\<turnstile>ty.[]\<preceq>Tb.[]; Norm s\<Colon>\<preceq>(G, L)
schirmer@12854
   764
\<rbrakk> \<Longrightarrow> G,s\<turnstile>the ((values obj) (Inr (the_Intg i')))\<Colon>\<preceq>Tb"
schirmer@12854
   765
apply (erule widen_Array_Array [THEN conf_widen])
schirmer@12854
   766
apply  (erule_tac [2] wf_ws_prog)
schirmer@12854
   767
apply (drule (1) conforms_globsD [THEN oconf_lconf, THEN lconfD])
schirmer@12854
   768
defer apply assumption
schirmer@12854
   769
apply (force intro: var_tys_Some_eq [THEN iffD2])
schirmer@12854
   770
done
schirmer@12854
   771
schirmer@14700
   772
lemma obj_split: "\<exists> t vs. obj = \<lparr>tag=t,values=vs\<rparr>"
schirmer@14700
   773
  by (cases obj) auto
schirmer@12854
   774
 
schirmer@12925
   775
lemma AVar_lemma2: "error_free state 
schirmer@12925
   776
       \<Longrightarrow> error_free
schirmer@12925
   777
           (assign
schirmer@12925
   778
             (\<lambda>v (x, s').
schirmer@12925
   779
                 ((raise_if (\<not> G,s'\<turnstile>v fits T) ArrStore) x,
schirmer@12925
   780
                  upd_gobj (Inl a) (Inr (the_Intg i)) v s'))
schirmer@12925
   781
             w state)"
schirmer@12925
   782
proof -
schirmer@12925
   783
  assume error_free: "error_free state"
schirmer@12925
   784
  obtain a s where "state=(a,s)"
wenzelm@23350
   785
    by (cases state)
schirmer@12925
   786
  with error_free
schirmer@12925
   787
  show ?thesis
schirmer@12925
   788
    by (cases a) auto
schirmer@12925
   789
qed
schirmer@12925
   790
schirmer@12854
   791
lemma AVar_lemma: "\<lbrakk>wf_prog G; G\<turnstile>(x1, s1) \<midarrow>e2-\<succ>i\<rightarrow> (x2, s2);  
schirmer@12854
   792
  ((v,f), Norm s2') = avar G i a (x2, s2); x1 = None \<longrightarrow> G,s1\<turnstile>a\<Colon>\<preceq>Ta.[];  
schirmer@12854
   793
  (x2, s2)\<Colon>\<preceq>(G, L); s1\<le>|s2\<rbrakk> \<Longrightarrow> G,s2'\<turnstile>v\<Colon>\<preceq>Ta \<and> s2'\<le>|f\<preceq>Ta\<Colon>\<preceq>(G, L)"
schirmer@12854
   794
apply (unfold assign_conforms_def)
schirmer@12854
   795
apply (drule sym)
schirmer@12854
   796
apply (clarsimp simp add: avar_def2)
schirmer@12854
   797
apply (drule (1) conf_gext)
schirmer@12854
   798
apply (drule conf_RefTD, clarsimp)
schirmer@12854
   799
apply (subgoal_tac "\<exists> t vs. obj = \<lparr>tag=t,values=vs\<rparr>")
schirmer@12854
   800
defer
schirmer@12854
   801
apply   (rule obj_split)
schirmer@12854
   802
apply clarify
schirmer@12854
   803
apply (frule obj_ty_widenD)
schirmer@12854
   804
apply (auto dest!: widen_Class)
schirmer@12925
   805
apply   (force dest: AVar_lemma1)
schirmer@12925
   806
schirmer@12925
   807
apply   (force elim!: fits_Array dest: gext_objD 
schirmer@12925
   808
         intro: var_tys_Some_eq [THEN iffD2] conforms_upd_gobj)
schirmer@12854
   809
done
schirmer@12854
   810
schirmer@13688
   811
schirmer@12925
   812
section "Call"
schirmer@12854
   813
schirmer@12854
   814
lemma conforms_init_lvars_lemma: "\<lbrakk>wf_prog G;  
schirmer@13688
   815
  wf_mhead G P sig mh;
schirmer@12854
   816
  list_all2 (conf G s) pvs pTsa; G\<turnstile>pTsa[\<preceq>](parTs sig)\<rbrakk> \<Longrightarrow>  
schirmer@13688
   817
  G,s\<turnstile>empty (pars mh[\<mapsto>]pvs)
schirmer@13688
   818
      [\<sim>\<Colon>\<preceq>]table_of lvars(pars mh[\<mapsto>]parTs sig)"
schirmer@12854
   819
apply (unfold wf_mhead_def)
schirmer@12854
   820
apply clarify
schirmer@13688
   821
apply (erule (1) wlconf_empty_vals [THEN wlconf_ext_list])
schirmer@12854
   822
apply (drule wf_ws_prog)
schirmer@12854
   823
apply (erule (2) conf_list_widen)
schirmer@12854
   824
done
schirmer@12854
   825
schirmer@12854
   826
schirmer@12854
   827
lemma lconf_map_lname [simp]: 
schirmer@12854
   828
  "G,s\<turnstile>(lname_case l1 l2)[\<Colon>\<preceq>](lname_case L1 L2)
schirmer@12854
   829
   =
schirmer@12854
   830
  (G,s\<turnstile>l1[\<Colon>\<preceq>]L1 \<and> G,s\<turnstile>(\<lambda>x::unit . l2)[\<Colon>\<preceq>](\<lambda>x::unit. L2))"
schirmer@12854
   831
apply (unfold lconf_def)
schirmer@13688
   832
apply (auto split add: lname.splits)
schirmer@13688
   833
done
schirmer@13688
   834
schirmer@13688
   835
lemma wlconf_map_lname [simp]: 
schirmer@13688
   836
  "G,s\<turnstile>(lname_case l1 l2)[\<sim>\<Colon>\<preceq>](lname_case L1 L2)
schirmer@13688
   837
   =
schirmer@13688
   838
  (G,s\<turnstile>l1[\<sim>\<Colon>\<preceq>]L1 \<and> G,s\<turnstile>(\<lambda>x::unit . l2)[\<sim>\<Colon>\<preceq>](\<lambda>x::unit. L2))"
schirmer@13688
   839
apply (unfold wlconf_def)
schirmer@13688
   840
apply (auto split add: lname.splits)
schirmer@12854
   841
done
schirmer@12854
   842
schirmer@12854
   843
lemma lconf_map_ename [simp]:
schirmer@12854
   844
  "G,s\<turnstile>(ename_case l1 l2)[\<Colon>\<preceq>](ename_case L1 L2)
schirmer@12854
   845
   =
schirmer@12854
   846
  (G,s\<turnstile>l1[\<Colon>\<preceq>]L1 \<and> G,s\<turnstile>(\<lambda>x::unit. l2)[\<Colon>\<preceq>](\<lambda>x::unit. L2))"
schirmer@12854
   847
apply (unfold lconf_def)
schirmer@13688
   848
apply (auto split add: ename.splits)
schirmer@12854
   849
done
schirmer@12854
   850
schirmer@13688
   851
lemma wlconf_map_ename [simp]:
schirmer@13688
   852
  "G,s\<turnstile>(ename_case l1 l2)[\<sim>\<Colon>\<preceq>](ename_case L1 L2)
schirmer@13688
   853
   =
schirmer@13688
   854
  (G,s\<turnstile>l1[\<sim>\<Colon>\<preceq>]L1 \<and> G,s\<turnstile>(\<lambda>x::unit. l2)[\<sim>\<Colon>\<preceq>](\<lambda>x::unit. L2))"
schirmer@13688
   855
apply (unfold wlconf_def)
schirmer@13688
   856
apply (auto split add: ename.splits)
schirmer@13688
   857
done
schirmer@13688
   858
schirmer@13688
   859
schirmer@12854
   860
schirmer@12854
   861
lemma defval_conf1 [rule_format (no_asm), elim]: 
schirmer@12854
   862
  "is_type G T \<longrightarrow> (\<exists>v\<in>Some (default_val T): G,s\<turnstile>v\<Colon>\<preceq>T)"
schirmer@12854
   863
apply (unfold conf_def)
schirmer@12854
   864
apply (induct "T")
schirmer@12854
   865
apply (auto intro: prim_ty.induct)
schirmer@12854
   866
done
schirmer@12854
   867
schirmer@13688
   868
lemma np_no_jump: "x\<noteq>Some (Jump j) \<Longrightarrow> (np a') x \<noteq> Some (Jump j)"
schirmer@13688
   869
by (auto simp add: abrupt_if_def)
schirmer@13688
   870
schirmer@12925
   871
declare split_paired_All [simp del] split_paired_Ex [simp del] 
schirmer@12925
   872
declare split_if     [split del] split_if_asm     [split del] 
schirmer@12925
   873
        option.split [split del] option.split_asm [split del]
wenzelm@24019
   874
declaration {* K (Simplifier.map_ss (fn ss => ss delloop "split_all_tac")) *}
wenzelm@24019
   875
declaration {* K (Classical.map_cs (fn cs => cs delSWrapper "split_all_tac")) *}
wenzelm@24019
   876
schirmer@12854
   877
lemma conforms_init_lvars: 
schirmer@12854
   878
"\<lbrakk>wf_mhead G (pid declC) sig (mhead (mthd dm)); wf_prog G;  
schirmer@12854
   879
  list_all2 (conf G s) pvs pTsa; G\<turnstile>pTsa[\<preceq>](parTs sig);  
schirmer@12854
   880
  (x, s)\<Colon>\<preceq>(G, L); 
schirmer@12854
   881
  methd G declC sig = Some dm;  
schirmer@12854
   882
  isrtype G statT;
schirmer@12854
   883
  G\<turnstile>invC\<preceq>\<^sub>C declC; 
schirmer@12854
   884
  G,s\<turnstile>a'\<Colon>\<preceq>RefT statT;  
schirmer@12854
   885
  invmode (mhd sm) e = IntVir \<longrightarrow> a' \<noteq> Null; 
schirmer@12854
   886
  invmode (mhd sm) e \<noteq> IntVir \<longrightarrow>  
schirmer@12854
   887
       (\<exists> statC. statT=ClassT statC \<and> G\<turnstile>statC\<preceq>\<^sub>C declC)
schirmer@12854
   888
    \<or>  (\<forall> statC. statT\<noteq>ClassT statC \<and> declC=Object);
schirmer@12854
   889
  invC  = invocation_class (invmode (mhd sm) e) s a' statT;
schirmer@12854
   890
  declC = invocation_declclass G (invmode (mhd sm) e) s a' statT sig;
schirmer@13688
   891
  x\<noteq>Some (Jump Ret) 
schirmer@12854
   892
 \<rbrakk> \<Longrightarrow>  
schirmer@12854
   893
  init_lvars G declC sig (invmode (mhd sm) e) a'  
schirmer@12854
   894
  pvs (x,s)\<Colon>\<preceq>(G,\<lambda> k. 
schirmer@12854
   895
                (case k of
schirmer@12854
   896
                   EName e \<Rightarrow> (case e of 
schirmer@12854
   897
                                 VNam v 
schirmer@12854
   898
                                  \<Rightarrow> (table_of (lcls (mbody (mthd dm)))
schirmer@12854
   899
                                        (pars (mthd dm)[\<mapsto>]parTs sig)) v
schirmer@12854
   900
                               | Res \<Rightarrow> Some (resTy (mthd dm)))
schirmer@12925
   901
                 | This \<Rightarrow> if (is_static (mthd sm)) 
schirmer@12854
   902
                              then None else Some (Class declC)))"
schirmer@12854
   903
apply (simp add: init_lvars_def2)
schirmer@12854
   904
apply (rule conforms_set_locals)
schirmer@12854
   905
apply  (simp (no_asm_simp) split add: split_if)
schirmer@12854
   906
apply (drule  (4) DynT_conf)
schirmer@12854
   907
apply clarsimp
schirmer@12854
   908
(* apply intro *)
schirmer@13688
   909
apply (drule (3) conforms_init_lvars_lemma 
schirmer@13688
   910
                 [where ?lvars="(lcls (mbody (mthd dm)))"])
schirmer@12854
   911
apply (case_tac "dm",simp)
schirmer@12854
   912
apply (rule conjI)
schirmer@13688
   913
apply (unfold wlconf_def, clarify)
schirmer@13688
   914
apply   (clarsimp simp add: wf_mhead_def is_acc_type_def)
schirmer@13688
   915
apply   (case_tac "is_static sm")
schirmer@13688
   916
apply     simp
schirmer@13688
   917
apply     simp
schirmer@13688
   918
schirmer@13688
   919
apply   simp
schirmer@13688
   920
apply   (case_tac "is_static sm")
schirmer@13688
   921
apply     simp
schirmer@13688
   922
apply     (simp add: np_no_jump)
schirmer@12854
   923
done
schirmer@12925
   924
declare split_paired_All [simp] split_paired_Ex [simp] 
schirmer@12925
   925
declare split_if     [split] split_if_asm     [split] 
schirmer@12925
   926
        option.split [split] option.split_asm [split]
wenzelm@24019
   927
declaration {* K (Classical.map_cs (fn cs => cs addSbefore ("split_all_tac", split_all_tac))) *}
wenzelm@24019
   928
declaration {* K (Simplifier.map_ss (fn ss => ss addloop ("split_all_tac", split_all_tac))) *}
schirmer@12854
   929
schirmer@12854
   930
schirmer@12854
   931
subsection "accessibility"
schirmer@12854
   932
schirmer@12854
   933
theorem dynamic_field_access_ok:
wenzelm@12937
   934
  assumes wf: "wf_prog G" and
wenzelm@12937
   935
    not_Null: "\<not> stat \<longrightarrow> a\<noteq>Null" and
wenzelm@12937
   936
   conform_a: "G,(store s)\<turnstile>a\<Colon>\<preceq> Class statC" and
wenzelm@12937
   937
   conform_s: "s\<Colon>\<preceq>(G, L)" and 
wenzelm@12937
   938
    normal_s: "normal s" and
wenzelm@12937
   939
        wt_e: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile>e\<Colon>-Class statC" and
wenzelm@12937
   940
           f: "accfield G accC statC fn = Some f" and
wenzelm@12937
   941
        dynC: "if stat then dynC=declclass f  
wenzelm@12937
   942
                       else dynC=obj_class (lookup_obj (store s) a)" and
wenzelm@12937
   943
        stat: "if stat then (is_static f) else (\<not> is_static f)"
schirmer@13688
   944
  shows "table_of (DeclConcepts.fields G dynC) (fn,declclass f) = Some (fld f)\<and>
schirmer@13688
   945
         G\<turnstile>Field fn f in dynC dyn_accessible_from accC"
schirmer@12854
   946
proof (cases "stat")
schirmer@12854
   947
  case True
schirmer@12925
   948
  with stat have static: "(is_static f)" by simp
schirmer@12925
   949
  from True dynC 
schirmer@12925
   950
  have dynC': "dynC=declclass f" by simp
schirmer@12854
   951
  with f
schirmer@12925
   952
  have "table_of (DeclConcepts.fields G statC) (fn,declclass f) = Some (fld f)"
schirmer@12854
   953
    by (auto simp add: accfield_def Let_def intro!: table_of_remap_SomeD)
schirmer@12925
   954
  moreover
schirmer@12925
   955
  from wt_e wf have "is_class G statC"
schirmer@12925
   956
    by (auto dest!: ty_expr_is_type)
schirmer@12925
   957
  moreover note wf dynC'
schirmer@12925
   958
  ultimately have
schirmer@12925
   959
     "table_of (DeclConcepts.fields G dynC) (fn,declclass f) = Some (fld f)"
schirmer@12925
   960
    by (auto dest: fields_declC)
schirmer@12925
   961
  with dynC' f static wf
schirmer@12854
   962
  show ?thesis
schirmer@12925
   963
    by (auto dest: static_to_dynamic_accessible_from_static
schirmer@12925
   964
            dest!: accfield_accessibleD )
schirmer@12854
   965
next
schirmer@12854
   966
  case False
schirmer@12925
   967
  with wf conform_a not_Null conform_s dynC
schirmer@12854
   968
  obtain subclseq: "G\<turnstile>dynC \<preceq>\<^sub>C statC" and
schirmer@12854
   969
    "is_class G dynC"
schirmer@12925
   970
    by (auto dest!: conforms_RefTD [of _ _ _ _ "(fst s)" L]
schirmer@12854
   971
              dest: obj_ty_obj_class1
schirmer@12854
   972
          simp add: obj_ty_obj_class )
schirmer@12854
   973
  with wf f
schirmer@12854
   974
  have "table_of (DeclConcepts.fields G dynC) (fn,declclass f) = Some (fld f)"
schirmer@12854
   975
    by (auto simp add: accfield_def Let_def
schirmer@12854
   976
                 dest: fields_mono
schirmer@12854
   977
                dest!: table_of_remap_SomeD)
schirmer@12854
   978
  moreover
schirmer@12854
   979
  from f subclseq
schirmer@12854
   980
  have "G\<turnstile>Field fn f in dynC dyn_accessible_from accC"
wenzelm@23350
   981
    by (auto intro!: static_to_dynamic_accessible_from wf
schirmer@12854
   982
               dest: accfield_accessibleD)
schirmer@12854
   983
  ultimately show ?thesis
schirmer@12854
   984
    by blast
schirmer@12854
   985
qed
schirmer@12854
   986
schirmer@12925
   987
lemma error_free_field_access:
wenzelm@12937
   988
  assumes accfield: "accfield G accC statC fn = Some (statDeclC, f)" and
schirmer@12925
   989
              wt_e: "\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>e\<Colon>-Class statC" and
schirmer@12925
   990
         eval_init: "G\<turnstile>Norm s0 \<midarrow>Init statDeclC\<rightarrow> s1" and
schirmer@12925
   991
            eval_e: "G\<turnstile>s1 \<midarrow>e-\<succ>a\<rightarrow> s2" and
schirmer@12925
   992
           conf_s2: "s2\<Colon>\<preceq>(G, L)" and
schirmer@12925
   993
            conf_a: "normal s2 \<Longrightarrow> G, store s2\<turnstile>a\<Colon>\<preceq>Class statC" and
schirmer@12925
   994
              fvar: "(v,s2')=fvar statDeclC (is_static f) fn a s2" and
schirmer@12925
   995
                wf: "wf_prog G"   
wenzelm@12937
   996
  shows "check_field_access G accC statDeclC fn (is_static f) a s2' = s2'"
schirmer@12925
   997
proof -
schirmer@12925
   998
  from fvar
schirmer@12925
   999
  have store_s2': "store s2'=store s2"
schirmer@12925
  1000
    by (cases s2) (simp add: fvar_def2)
schirmer@12925
  1001
  with fvar conf_s2 
schirmer@12925
  1002
  have conf_s2': "s2'\<Colon>\<preceq>(G, L)"
schirmer@12925
  1003
    by (cases s2,cases "is_static f") (auto simp add: fvar_def2)
schirmer@12925
  1004
  from eval_init 
schirmer@12925
  1005
  have initd_statDeclC_s1: "initd statDeclC s1"
schirmer@12925
  1006
    by (rule init_yields_initd)
schirmer@12925
  1007
  with eval_e store_s2'
schirmer@12925
  1008
  have initd_statDeclC_s2': "initd statDeclC s2'"
schirmer@12925
  1009
    by (auto dest: eval_gext intro: inited_gext)
schirmer@12925
  1010
  show ?thesis
schirmer@12925
  1011
  proof (cases "normal s2'")
schirmer@12925
  1012
    case False
schirmer@12925
  1013
    then show ?thesis 
schirmer@12925
  1014
      by (auto simp add: check_field_access_def Let_def)
schirmer@12925
  1015
  next
schirmer@12925
  1016
    case True
schirmer@12925
  1017
    with fvar store_s2' 
schirmer@12925
  1018
    have not_Null: "\<not> (is_static f) \<longrightarrow> a\<noteq>Null" 
schirmer@12925
  1019
      by (cases s2) (auto simp add: fvar_def2)
schirmer@12925
  1020
    from True fvar store_s2'
schirmer@12925
  1021
    have "normal s2"
schirmer@12925
  1022
      by (cases s2,cases "is_static f") (auto simp add: fvar_def2)
schirmer@12925
  1023
    with conf_a store_s2'
schirmer@12925
  1024
    have conf_a': "G,store s2'\<turnstile>a\<Colon>\<preceq>Class statC"
schirmer@12925
  1025
      by simp
schirmer@12925
  1026
    from conf_a' conf_s2' True initd_statDeclC_s2' 
schirmer@12925
  1027
      dynamic_field_access_ok [OF wf not_Null conf_a' conf_s2' 
schirmer@12925
  1028
                                   True wt_e accfield ] 
schirmer@12925
  1029
    show ?thesis
schirmer@12925
  1030
      by  (cases "is_static f")
schirmer@12925
  1031
          (auto dest!: initedD
schirmer@12925
  1032
           simp add: check_field_access_def Let_def)
schirmer@12925
  1033
  qed
schirmer@12925
  1034
qed
schirmer@12925
  1035
schirmer@12925
  1036
lemma call_access_ok:
wenzelm@12937
  1037
  assumes invC_prop: "G\<turnstile>invmode statM e\<rightarrow>invC\<preceq>statT" 
wenzelm@12937
  1038
      and        wf: "wf_prog G" 
wenzelm@12937
  1039
      and      wt_e: "\<lparr>prg=G,cls=C,lcl=L\<rparr>\<turnstile>e\<Colon>-RefT statT"
wenzelm@12937
  1040
      and     statM: "(statDeclT,statM) \<in> mheads G accC statT sig" 
wenzelm@12937
  1041
      and      invC: "invC = invocation_class (invmode statM e) s a statT"
wenzelm@12937
  1042
  shows "\<exists> dynM. dynlookup G statT invC sig = Some dynM \<and>
schirmer@12854
  1043
  G\<turnstile>Methd sig dynM in invC dyn_accessible_from accC"
schirmer@12854
  1044
proof -
schirmer@12854
  1045
  from wt_e wf have type_statT: "is_type G (RefT statT)"
schirmer@12854
  1046
    by (auto dest: ty_expr_is_type)
schirmer@12854
  1047
  from statM have not_Null: "statT \<noteq> NullT" by auto
schirmer@12854
  1048
  from type_statT wt_e 
schirmer@12854
  1049
  have wf_I: "(\<forall>I. statT = IfaceT I \<longrightarrow> is_iface G I \<and> 
schirmer@12925
  1050
                                        invmode statM e \<noteq> SuperM)"
schirmer@12854
  1051
    by (auto dest: invocationTypeExpr_noClassD)
schirmer@12854
  1052
  from wt_e
schirmer@12925
  1053
  have wf_A: "(\<forall>     T. statT = ArrayT T \<longrightarrow> invmode statM e \<noteq> SuperM)"
schirmer@12854
  1054
    by (auto dest: invocationTypeExpr_noClassD)
schirmer@12854
  1055
  show ?thesis
schirmer@12925
  1056
  proof (cases "invmode statM e = IntVir")
schirmer@12854
  1057
    case True
schirmer@12854
  1058
    with invC_prop not_Null
schirmer@12854
  1059
    have invC_prop': "is_class G invC \<and>  
schirmer@12854
  1060
                      (if (\<exists>T. statT=ArrayT T) then invC=Object 
schirmer@12854
  1061
                                              else G\<turnstile>Class invC\<preceq>RefT statT)"
schirmer@12854
  1062
      by (auto simp add: DynT_prop_def)
schirmer@12854
  1063
    with True not_Null
schirmer@12854
  1064
    have "G,statT \<turnstile> invC valid_lookup_cls_for is_static statM"
schirmer@12925
  1065
     by (cases statT) (auto simp add: invmode_def) 
schirmer@12854
  1066
    with statM type_statT wf 
schirmer@12854
  1067
    show ?thesis
schirmer@12854
  1068
      by - (rule dynlookup_access,auto)
schirmer@12854
  1069
  next
schirmer@12854
  1070
    case False
schirmer@12854
  1071
    with type_statT wf invC not_Null wf_I wf_A
schirmer@12854
  1072
    have invC_prop': " is_class G invC \<and>
schirmer@12854
  1073
                      ((\<exists> statC. statT=ClassT statC \<and> invC=statC) \<or>
schirmer@12854
  1074
                      (\<forall> statC. statT\<noteq>ClassT statC \<and> invC=Object)) "
schirmer@12854
  1075
        by (case_tac "statT") (auto simp add: invocation_class_def 
schirmer@12854
  1076
                                       split: inv_mode.splits)
schirmer@12854
  1077
    with not_Null wf
schirmer@12854
  1078
    have dynlookup_static: "dynlookup G statT invC sig = methd G invC sig"
schirmer@12854
  1079
      by (case_tac "statT") (auto simp add: dynlookup_def dynmethd_C_C
schirmer@12854
  1080
                                            dynimethd_def)
schirmer@12854
  1081
   from statM wf wt_e not_Null False invC_prop' obtain dynM where
schirmer@12854
  1082
                "accmethd G accC invC sig = Some dynM" 
schirmer@12854
  1083
     by (auto dest!: static_mheadsD)
schirmer@12854
  1084
   from invC_prop' False not_Null wf_I
schirmer@12854
  1085
   have "G,statT \<turnstile> invC valid_lookup_cls_for is_static statM"
schirmer@12925
  1086
     by (cases statT) (auto simp add: invmode_def) 
schirmer@12854
  1087
   with statM type_statT wf 
schirmer@12854
  1088
    show ?thesis
schirmer@12854
  1089
      by - (rule dynlookup_access,auto)
schirmer@12854
  1090
  qed
schirmer@12854
  1091
qed
schirmer@12854
  1092
schirmer@12925
  1093
lemma error_free_call_access:
wenzelm@12937
  1094
  assumes
schirmer@12925
  1095
   eval_args: "G\<turnstile>s1 \<midarrow>args\<doteq>\<succ>vs\<rightarrow> s2" and
schirmer@12925
  1096
        wt_e: "\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>e\<Colon>-(RefT statT)" and  
schirmer@12925
  1097
       statM: "max_spec G accC statT \<lparr>name = mn, parTs = pTs\<rparr> 
schirmer@12925
  1098
               = {((statDeclT, statM), pTs')}" and
schirmer@12925
  1099
     conf_s2: "s2\<Colon>\<preceq>(G, L)" and
schirmer@12925
  1100
      conf_a: "normal s1 \<Longrightarrow> G, store s1\<turnstile>a\<Colon>\<preceq>RefT statT" and
schirmer@12925
  1101
     invProp: "normal s3 \<Longrightarrow>
schirmer@12925
  1102
                G\<turnstile>invmode statM e\<rightarrow>invC\<preceq>statT" and
schirmer@12925
  1103
          s3: "s3=init_lvars G invDeclC \<lparr>name = mn, parTs = pTs'\<rparr> 
schirmer@12925
  1104
                        (invmode statM e) a vs s2" and
schirmer@12925
  1105
        invC: "invC = invocation_class (invmode statM e) (store s2) a statT"and
schirmer@12925
  1106
    invDeclC: "invDeclC = invocation_declclass G (invmode statM e) (store s2) 
schirmer@12925
  1107
                             a statT \<lparr>name = mn, parTs = pTs'\<rparr>" and
schirmer@12925
  1108
          wf: "wf_prog G"
wenzelm@12937
  1109
  shows "check_method_access G accC statT (invmode statM e) \<lparr>name=mn,parTs=pTs'\<rparr> a s3
schirmer@12925
  1110
   = s3"
schirmer@12925
  1111
proof (cases "normal s2")
schirmer@12925
  1112
  case False
schirmer@12925
  1113
  with s3 
schirmer@12925
  1114
  have "abrupt s3 = abrupt s2"  
schirmer@12925
  1115
    by (auto simp add: init_lvars_def2)
schirmer@12925
  1116
  with False
schirmer@12925
  1117
  show ?thesis
schirmer@12925
  1118
    by (auto simp add: check_method_access_def Let_def)
schirmer@12925
  1119
next
schirmer@12925
  1120
  case True
schirmer@12925
  1121
  note normal_s2 = True
schirmer@12925
  1122
  with eval_args
schirmer@12925
  1123
  have normal_s1: "normal s1"
schirmer@12925
  1124
    by (cases "normal s1") auto
schirmer@12925
  1125
  with conf_a eval_args 
schirmer@12925
  1126
  have conf_a_s2: "G, store s2\<turnstile>a\<Colon>\<preceq>RefT statT"
schirmer@12925
  1127
    by (auto dest: eval_gext intro: conf_gext)
schirmer@12925
  1128
  show ?thesis
schirmer@12925
  1129
  proof (cases "a=Null \<longrightarrow> (is_static statM)")
schirmer@12925
  1130
    case False
schirmer@12925
  1131
    then obtain "\<not> is_static statM" "a=Null" 
schirmer@12925
  1132
      by blast
schirmer@12925
  1133
    with normal_s2 s3
schirmer@12925
  1134
    have "abrupt s3 = Some (Xcpt (Std NullPointer))" 
schirmer@12925
  1135
      by (auto simp add: init_lvars_def2)
schirmer@12925
  1136
    then show ?thesis
schirmer@12925
  1137
      by (auto simp add: check_method_access_def Let_def)
schirmer@12925
  1138
  next
schirmer@12925
  1139
    case True
schirmer@12925
  1140
    from statM 
schirmer@12925
  1141
    obtain
schirmer@12925
  1142
      statM': "(statDeclT,statM)\<in>mheads G accC statT \<lparr>name=mn,parTs=pTs'\<rparr>" 
schirmer@12925
  1143
      by (blast dest: max_spec2mheads)
schirmer@12925
  1144
    from True normal_s2 s3
schirmer@12925
  1145
    have "normal s3"
schirmer@12925
  1146
      by (auto simp add: init_lvars_def2)
schirmer@12925
  1147
    then have "G\<turnstile>invmode statM e\<rightarrow>invC\<preceq>statT"
schirmer@12925
  1148
      by (rule invProp)
schirmer@12925
  1149
    with wt_e statM' wf invC
schirmer@12925
  1150
    obtain dynM where 
schirmer@12925
  1151
      dynM: "dynlookup G statT invC  \<lparr>name=mn,parTs=pTs'\<rparr> = Some dynM" and
schirmer@12925
  1152
      acc_dynM: "G \<turnstile>Methd  \<lparr>name=mn,parTs=pTs'\<rparr> dynM 
schirmer@12925
  1153
                          in invC dyn_accessible_from accC"
schirmer@12925
  1154
      by (force dest!: call_access_ok)
schirmer@12925
  1155
    moreover
schirmer@12925
  1156
    from s3 invC
schirmer@12925
  1157
    have invC': "invC=(invocation_class (invmode statM e) (store s3) a statT)"
schirmer@12925
  1158
      by (cases s2,cases "invmode statM e") 
schirmer@12925
  1159
         (simp add: init_lvars_def2 del: invmode_Static_eq)+
schirmer@12925
  1160
    ultimately
schirmer@12925
  1161
    show ?thesis
schirmer@12925
  1162
      by (auto simp add: check_method_access_def Let_def)
schirmer@12925
  1163
  qed
schirmer@12925
  1164
qed
schirmer@12925
  1165
schirmer@13688
  1166
lemma map_upds_eq_length_append_simp:
schirmer@13688
  1167
  "\<And> tab qs. length ps = length qs \<Longrightarrow>  tab(ps[\<mapsto>]qs@zs) = tab(ps[\<mapsto>]qs)"
schirmer@13688
  1168
proof (induct ps) 
schirmer@13688
  1169
  case Nil thus ?case by simp
schirmer@13688
  1170
next
schirmer@13688
  1171
  case (Cons p ps tab qs)
wenzelm@23350
  1172
  from `length (p#ps) = length qs`
wenzelm@23350
  1173
  obtain q qs' where qs: "qs=q#qs'" and eq_length: "length ps=length qs'"
schirmer@13688
  1174
    by (cases qs) auto
schirmer@13688
  1175
  from eq_length have "(tab(p\<mapsto>q))(ps[\<mapsto>]qs'@zs)=(tab(p\<mapsto>q))(ps[\<mapsto>]qs')"
schirmer@13688
  1176
    by (rule Cons.hyps)
schirmer@13688
  1177
  with qs show ?case 
schirmer@13688
  1178
    by simp
schirmer@13688
  1179
qed
schirmer@13688
  1180
schirmer@13688
  1181
lemma map_upds_upd_eq_length_simp:
schirmer@13688
  1182
  "\<And> tab qs x y. length ps = length qs 
schirmer@13688
  1183
                  \<Longrightarrow> tab(ps[\<mapsto>]qs)(x\<mapsto>y) = tab(ps@[x][\<mapsto>]qs@[y])"
schirmer@13688
  1184
proof (induct "ps")
schirmer@13688
  1185
  case Nil thus ?case by simp
schirmer@13688
  1186
next
schirmer@13688
  1187
  case (Cons p ps tab qs x y)
wenzelm@23350
  1188
  from `length (p#ps) = length qs`
wenzelm@23350
  1189
  obtain q qs' where qs: "qs=q#qs'" and eq_length: "length ps=length qs'"
schirmer@13688
  1190
    by (cases qs) auto
schirmer@13688
  1191
  from eq_length 
schirmer@13688
  1192
  have "(tab(p\<mapsto>q))(ps[\<mapsto>]qs')(x\<mapsto>y) = (tab(p\<mapsto>q))(ps@[x][\<mapsto>]qs'@[y])"
schirmer@13688
  1193
    by (rule Cons.hyps)
schirmer@13688
  1194
  with qs show ?case
schirmer@13688
  1195
    by simp
schirmer@13688
  1196
qed
schirmer@13688
  1197
schirmer@13688
  1198
schirmer@13688
  1199
lemma map_upd_cong: "tab=tab'\<Longrightarrow> tab(x\<mapsto>y) = tab'(x\<mapsto>y)"
schirmer@13688
  1200
by simp
schirmer@13688
  1201
schirmer@13688
  1202
lemma map_upd_cong_ext: "tab z=tab' z\<Longrightarrow> (tab(x\<mapsto>y)) z = (tab'(x\<mapsto>y)) z"
schirmer@13688
  1203
by (simp add: fun_upd_def)
schirmer@13688
  1204
schirmer@13688
  1205
lemma map_upds_cong: "tab=tab'\<Longrightarrow> tab(xs[\<mapsto>]ys) = tab'(xs[\<mapsto>]ys)"
schirmer@13688
  1206
by (cases xs) simp+
schirmer@13688
  1207
schirmer@13688
  1208
lemma map_upds_cong_ext: 
schirmer@13688
  1209
 "\<And> tab tab' ys. tab z=tab' z \<Longrightarrow> (tab(xs[\<mapsto>]ys)) z = (tab'(xs[\<mapsto>]ys)) z"
schirmer@13688
  1210
proof (induct xs)
schirmer@13688
  1211
  case Nil thus ?case by simp
schirmer@13688
  1212
next
schirmer@13688
  1213
  case (Cons x xs tab tab' ys)
schirmer@14030
  1214
  note Hyps = this
schirmer@14030
  1215
  show ?case
schirmer@14030
  1216
  proof (cases ys)
schirmer@14030
  1217
    case Nil
wenzelm@23350
  1218
    with Hyps
wenzelm@23350
  1219
    show ?thesis by simp
schirmer@14030
  1220
  next
schirmer@14030
  1221
    case (Cons y ys')
schirmer@14030
  1222
    have "(tab(x\<mapsto>y)(xs[\<mapsto>]ys')) z = (tab'(x\<mapsto>y)(xs[\<mapsto>]ys')) z"
nipkow@17589
  1223
      by (iprover intro: Hyps map_upd_cong_ext)
schirmer@14030
  1224
    with Cons show ?thesis
schirmer@14030
  1225
      by simp
schirmer@14030
  1226
  qed
schirmer@13688
  1227
qed
schirmer@13688
  1228
   
schirmer@13688
  1229
lemma map_upd_override: "(tab(x\<mapsto>y)) x = (tab'(x\<mapsto>y)) x"
schirmer@13688
  1230
  by simp
schirmer@13688
  1231
schirmer@13688
  1232
lemma map_upds_eq_length_suffix: "\<And> tab qs. 
schirmer@13688
  1233
        length ps = length qs \<Longrightarrow> tab(ps@xs[\<mapsto>]qs) = tab(ps[\<mapsto>]qs)(xs[\<mapsto>][])"
schirmer@13688
  1234
proof (induct ps)
schirmer@13688
  1235
  case Nil thus ?case by simp
schirmer@13688
  1236
next
schirmer@13688
  1237
  case (Cons p ps tab qs)
schirmer@13688
  1238
  then obtain q qs' where qs: "qs=q#qs'" and eq_length: "length ps=length qs'"
schirmer@13688
  1239
    by (cases qs) auto
schirmer@13688
  1240
  from eq_length
schirmer@13688
  1241
  have "tab(p\<mapsto>q)(ps @ xs[\<mapsto>]qs') = tab(p\<mapsto>q)(ps[\<mapsto>]qs')(xs[\<mapsto>][])"
schirmer@13688
  1242
    by (rule Cons.hyps)
schirmer@13688
  1243
  with qs show ?case 
schirmer@13688
  1244
    by simp
schirmer@13688
  1245
qed
schirmer@13688
  1246
  
schirmer@13688
  1247
  
schirmer@13688
  1248
lemma map_upds_upds_eq_length_prefix_simp:
schirmer@13688
  1249
  "\<And> tab qs. length ps = length qs
schirmer@13688
  1250
              \<Longrightarrow> tab(ps[\<mapsto>]qs)(xs[\<mapsto>]ys) = tab(ps@xs[\<mapsto>]qs@ys)"
schirmer@13688
  1251
proof (induct ps)
schirmer@13688
  1252
  case Nil thus ?case by simp
schirmer@13688
  1253
next
schirmer@13688
  1254
  case (Cons p ps tab qs)
schirmer@13688
  1255
  then obtain q qs' where qs: "qs=q#qs'" and eq_length: "length ps=length qs'"
schirmer@13688
  1256
    by (cases qs) auto
schirmer@13688
  1257
  from eq_length 
schirmer@13688
  1258
  have "tab(p\<mapsto>q)(ps[\<mapsto>]qs')(xs[\<mapsto>]ys) = tab(p\<mapsto>q)(ps @ xs[\<mapsto>](qs' @ ys))"
schirmer@13688
  1259
    by (rule Cons.hyps)
schirmer@13688
  1260
  with qs 
schirmer@13688
  1261
  show ?case by simp
schirmer@13688
  1262
qed
schirmer@13688
  1263
schirmer@13688
  1264
lemma map_upd_cut_irrelevant:
schirmer@13688
  1265
"\<lbrakk>(tab(x\<mapsto>y)) vn = Some el; (tab'(x\<mapsto>y)) vn = None\<rbrakk>
schirmer@13688
  1266
    \<Longrightarrow> tab vn = Some el"
schirmer@13688
  1267
by (cases "tab' vn = None") (simp add: fun_upd_def)+
schirmer@13688
  1268
schirmer@13688
  1269
lemma map_upd_Some_expand:
schirmer@13688
  1270
"\<lbrakk>tab vn = Some z\<rbrakk>
schirmer@13688
  1271
    \<Longrightarrow> \<exists> z. (tab(x\<mapsto>y)) vn = Some z"
schirmer@13688
  1272
by (simp add: fun_upd_def)
schirmer@13688
  1273
schirmer@13688
  1274
lemma map_upds_Some_expand:
schirmer@13688
  1275
"\<And> tab ys z. \<lbrakk>tab vn = Some z\<rbrakk>
schirmer@13688
  1276
    \<Longrightarrow> \<exists> z. (tab(xs[\<mapsto>]ys)) vn = Some z"
schirmer@13688
  1277
proof (induct xs)
schirmer@13688
  1278
  case Nil thus ?case by simp
schirmer@13688
  1279
next
schirmer@13688
  1280
  case (Cons x xs tab ys z)
wenzelm@23350
  1281
  note z = `tab vn = Some z`
schirmer@14030
  1282
  show ?case
schirmer@14030
  1283
  proof (cases ys)
schirmer@14030
  1284
    case Nil
schirmer@14030
  1285
    with z show ?thesis by simp
schirmer@14030
  1286
  next
schirmer@14030
  1287
    case (Cons y ys')
wenzelm@23350
  1288
    note ys = `ys = y#ys'`
schirmer@14030
  1289
    from z obtain z' where "(tab(x\<mapsto>y)) vn = Some z'"
schirmer@14030
  1290
      by (rule map_upd_Some_expand [of tab,elim_format]) blast
schirmer@14030
  1291
    hence "\<exists>z. ((tab(x\<mapsto>y))(xs[\<mapsto>]ys')) vn = Some z"
schirmer@14030
  1292
      by (rule Cons.hyps)
schirmer@14030
  1293
    with ys show ?thesis
schirmer@14030
  1294
      by simp
schirmer@14030
  1295
  qed
schirmer@13688
  1296
qed
schirmer@13688
  1297
schirmer@13688
  1298
schirmer@13688
  1299
lemma map_upd_Some_swap:
schirmer@13688
  1300
 "(tab(r\<mapsto>w)(u\<mapsto>v)) vn = Some z \<Longrightarrow> \<exists> z. (tab(u\<mapsto>v)(r\<mapsto>w)) vn = Some z"
schirmer@13688
  1301
by (simp add: fun_upd_def)
schirmer@13688
  1302
schirmer@13688
  1303
lemma map_upd_None_swap:
schirmer@13688
  1304
 "(tab(r\<mapsto>w)(u\<mapsto>v)) vn = None \<Longrightarrow> (tab(u\<mapsto>v)(r\<mapsto>w)) vn = None"
schirmer@13688
  1305
by (simp add: fun_upd_def)
schirmer@13688
  1306
schirmer@13688
  1307
schirmer@13688
  1308
lemma map_eq_upd_eq: "tab vn = tab' vn \<Longrightarrow> (tab(x\<mapsto>y)) vn = (tab'(x\<mapsto>y)) vn"
schirmer@13688
  1309
by (simp add: fun_upd_def)
schirmer@13688
  1310
schirmer@13688
  1311
lemma map_upd_in_expansion_map_swap:
schirmer@13688
  1312
 "\<lbrakk>(tab(x\<mapsto>y)) vn = Some z;tab vn \<noteq> Some z\<rbrakk> 
schirmer@13688
  1313
                 \<Longrightarrow>  (tab'(x\<mapsto>y)) vn = Some z"
schirmer@13688
  1314
by (simp add: fun_upd_def)
schirmer@13688
  1315
schirmer@13688
  1316
lemma map_upds_in_expansion_map_swap:
schirmer@13688
  1317
 "\<And>tab tab' ys z. \<lbrakk>(tab(xs[\<mapsto>]ys)) vn = Some z;tab vn \<noteq> Some z\<rbrakk> 
schirmer@13688
  1318
                 \<Longrightarrow>  (tab'(xs[\<mapsto>]ys)) vn = Some z"
schirmer@13688
  1319
proof (induct xs)
schirmer@13688
  1320
  case Nil thus ?case by simp
schirmer@13688
  1321
next
schirmer@13688
  1322
  case (Cons x xs tab tab' ys z)
wenzelm@23350
  1323
  note some = `(tab(x # xs[\<mapsto>]ys)) vn = Some z`
wenzelm@23350
  1324
  note tab_not_z = `tab vn \<noteq> Some z`
schirmer@13688
  1325
  show ?case
wenzelm@23350
  1326
  proof (cases ys)
schirmer@14030
  1327
    case Nil with some tab_not_z show ?thesis by simp
schirmer@13688
  1328
  next
schirmer@14030
  1329
    case (Cons y tl)
wenzelm@23350
  1330
    note ys = `ys = y#tl`
schirmer@14030
  1331
    show ?thesis
schirmer@14030
  1332
    proof (cases "(tab(x\<mapsto>y)) vn \<noteq> Some z")
schirmer@14030
  1333
      case True
schirmer@14030
  1334
      with some ys have "(tab'(x\<mapsto>y)(xs[\<mapsto>]tl)) vn = Some z"
nipkow@44890
  1335
        by (fastforce intro: Cons.hyps)
schirmer@14030
  1336
      with ys show ?thesis 
wenzelm@32960
  1337
        by simp
schirmer@14030
  1338
    next
schirmer@14030
  1339
      case False
schirmer@14030
  1340
      hence tabx_z: "(tab(x\<mapsto>y)) vn = Some z" by blast
schirmer@14030
  1341
      moreover
schirmer@14030
  1342
      from tabx_z tab_not_z
schirmer@14030
  1343
      have "(tab'(x\<mapsto>y)) vn = Some z" 
wenzelm@32960
  1344
        by (rule map_upd_in_expansion_map_swap)
schirmer@14030
  1345
      ultimately
schirmer@14030
  1346
      have "(tab(x\<mapsto>y)) vn =(tab'(x\<mapsto>y)) vn"
wenzelm@32960
  1347
        by simp
schirmer@14030
  1348
      hence "(tab(x\<mapsto>y)(xs[\<mapsto>]tl)) vn = (tab'(x\<mapsto>y)(xs[\<mapsto>]tl)) vn"
wenzelm@32960
  1349
        by (rule map_upds_cong_ext)
schirmer@14030
  1350
      with some ys
schirmer@14030
  1351
      show ?thesis 
wenzelm@32960
  1352
        by simp
schirmer@14030
  1353
    qed
schirmer@13688
  1354
  qed
schirmer@13688
  1355
qed
schirmer@13688
  1356
   
schirmer@13688
  1357
lemma map_upds_Some_swap: 
schirmer@13688
  1358
 assumes r_u: "(tab(r\<mapsto>w)(u\<mapsto>v)(xs[\<mapsto>]ys)) vn = Some z"
schirmer@13688
  1359
    shows "\<exists> z. (tab(u\<mapsto>v)(r\<mapsto>w)(xs[\<mapsto>]ys)) vn = Some z"
schirmer@13688
  1360
proof (cases "(tab(r\<mapsto>w)(u\<mapsto>v)) vn = Some z")
schirmer@13688
  1361
  case True
schirmer@13688
  1362
  then obtain z' where "(tab(u\<mapsto>v)(r\<mapsto>w)) vn = Some z'"
schirmer@13688
  1363
    by (rule map_upd_Some_swap [elim_format]) blast
schirmer@13688
  1364
  thus "\<exists> z. (tab(u\<mapsto>v)(r\<mapsto>w)(xs[\<mapsto>]ys)) vn = Some z"
schirmer@13688
  1365
    by (rule map_upds_Some_expand)
schirmer@13688
  1366
next
schirmer@13688
  1367
  case False
schirmer@13688
  1368
  with r_u
schirmer@13688
  1369
  have "(tab(u\<mapsto>v)(r\<mapsto>w)(xs[\<mapsto>]ys)) vn = Some z"
schirmer@13688
  1370
    by (rule map_upds_in_expansion_map_swap)
schirmer@13688
  1371
  thus ?thesis
schirmer@13688
  1372
    by simp
schirmer@13688
  1373
qed
schirmer@13688
  1374
 
schirmer@13688
  1375
lemma map_upds_Some_insert:
schirmer@13688
  1376
  assumes z: "(tab(xs[\<mapsto>]ys)) vn = Some z"
schirmer@13688
  1377
    shows "\<exists> z. (tab(u\<mapsto>v)(xs[\<mapsto>]ys)) vn = Some z"
schirmer@13688
  1378
proof (cases "\<exists> z. tab vn = Some z")
schirmer@13688
  1379
  case True
schirmer@13688
  1380
  then obtain z' where "tab vn = Some z'" by blast
schirmer@13688
  1381
  then obtain z'' where "(tab(u\<mapsto>v)) vn = Some z''"
schirmer@13688
  1382
    by (rule map_upd_Some_expand [elim_format]) blast
schirmer@13688
  1383
  thus ?thesis
schirmer@13688
  1384
    by (rule map_upds_Some_expand)
schirmer@13688
  1385
next
schirmer@13688
  1386
  case False
schirmer@13688
  1387
  hence "tab vn \<noteq> Some z" by simp
schirmer@13688
  1388
  with z
schirmer@13688
  1389
  have "(tab(u\<mapsto>v)(xs[\<mapsto>]ys)) vn = Some z"
schirmer@13688
  1390
    by (rule map_upds_in_expansion_map_swap)
schirmer@13688
  1391
  thus ?thesis ..
schirmer@13688
  1392
qed
schirmer@13688
  1393
   
schirmer@13688
  1394
lemma map_upds_None_cut:
schirmer@13688
  1395
assumes expand_None: "(tab(xs[\<mapsto>]ys)) vn = None"
schirmer@13688
  1396
  shows "tab vn = None"
schirmer@13688
  1397
proof (cases "tab vn = None")
schirmer@13688
  1398
  case True thus ?thesis by simp
schirmer@13688
  1399
next
schirmer@13688
  1400
  case False then obtain z where "tab vn = Some z" by blast
schirmer@13688
  1401
  then obtain z' where "(tab(xs[\<mapsto>]ys)) vn = Some z'"
schirmer@13688
  1402
    by (rule map_upds_Some_expand [where  ?tab="tab",elim_format]) blast
schirmer@13688
  1403
  with expand_None show ?thesis
schirmer@13688
  1404
    by simp
schirmer@13688
  1405
qed
schirmer@13688
  1406
    
schirmer@13688
  1407
schirmer@13688
  1408
lemma map_upds_cut_irrelevant:
schirmer@13688
  1409
"\<And> tab tab' ys. \<lbrakk>(tab(xs[\<mapsto>]ys)) vn = Some el; (tab'(xs[\<mapsto>]ys)) vn = None\<rbrakk>
schirmer@13688
  1410
                  \<Longrightarrow> tab vn = Some el"
schirmer@13688
  1411
proof  (induct "xs")
schirmer@13688
  1412
  case Nil thus ?case by simp
schirmer@13688
  1413
next
schirmer@13688
  1414
  case (Cons x xs tab tab' ys)
wenzelm@23350
  1415
  note tab_vn = `(tab(x # xs[\<mapsto>]ys)) vn = Some el`
wenzelm@23350
  1416
  note tab'_vn = `(tab'(x # xs[\<mapsto>]ys)) vn = None`
schirmer@14030
  1417
  show ?case
schirmer@14030
  1418
  proof (cases ys)
schirmer@14030
  1419
    case Nil
schirmer@14030
  1420
    with tab_vn show ?thesis by simp
schirmer@14030
  1421
  next
schirmer@14030
  1422
    case (Cons y tl)
wenzelm@23350
  1423
    note ys = `ys=y#tl`
schirmer@14030
  1424
    with tab_vn tab'_vn 
schirmer@14030
  1425
    have "(tab(x\<mapsto>y)) vn = Some el"
schirmer@14030
  1426
      by - (rule Cons.hyps,auto)
schirmer@14030
  1427
    moreover from tab'_vn ys
schirmer@14030
  1428
    have "(tab'(x\<mapsto>y)(xs[\<mapsto>]tl)) vn = None" 
schirmer@14030
  1429
      by simp
schirmer@14030
  1430
    hence "(tab'(x\<mapsto>y)) vn = None"
schirmer@14030
  1431
      by (rule map_upds_None_cut)
schirmer@14030
  1432
    ultimately show "tab vn = Some el" 
schirmer@14030
  1433
      by (rule map_upd_cut_irrelevant)
schirmer@14030
  1434
  qed
schirmer@13688
  1435
qed
schirmer@14030
  1436
schirmer@13688
  1437
   
schirmer@13688
  1438
lemma dom_vname_split:
schirmer@13688
  1439
 "dom (lname_case (ename_case (tab(x\<mapsto>y)(xs[\<mapsto>]ys)) a) b)
schirmer@13688
  1440
   = dom (lname_case (ename_case (tab(x\<mapsto>y)) a) b) \<union> 
schirmer@13688
  1441
     dom (lname_case (ename_case (tab(xs[\<mapsto>]ys)) a) b)"
schirmer@13688
  1442
  (is "?List x xs y ys = ?Hd x y \<union> ?Tl xs ys")
schirmer@13688
  1443
proof 
schirmer@13688
  1444
  show "?List x xs y ys \<subseteq> ?Hd x y \<union> ?Tl xs ys"
schirmer@13688
  1445
  proof 
schirmer@13688
  1446
    fix el 
schirmer@13688
  1447
    assume el_in_list: "el \<in> ?List x xs y ys"
schirmer@13688
  1448
    show "el \<in>  ?Hd x y \<union> ?Tl xs ys"
schirmer@13688
  1449
    proof (cases el)
schirmer@13688
  1450
      case This
schirmer@13688
  1451
      with el_in_list show ?thesis by (simp add: dom_def)
schirmer@13688
  1452
    next
schirmer@13688
  1453
      case (EName en)
schirmer@13688
  1454
      show ?thesis
schirmer@13688
  1455
      proof (cases en)
wenzelm@32960
  1456
        case Res
wenzelm@32960
  1457
        with EName el_in_list show ?thesis by (simp add: dom_def)
schirmer@13688
  1458
      next
wenzelm@32960
  1459
        case (VNam vn)
wenzelm@32960
  1460
        with EName el_in_list show ?thesis 
wenzelm@32960
  1461
          by (auto simp add: dom_def dest: map_upds_cut_irrelevant)
schirmer@13688
  1462
      qed
schirmer@13688
  1463
    qed
schirmer@13688
  1464
  qed
schirmer@13688
  1465
next
schirmer@13688
  1466
  show "?Hd x y \<union> ?Tl xs ys  \<subseteq> ?List x xs y ys" 
paulson@15102
  1467
  proof (rule subsetI)
schirmer@13688
  1468
    fix el 
schirmer@13688
  1469
    assume  el_in_hd_tl: "el \<in>  ?Hd x y \<union> ?Tl xs ys"
schirmer@13688
  1470
    show "el \<in> ?List x xs y ys"
schirmer@13688
  1471
    proof (cases el)
schirmer@13688
  1472
      case This
schirmer@13688
  1473
      with el_in_hd_tl show ?thesis by (simp add: dom_def)
schirmer@13688
  1474
    next
schirmer@13688
  1475
      case (EName en)
schirmer@13688
  1476
      show ?thesis
schirmer@13688
  1477
      proof (cases en)
wenzelm@32960
  1478
        case Res
wenzelm@32960
  1479
        with EName el_in_hd_tl show ?thesis by (simp add: dom_def)
schirmer@13688
  1480
      next
wenzelm@32960
  1481
        case (VNam vn)
wenzelm@32960
  1482
        with EName el_in_hd_tl show ?thesis 
wenzelm@32960
  1483
          by (auto simp add: dom_def intro: map_upds_Some_expand 
schirmer@13688
  1484
                                            map_upds_Some_insert)
schirmer@13688
  1485
      qed
schirmer@13688
  1486
    qed
schirmer@13688
  1487
  qed
schirmer@13688
  1488
qed
schirmer@13688
  1489
schirmer@13688
  1490
lemma dom_map_upd: "\<And> tab. dom (tab(x\<mapsto>y)) = dom tab \<union> {x}"
schirmer@13688
  1491
by (auto simp add: dom_def fun_upd_def)
schirmer@13688
  1492
schirmer@14030
  1493
lemma dom_map_upds: "\<And> tab ys. length xs = length ys 
schirmer@14030
  1494
  \<Longrightarrow> dom (tab(xs[\<mapsto>]ys)) = dom tab \<union> set xs"
schirmer@13688
  1495
proof (induct xs)
schirmer@13688
  1496
  case Nil thus ?case by (simp add: dom_def)
schirmer@13688
  1497
next
schirmer@13688
  1498
  case (Cons x xs tab ys)
schirmer@14030
  1499
  note Hyp = Cons.hyps
wenzelm@23350
  1500
  note len = `length (x#xs)=length ys`
schirmer@13688
  1501
  show ?case
schirmer@14030
  1502
  proof (cases ys)
schirmer@14030
  1503
    case Nil with len show ?thesis by simp
schirmer@14030
  1504
  next
schirmer@14030
  1505
    case (Cons y tl)
schirmer@14030
  1506
    with len have "dom (tab(x\<mapsto>y)(xs[\<mapsto>]tl)) = dom (tab(x\<mapsto>y)) \<union> set xs"
schirmer@14030
  1507
      by - (rule Hyp,simp)
schirmer@14030
  1508
    moreover 
schirmer@14030
  1509
    have "dom (tab(x\<mapsto>hd ys)) = dom tab \<union> {x}"
schirmer@14030
  1510
      by (rule dom_map_upd)
schirmer@14030
  1511
    ultimately
schirmer@14030
  1512
    show ?thesis using Cons
schirmer@14030
  1513
      by simp
schirmer@14030
  1514
  qed
schirmer@13688
  1515
qed
schirmer@13688
  1516
 
schirmer@13688
  1517
lemma dom_ename_case_None_simp:
schirmer@13688
  1518
 "dom (ename_case vname_tab None) = VNam ` (dom vname_tab)"
schirmer@13688
  1519
  apply (auto simp add: dom_def image_def )
schirmer@13688
  1520
  apply (case_tac "x")
schirmer@13688
  1521
  apply auto
schirmer@13688
  1522
  done
schirmer@13688
  1523
schirmer@13688
  1524
lemma dom_ename_case_Some_simp:
schirmer@13688
  1525
 "dom (ename_case vname_tab (Some a)) = VNam ` (dom vname_tab) \<union> {Res}"
schirmer@13688
  1526
  apply (auto simp add: dom_def image_def )
schirmer@13688
  1527
  apply (case_tac "x")
schirmer@13688
  1528
  apply auto
schirmer@13688
  1529
  done
schirmer@13688
  1530
schirmer@13688
  1531
lemma dom_lname_case_None_simp:
schirmer@13688
  1532
  "dom (lname_case ename_tab None) = EName ` (dom ename_tab)"
schirmer@13688
  1533
  apply (auto simp add: dom_def image_def )
schirmer@13688
  1534
  apply (case_tac "x")
schirmer@13688
  1535
  apply auto
schirmer@13688
  1536
  done
schirmer@13688
  1537
schirmer@13688
  1538
lemma dom_lname_case_Some_simp:
schirmer@13688
  1539
 "dom (lname_case ename_tab (Some a)) = EName ` (dom ename_tab) \<union> {This}"
schirmer@13688
  1540
  apply (auto simp add: dom_def image_def)
schirmer@13688
  1541
  apply (case_tac "x")
schirmer@13688
  1542
  apply auto
schirmer@13688
  1543
  done
schirmer@13688
  1544
schirmer@13688
  1545
lemmas dom_lname_ename_case_simps =  
schirmer@13688
  1546
     dom_ename_case_None_simp dom_ename_case_Some_simp 
schirmer@13688
  1547
     dom_lname_case_None_simp dom_lname_case_Some_simp
schirmer@13688
  1548
schirmer@13688
  1549
lemma image_comp: 
schirmer@13688
  1550
 "f ` g ` A = (f \<circ> g) ` A"
schirmer@13688
  1551
by (auto simp add: image_def)
schirmer@13688
  1552
schirmer@14030
  1553
schirmer@13688
  1554
lemma dom_locals_init_lvars: 
schirmer@13688
  1555
  assumes m: "m=(mthd (the (methd G C sig)))"  
schirmer@14030
  1556
  assumes len: "length (pars m) = length pvs"
schirmer@13688
  1557
  shows "dom (locals (store (init_lvars G C sig (invmode m e) a pvs s)))  
schirmer@13688
  1558
           = parameters m"
schirmer@13688
  1559
proof -
schirmer@13688
  1560
  from m
schirmer@13688
  1561
  have static_m': "is_static m = static m"
schirmer@13688
  1562
    by simp
schirmer@14030
  1563
  from len
schirmer@13688
  1564
  have dom_vnames: "dom (empty(pars m[\<mapsto>]pvs))=set (pars m)"
schirmer@13688
  1565
    by (simp add: dom_map_upds)
schirmer@13688
  1566
  show ?thesis
schirmer@13688
  1567
  proof (cases "static m")
schirmer@13688
  1568
    case True
schirmer@13688
  1569
    with static_m' dom_vnames m
schirmer@13688
  1570
    show ?thesis
schirmer@13688
  1571
      by (cases s) (simp add: init_lvars_def Let_def parameters_def
schirmer@13688
  1572
                              dom_lname_ename_case_simps image_comp)
schirmer@13688
  1573
  next
schirmer@13688
  1574
    case False
schirmer@13688
  1575
    with static_m' dom_vnames m
schirmer@13688
  1576
    show ?thesis
schirmer@13688
  1577
      by (cases s) (simp add: init_lvars_def Let_def parameters_def
schirmer@13688
  1578
                              dom_lname_ename_case_simps image_comp)
schirmer@13688
  1579
  qed
schirmer@13688
  1580
qed
schirmer@13688
  1581
schirmer@14030
  1582
schirmer@13688
  1583
lemma da_e2_BinOp:
schirmer@13688
  1584
  assumes da: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>
schirmer@13688
  1585
                  \<turnstile>dom (locals (store s0)) \<guillemotright>\<langle>BinOp binop e1 e2\<rangle>\<^sub>e\<guillemotright> A"
schirmer@13688
  1586
    and wt_e1: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile>e1\<Colon>-e1T"
schirmer@13688
  1587
    and wt_e2: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile>e2\<Colon>-e2T" 
schirmer@13688
  1588
    and wt_binop: "wt_binop G binop e1T e2T" 
schirmer@13688
  1589
    and conf_s0: "s0\<Colon>\<preceq>(G,L)"  
schirmer@13688
  1590
    and normal_s1: "normal s1"
wenzelm@32960
  1591
    and eval_e1: "G\<turnstile>s0 \<midarrow>e1-\<succ>v1\<rightarrow> s1"
schirmer@13688
  1592
    and conf_v1: "G,store s1\<turnstile>v1\<Colon>\<preceq>e1T"
schirmer@13688
  1593
    and wf: "wf_prog G"
schirmer@13688
  1594
  shows "\<exists> E2. \<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile> dom (locals (store s1)) 
schirmer@13688
  1595
         \<guillemotright>(if need_second_arg binop v1 then \<langle>e2\<rangle>\<^sub>e else \<langle>Skip\<rangle>\<^sub>s)\<guillemotright> E2"
schirmer@13688
  1596
proof -
schirmer@13688
  1597
  note inj_term_simps [simp]
schirmer@13688
  1598
  from da obtain E1 where
schirmer@13688
  1599
    da_e1: "\<lparr>prg=G,cls=accC,lcl=L\<rparr> \<turnstile> dom (locals (store s0)) \<guillemotright>\<langle>e1\<rangle>\<^sub>e\<guillemotright> E1"
schirmer@13688
  1600
    by cases simp+
schirmer@13688
  1601
  obtain E2 where
schirmer@13688
  1602
    "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile> dom (locals (store s1)) 
schirmer@13688
  1603
      \<guillemotright>(if need_second_arg binop v1 then \<langle>e2\<rangle>\<^sub>e else \<langle>Skip\<rangle>\<^sub>s)\<guillemotright> E2"
schirmer@13688
  1604
  proof (cases "need_second_arg binop v1")
schirmer@13688
  1605
    case False
schirmer@13688
  1606
    obtain S where
schirmer@13688
  1607
      daSkip: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>
schirmer@13688
  1608
                  \<turnstile> dom (locals (store s1)) \<guillemotright>\<langle>Skip\<rangle>\<^sub>s\<guillemotright> S"
schirmer@13688
  1609
      by (auto intro: da_Skip [simplified] assigned.select_convs)
schirmer@13688
  1610
    thus ?thesis
schirmer@13688
  1611
      using that by (simp add: False)
schirmer@13688
  1612
  next
schirmer@13688
  1613
    case True
schirmer@13688
  1614
    from eval_e1 have 
schirmer@13688
  1615
      s0_s1:"dom (locals (store s0)) \<subseteq> dom (locals (store s1))"
schirmer@13688
  1616
      by (rule dom_locals_eval_mono_elim)
schirmer@13688
  1617
    {
schirmer@13688
  1618
      assume condAnd: "binop=CondAnd"
schirmer@13688
  1619
      have ?thesis
schirmer@13688
  1620
      proof -
wenzelm@32960
  1621
        from da obtain E2' where
wenzelm@32960
  1622
          "\<lparr>prg=G,cls=accC,lcl=L\<rparr>
schirmer@13688
  1623
             \<turnstile> dom (locals (store s0)) \<union> assigns_if True e1 \<guillemotright>\<langle>e2\<rangle>\<^sub>e\<guillemotright> E2'"
wenzelm@32960
  1624
          by cases (simp add: condAnd)+
wenzelm@32960
  1625
        moreover
wenzelm@32960
  1626
        have "dom (locals (store s0)) 
schirmer@13688
  1627
          \<union> assigns_if True e1 \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1628
        proof -
wenzelm@32960
  1629
          from condAnd wt_binop have e1T: "e1T=PrimT Boolean"
wenzelm@32960
  1630
            by simp
wenzelm@32960
  1631
          with normal_s1 conf_v1 obtain b where "v1=Bool b"
wenzelm@32960
  1632
            by (auto dest: conf_Boolean)
wenzelm@32960
  1633
          with True condAnd
wenzelm@32960
  1634
          have v1: "v1=Bool True"
wenzelm@32960
  1635
            by simp
wenzelm@32960
  1636
          from eval_e1 normal_s1 
wenzelm@32960
  1637
          have "assigns_if True e1 \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1638
            by (rule assigns_if_good_approx' [elim_format])
wenzelm@32960
  1639
               (insert wt_e1, simp_all add: e1T v1)
wenzelm@32960
  1640
          with s0_s1 show ?thesis by (rule Un_least)
wenzelm@32960
  1641
        qed
wenzelm@32960
  1642
        ultimately
wenzelm@32960
  1643
        show ?thesis
wenzelm@32960
  1644
          using that by (cases rule: da_weakenE) (simp add: True)
schirmer@13688
  1645
      qed
schirmer@13688
  1646
    }
schirmer@13688
  1647
    moreover
schirmer@13688
  1648
    { 
schirmer@13688
  1649
      assume condOr: "binop=CondOr"
schirmer@13688
  1650
      have ?thesis
wenzelm@32960
  1651
        (* Beweis durch Analogie/Example/Pattern?, True\<rightarrow>False; And\<rightarrow>Or *)
schirmer@13688
  1652
      proof -
wenzelm@32960
  1653
        from da obtain E2' where
wenzelm@32960
  1654
          "\<lparr>prg=G,cls=accC,lcl=L\<rparr>
schirmer@13688
  1655
              \<turnstile> dom (locals (store s0)) \<union> assigns_if False e1 \<guillemotright>\<langle>e2\<rangle>\<^sub>e\<guillemotright> E2'"
wenzelm@32960
  1656
          by cases (simp add: condOr)+
wenzelm@32960
  1657
        moreover
wenzelm@32960
  1658
        have "dom (locals (store s0)) 
schirmer@13688
  1659
                     \<union> assigns_if False e1 \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1660
        proof -
wenzelm@32960
  1661
          from condOr wt_binop have e1T: "e1T=PrimT Boolean"
wenzelm@32960
  1662
            by simp
wenzelm@32960
  1663
          with normal_s1 conf_v1 obtain b where "v1=Bool b"
wenzelm@32960
  1664
            by (auto dest: conf_Boolean)
wenzelm@32960
  1665
          with True condOr
wenzelm@32960
  1666
          have v1: "v1=Bool False"
wenzelm@32960
  1667
            by simp
wenzelm@32960
  1668
          from eval_e1 normal_s1 
wenzelm@32960
  1669
          have "assigns_if False e1 \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1670
            by (rule assigns_if_good_approx' [elim_format])
wenzelm@32960
  1671
               (insert wt_e1, simp_all add: e1T v1)
wenzelm@32960
  1672
          with s0_s1 show ?thesis by (rule Un_least)
wenzelm@32960
  1673
        qed
wenzelm@32960
  1674
        ultimately
wenzelm@32960
  1675
        show ?thesis
wenzelm@32960
  1676
          using that by (rule da_weakenE) (simp add: True)
schirmer@13688
  1677
      qed
schirmer@13688
  1678
    }
schirmer@13688
  1679
    moreover
schirmer@13688
  1680
    {
schirmer@13688
  1681
      assume notAndOr: "binop\<noteq>CondAnd" "binop\<noteq>CondOr"
schirmer@13688
  1682
      have ?thesis
schirmer@13688
  1683
      proof -
wenzelm@32960
  1684
        from da notAndOr obtain E1' where
schirmer@13688
  1685
          da_e1: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>
schirmer@13688
  1686
                  \<turnstile> dom (locals (store s0)) \<guillemotright>\<langle>e1\<rangle>\<^sub>e\<guillemotright> E1'"
wenzelm@32960
  1687
          and da_e2: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile> nrm E1' \<guillemotright>In1l e2\<guillemotright> A"
wenzelm@32960
  1688
          by cases simp+
wenzelm@32960
  1689
        from eval_e1 wt_e1 da_e1 wf normal_s1 
wenzelm@32960
  1690
        have "nrm E1' \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1691
          by (cases rule: da_good_approxE') iprover
wenzelm@32960
  1692
        with da_e2 show ?thesis
wenzelm@32960
  1693
          using that by (rule da_weakenE) (simp add: True)
schirmer@13688
  1694
      qed
schirmer@13688
  1695
    }
schirmer@13688
  1696
    ultimately show ?thesis
schirmer@13688
  1697
      by (cases binop) auto
schirmer@13688
  1698
  qed
schirmer@13688
  1699
  thus ?thesis ..
schirmer@13688
  1700
qed
schirmer@13688
  1701
schirmer@12854
  1702
section "main proof of type safety"
schirmer@13688
  1703
    
schirmer@12925
  1704
lemma eval_type_sound:
schirmer@13688
  1705
  assumes  eval: "G\<turnstile>s0 \<midarrow>t\<succ>\<rightarrow> (v,s1)" 
schirmer@13688
  1706
   and      wt: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile>t\<Colon>T" 
schirmer@13688
  1707
   and      da: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile>dom (locals (store s0))\<guillemotright>t\<guillemotright>A"
schirmer@13688
  1708
   and      wf: "wf_prog G" 
schirmer@13688
  1709
   and conf_s0: "s0\<Colon>\<preceq>(G,L)"           
wenzelm@12937
  1710
  shows "s1\<Colon>\<preceq>(G,L) \<and>  (normal s1 \<longrightarrow> G,L,store s1\<turnstile>t\<succ>v\<Colon>\<preceq>T) \<and> 
schirmer@12925
  1711
         (error_free s0 = error_free s1)"
schirmer@12925
  1712
proof -
schirmer@13688
  1713
  note inj_term_simps [simp]
schirmer@13688
  1714
  let ?TypeSafeObj = "\<lambda> s0 s1 t v. 
schirmer@13688
  1715
          \<forall>  L accC T A. s0\<Colon>\<preceq>(G,L) \<longrightarrow> \<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile>t\<Colon>T
schirmer@13688
  1716
                      \<longrightarrow> \<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile>dom (locals (store s0))\<guillemotright>t\<guillemotright>A  
schirmer@13688
  1717
                      \<longrightarrow> s1\<Colon>\<preceq>(G,L) \<and> (normal s1 \<longrightarrow> G,L,store s1\<turnstile>t\<succ>v\<Colon>\<preceq>T)
schirmer@13688
  1718
                          \<and> (error_free s0 = error_free s1)"
schirmer@12925
  1719
  from eval 
schirmer@13688
  1720
  have "\<And> L accC T A. \<lbrakk>s0\<Colon>\<preceq>(G,L);\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile>t\<Colon>T;
schirmer@13688
  1721
                      \<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile>dom (locals (store s0))\<guillemotright>t\<guillemotright>A\<rbrakk>  
schirmer@12925
  1722
        \<Longrightarrow> s1\<Colon>\<preceq>(G,L) \<and> (normal s1 \<longrightarrow> G,L,store s1\<turnstile>t\<succ>v\<Colon>\<preceq>T)
schirmer@12925
  1723
            \<and> (error_free s0 = error_free s1)"
schirmer@12925
  1724
   (is "PROP ?TypeSafe s0 s1 t v"
schirmer@13688
  1725
    is "\<And> L accC T A. ?Conform L s0 \<Longrightarrow> ?WellTyped L accC T t  
schirmer@13688
  1726
                 \<Longrightarrow> ?DefAss L accC s0 t A 
schirmer@12925
  1727
                 \<Longrightarrow> ?Conform L s1 \<and> ?ValueTyped L T s1 t v \<and>
schirmer@12925
  1728
                     ?ErrorFree s0 s1")
schirmer@12925
  1729
  proof (induct)
berghofe@21765
  1730
    case (Abrupt xc s t L accC T A) 
wenzelm@23350
  1731
    from `(Some xc, s)\<Colon>\<preceq>(G,L)`
wenzelm@23350
  1732
    show "(Some xc, s)\<Colon>\<preceq>(G,L) \<and> 
schirmer@12925
  1733
      (normal (Some xc, s) 
haftmann@28524
  1734
      \<longrightarrow> G,L,store (Some xc,s)\<turnstile>t\<succ>undefined3 t\<Colon>\<preceq>T) \<and> 
schirmer@12925
  1735
      (error_free (Some xc, s) = error_free (Some xc, s))"
wenzelm@23350
  1736
      by simp
schirmer@12925
  1737
  next
schirmer@13688
  1738
    case (Skip s L accC T A)
wenzelm@23350
  1739
    from `Norm s\<Colon>\<preceq>(G, L)` and
wenzelm@23350
  1740
      `\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>In1r Skip\<Colon>T`
wenzelm@23350
  1741
    show "Norm s\<Colon>\<preceq>(G, L) \<and>
schirmer@12925
  1742
              (normal (Norm s) \<longrightarrow> G,L,store (Norm s)\<turnstile>In1r Skip\<succ>\<diamondsuit>\<Colon>\<preceq>T) \<and> 
schirmer@12925
  1743
              (error_free (Norm s) = error_free (Norm s))"
wenzelm@23350
  1744
      by simp
schirmer@12925
  1745
  next
berghofe@21765
  1746
    case (Expr s0 e v s1 L accC T A)
wenzelm@23350
  1747
    note `G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1`
wenzelm@23350
  1748
    note hyp = `PROP ?TypeSafe (Norm s0) s1 (In1l e) (In1 v)`
wenzelm@23350
  1749
    note conf_s0 = `Norm s0\<Colon>\<preceq>(G, L)`
schirmer@13688
  1750
    moreover
wenzelm@23350
  1751
    note wt = `\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>In1r (Expr e)\<Colon>T`
schirmer@12925
  1752
    then obtain eT 
schirmer@12925
  1753
      where "\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>In1l e\<Colon>eT"
wenzelm@23350
  1754
      by (rule wt_elim_cases) blast
schirmer@13688
  1755
    moreover
schirmer@13688
  1756
    from Expr.prems obtain E where
schirmer@13688
  1757
      "\<lparr>prg=G,cls=accC, lcl=L\<rparr>\<turnstile>dom (locals (store ((Norm s0)::state)))\<guillemotright>In1l e\<guillemotright>E"
schirmer@13688
  1758
      by (elim da_elim_cases) simp
schirmer@13688
  1759
    ultimately 
schirmer@12925
  1760
    obtain "s1\<Colon>\<preceq>(G, L)" and "error_free s1"
schirmer@13688
  1761
      by (rule hyp [elim_format]) simp
schirmer@12925
  1762
    with wt
schirmer@12925
  1763
    show "s1\<Colon>\<preceq>(G, L) \<and>
schirmer@12925
  1764
          (normal s1 \<longrightarrow> G,L,store s1\<turnstile>In1r (Expr e)\<succ>\<diamondsuit>\<Colon>\<preceq>T) \<and> 
schirmer@12925
  1765
          (error_free (Norm s0) = error_free s1)"
schirmer@12925
  1766
      by (simp)
schirmer@12925
  1767
  next
berghofe@21765
  1768
    case (Lab s0 c s1 l L accC T A)
wenzelm@23350
  1769
    note hyp = `PROP ?TypeSafe (Norm s0) s1 (In1r c) \<diamondsuit>`
wenzelm@23350
  1770
    note conf_s0 = `Norm s0\<Colon>\<preceq>(G, L)`
schirmer@13688
  1771
    moreover
wenzelm@23350
  1772
    note wt = `\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>In1r (l\<bullet> c)\<Colon>T`
schirmer@12925
  1773
    then have "\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>c\<Colon>\<surd>"
wenzelm@23350
  1774
      by (rule wt_elim_cases) blast
schirmer@13688
  1775
    moreover from Lab.prems obtain C where
schirmer@13688
  1776
     "\<lparr>prg=G,cls=accC, lcl=L\<rparr>\<turnstile>dom (locals (store ((Norm s0)::state)))\<guillemotright>In1r c\<guillemotright>C"
schirmer@13688
  1777
      by (elim da_elim_cases) simp
schirmer@13688
  1778
    ultimately
schirmer@12925
  1779
    obtain       conf_s1: "s1\<Colon>\<preceq>(G, L)" and 
schirmer@12925
  1780
           error_free_s1: "error_free s1" 
schirmer@13688
  1781
      by (rule hyp [elim_format]) simp
schirmer@13337
  1782
    from conf_s1 have "abupd (absorb l) s1\<Colon>\<preceq>(G, L)"
schirmer@12925
  1783
      by (cases s1) (auto intro: conforms_absorb)
schirmer@12925
  1784
    with wt error_free_s1
schirmer@13337
  1785
    show "abupd (absorb l) s1\<Colon>\<preceq>(G, L) \<and>
schirmer@13337
  1786
          (normal (abupd (absorb l) s1)
schirmer@13337
  1787
           \<longrightarrow> G,L,store (abupd (absorb l) s1)\<turnstile>In1r (l\<bullet> c)\<succ>\<diamondsuit>\<Colon>\<preceq>T) \<and>
schirmer@13337
  1788
          (error_free (Norm s0) = error_free (abupd (absorb l) s1))"
schirmer@12925
  1789
      by (simp)
schirmer@12925
  1790
  next
berghofe@21765
  1791
    case (Comp s0 c1 s1 c2 s2 L accC T A)
wenzelm@23350
  1792
    note eval_c1 = `G\<turnstile>Norm s0 \<midarrow>c1\<rightarrow> s1`
wenzelm@23350
  1793
    note eval_c2 = `G\<turnstile>s1 \<midarrow>c2\<rightarrow> s2`
wenzelm@23350
  1794
    note hyp_c1 = `PROP ?TypeSafe (Norm s0) s1 (In1r c1) \<diamondsuit>`
wenzelm@23350
  1795
    note hyp_c2 = `PROP ?TypeSafe s1        s2 (In1r c2) \<diamondsuit>`
wenzelm@23350
  1796
    note conf_s0 = `Norm s0\<Colon>\<preceq>(G, L)`
wenzelm@23350
  1797
    note wt = `\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>In1r (c1;; c2)\<Colon>T`
schirmer@12925
  1798
    then obtain wt_c1: "\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>c1\<Colon>\<surd>" and
schirmer@12925
  1799
                wt_c2: "\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>c2\<Colon>\<surd>"
wenzelm@23350
  1800
      by (rule wt_elim_cases) blast
schirmer@13688
  1801
    from Comp.prems
schirmer@13688
  1802
    obtain C1 C2
schirmer@13688
  1803
      where da_c1: "\<lparr>prg=G, cls=accC, lcl=L\<rparr>\<turnstile> 
schirmer@13688
  1804
                      dom (locals (store ((Norm s0)::state))) \<guillemotright>In1r c1\<guillemotright> C1" and 
schirmer@13688
  1805
            da_c2: "\<lparr>prg=G, cls=accC, lcl=L\<rparr>\<turnstile>  nrm C1 \<guillemotright>In1r c2\<guillemotright> C2" 
schirmer@13688
  1806
      by (elim da_elim_cases) simp
schirmer@13688
  1807
    from conf_s0 wt_c1 da_c1
schirmer@13688
  1808
    obtain conf_s1: "s1\<Colon>\<preceq>(G, L)" and 
schirmer@13688
  1809
           error_free_s1: "error_free s1"
schirmer@13688
  1810
      by (rule hyp_c1 [elim_format]) simp
schirmer@12925
  1811
    show "s2\<Colon>\<preceq>(G, L) \<and>
schirmer@12925
  1812
          (normal s2 \<longrightarrow> G,L,store s2\<turnstile>In1r (c1;; c2)\<succ>\<diamondsuit>\<Colon>\<preceq>T) \<and>
schirmer@12925
  1813
          (error_free (Norm s0) = error_free s2)"
schirmer@13688
  1814
    proof (cases "normal s1")
schirmer@13688
  1815
      case False
schirmer@13688
  1816
      with eval_c2 have "s2=s1" by auto
schirmer@13688
  1817
      with conf_s1 error_free_s1 False wt show ?thesis
wenzelm@32960
  1818
        by simp
schirmer@13688
  1819
    next
schirmer@13688
  1820
      case True
schirmer@13688
  1821
      obtain C2' where 
wenzelm@32960
  1822
        "\<lparr>prg=G, cls=accC, lcl=L\<rparr>\<turnstile> dom (locals (store s1)) \<guillemotright>In1r c2\<guillemotright> C2'"
schirmer@13688
  1823
      proof -
wenzelm@32960
  1824
        from eval_c1 wt_c1 da_c1 wf True
wenzelm@32960
  1825
        have "nrm C1 \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1826
          by (cases rule: da_good_approxE') iprover
wenzelm@32960
  1827
        with da_c2 show thesis
wenzelm@32960
  1828
          by (rule da_weakenE) (rule that)
schirmer@13688
  1829
      qed
schirmer@13688
  1830
      with conf_s1 wt_c2 
schirmer@13688
  1831
      obtain "s2\<Colon>\<preceq>(G, L)" and "error_free s2"
wenzelm@32960
  1832
        by (rule hyp_c2 [elim_format]) (simp add: error_free_s1)
schirmer@13688
  1833
      thus ?thesis
wenzelm@32960
  1834
        using wt by simp
schirmer@13688
  1835
    qed
schirmer@12925
  1836
  next
berghofe@21765
  1837
    case (If s0 e b s1 c1 c2 s2 L accC T A)
wenzelm@23350
  1838
    note eval_e = `G\<turnstile>Norm s0 \<midarrow>e-\<succ>b\<rightarrow> s1`
wenzelm@23350
  1839
    note eval_then_else = `G\<turnstile>s1 \<midarrow>(if the_Bool b then c1 else c2)\<rightarrow> s2`
wenzelm@23350
  1840
    note hyp_e = `PROP ?TypeSafe (Norm s0) s1 (In1l e) (In1 b)`
wenzelm@23350
  1841
    note hyp_then_else =
wenzelm@23350
  1842
      `PROP ?TypeSafe s1 s2 (In1r (if the_Bool b then c1 else c2)) \<diamondsuit>`
wenzelm@23350
  1843
    note conf_s0 = `Norm s0\<Colon>\<preceq>(G, L)`
wenzelm@23350
  1844
    note wt = `\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>In1r (If(e) c1 Else c2)\<Colon>T`
schirmer@13688
  1845
    then obtain 
schirmer@13688
  1846
              wt_e: "\<lparr>prg=G, cls=accC, lcl=L\<rparr>\<turnstile>e\<Colon>-PrimT Boolean" and
schirmer@13688
  1847
      wt_then_else: "\<lparr>prg=G, cls=accC, lcl=L\<rparr>\<turnstile>(if the_Bool b then c1 else c2)\<Colon>\<surd>"
schirmer@13688
  1848
      (*
schirmer@13688
  1849
                wt_c1: "\<lparr>prg=G, cls=accC, lcl=L\<rparr>\<turnstile>c1\<Colon>\<surd>" and
schirmer@13688
  1850
                wt_c2: "\<lparr>prg=G, cls=accC, lcl=L\<rparr>\<turnstile>c2\<Colon>\<surd>"*)
wenzelm@46714
  1851
      by (rule wt_elim_cases) auto
schirmer@13688
  1852
    from If.prems obtain E C where
schirmer@13688
  1853
      da_e: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile> dom (locals (store ((Norm s0)::state))) 
schirmer@13688
  1854
                                       \<guillemotright>In1l e\<guillemotright> E" and
schirmer@13688
  1855
      da_then_else: 
schirmer@13688
  1856
      "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile> 
schirmer@13688
  1857
         (dom (locals (store ((Norm s0)::state))) \<union> assigns_if (the_Bool b) e)
schirmer@13688
  1858
          \<guillemotright>In1r (if the_Bool b then c1 else c2)\<guillemotright> C"
schirmer@13688
  1859
     (*
schirmer@13688
  1860
     da_c1: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile> (dom (locals (store ((Norm s0)::state))) 
schirmer@13688
  1861
                                      \<union> assigns_if True e) \<guillemotright>In1r c1\<guillemotright> C1" and
schirmer@13688
  1862
     da_c2: "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile> (dom (locals (store ((Norm s0)::state))) 
schirmer@13688
  1863
                                       \<union> assigns_if False e) \<guillemotright>In1r c2\<guillemotright> C2" *)
schirmer@13688
  1864
      by (elim da_elim_cases) (cases "the_Bool b",auto)
schirmer@13688
  1865
    from conf_s0 wt_e da_e  
schirmer@13688
  1866
    obtain conf_s1: "s1\<Colon>\<preceq>(G, L)" and error_free_s1: "error_free s1"
schirmer@13688
  1867
      by (rule hyp_e [elim_format]) simp
schirmer@12925
  1868
    show "s2\<Colon>\<preceq>(G, L) \<and>
schirmer@12925
  1869
           (normal s2 \<longrightarrow> G,L,store s2\<turnstile>In1r (If(e) c1 Else c2)\<succ>\<diamondsuit>\<Colon>\<preceq>T) \<and>
schirmer@12925
  1870
           (error_free (Norm s0) = error_free s2)"
schirmer@13688
  1871
    proof (cases "normal s1")
schirmer@13688
  1872
      case False
schirmer@13688
  1873
      with eval_then_else have "s2=s1" by auto
schirmer@13688
  1874
      with conf_s1 error_free_s1 False wt show ?thesis
wenzelm@32960
  1875
        by simp
schirmer@13688
  1876
    next
schirmer@13688
  1877
      case True
schirmer@13688
  1878
      obtain C' where
wenzelm@32960
  1879
        "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile> 
schirmer@13688
  1880
          (dom (locals (store s1)))\<guillemotright>In1r (if the_Bool b then c1 else c2)\<guillemotright> C'"
schirmer@13688
  1881
      proof -
wenzelm@32960
  1882
        from eval_e have 
wenzelm@32960
  1883
          "dom (locals (store ((Norm s0)::state))) \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1884
          by (rule dom_locals_eval_mono_elim)
schirmer@13688
  1885
        moreover
wenzelm@32960
  1886
        from eval_e True wt_e 
wenzelm@32960
  1887
        have "assigns_if (the_Bool b) e \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1888
          by (rule assigns_if_good_approx')
wenzelm@32960
  1889
        ultimately 
wenzelm@32960
  1890
        have "dom (locals (store ((Norm s0)::state))) 
schirmer@13688
  1891
                \<union> assigns_if (the_Bool b) e \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1892
          by (rule Un_least)
wenzelm@32960
  1893
        with da_then_else show thesis
wenzelm@32960
  1894
          by (rule da_weakenE) (rule that)
schirmer@13688
  1895
      qed
schirmer@13688
  1896
      with conf_s1 wt_then_else  
schirmer@13688
  1897
      obtain "s2\<Colon>\<preceq>(G, L)" and "error_free s2"
wenzelm@32960
  1898
        by (rule hyp_then_else [elim_format]) (simp add: error_free_s1)
schirmer@13688
  1899
      with wt show ?thesis
wenzelm@32960
  1900
        by simp
schirmer@13688
  1901
    qed
schirmer@13688
  1902
    -- {* Note that we don't have to show that @{term b} really is a boolean 
schirmer@13688
  1903
          value. With @{term the_Bool} we enforce to get a value of boolean 
schirmer@13688
  1904
          type. So execution will be type safe, even if b would be
schirmer@13688
  1905
          a string, for example. We might not expect such a behaviour to be
schirmer@13688
  1906
          called type safe. To remedy the situation we would have to change
schirmer@13688
  1907
          the evaulation rule, so that it only has a type safe evaluation if
schirmer@13688
  1908
          we actually get a boolean value for the condition. That b is actually
schirmer@13688
  1909
          a boolean value is part of @{term hyp_e}. See also Loop 
schirmer@13688
  1910
       *}
schirmer@12925
  1911
  next
berghofe@21765
  1912
    case (Loop s0 e b s1 c s2 l s3 L accC T A)
wenzelm@23350
  1913
    note eval_e = `G\<turnstile>Norm s0 \<midarrow>e-\<succ>b\<rightarrow> s1`
wenzelm@23350
  1914
    note hyp_e = `PROP ?TypeSafe (Norm s0) s1 (In1l e) (In1 b)`
wenzelm@23350
  1915
    note conf_s0 = `Norm s0\<Colon>\<preceq>(G, L)`
wenzelm@23350
  1916
    note wt = `\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>In1r (l\<bullet> While(e) c)\<Colon>T`
schirmer@12925
  1917
    then obtain wt_e: "\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>e\<Colon>-PrimT Boolean" and
schirmer@12925
  1918
                wt_c: "\<lparr>prg = G, cls = accC, lcl = L\<rparr>\<turnstile>c\<Colon>\<surd>"
wenzelm@23350
  1919
      by (rule wt_elim_cases) blast
wenzelm@23350
  1920
    note da = `\<lparr>prg=G, cls=accC, lcl=L\<rparr>
wenzelm@23350
  1921
            \<turnstile> dom (locals(store ((Norm s0)::state))) \<guillemotright>In1r (l\<bullet> While(e) c)\<guillemotright> A`
schirmer@13688
  1922
    then
schirmer@13688
  1923
    obtain E C where
schirmer@13688
  1924
      da_e: "\<lparr>prg=G, cls=accC, lcl=L\<rparr>
schirmer@13688
  1925
              \<turnstile> dom (locals (store ((Norm s0)::state))) \<guillemotright>In1l e\<guillemotright> E" and
schirmer@13688
  1926
      da_c: "\<lparr>prg=G, cls=accC, lcl=L\<rparr>
schirmer@13688
  1927
              \<turnstile> (dom (locals (store ((Norm s0)::state))) 
schirmer@13688
  1928
                   \<union> assigns_if True e) \<guillemotright>In1r c\<guillemotright> C" 
schirmer@13688
  1929
      by (rule da_elim_cases) simp
wenzelm@23350
  1930
    from conf_s0 wt_e da_e
schirmer@12925
  1931
    obtain conf_s1: "s1\<Colon>\<preceq>(G, L)" and error_free_s1: "error_free s1"
schirmer@13688
  1932
      by (rule hyp_e [elim_format]) simp
schirmer@12925
  1933
    show "s3\<Colon>\<preceq>(G, L) \<and>
schirmer@12925
  1934
          (normal s3 \<longrightarrow> G,L,store s3\<turnstile>In1r (l\<bullet> While(e) c)\<succ>\<diamondsuit>\<Colon>\<preceq>T) \<and>
schirmer@12925
  1935
          (error_free (Norm s0) = error_free s3)"
schirmer@13688
  1936
    proof (cases "normal s1")
schirmer@12925
  1937
      case True
schirmer@13688
  1938
      note normal_s1 = this
schirmer@12925
  1939
      show ?thesis
schirmer@13688
  1940
      proof (cases "the_Bool b")
wenzelm@32960
  1941
        case True
wenzelm@32960
  1942
        with Loop.hyps  obtain
schirmer@13688
  1943
          eval_c: "G\<turnstile>s1 \<midarrow>c\<rightarrow> s2" and 
schirmer@13688
  1944
          eval_while: "G\<turnstile>abupd (absorb (Cont l)) s2 \<midarrow>l\<bullet> While(e) c\<rightarrow> s3"
wenzelm@32960
  1945
          by simp 
wenzelm@32960
  1946
        have "?TypeSafeObj s1 s2 (In1r c) \<diamondsuit>"
wenzelm@32960
  1947
          using Loop.hyps True by simp
wenzelm@32960
  1948
        note hyp_c = this [rule_format]
wenzelm@32960
  1949
        have "?TypeSafeObj (abupd (absorb (Cont l)) s2)
schirmer@13688
  1950
          s3 (In1r (l\<bullet> While(e) c)) \<diamondsuit>"
wenzelm@32960
  1951
          using Loop.hyps True by simp
wenzelm@32960
  1952
        note hyp_w = this [rule_format]
wenzelm@32960
  1953
        from eval_e have 
wenzelm@32960
  1954
          s0_s1: "dom (locals (store ((Norm s0)::state)))
schirmer@13688
  1955
                    \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1956
          by (rule dom_locals_eval_mono_elim)
wenzelm@32960
  1957
        obtain C' where
wenzelm@32960
  1958
          "\<lparr>prg=G, cls=accC, lcl=L\<rparr>\<turnstile>(dom (locals (store s1)))\<guillemotright>In1r c\<guillemotright> C'" 
wenzelm@32960
  1959
        proof -
wenzelm@32960
  1960
          note s0_s1
schirmer@13688
  1961
          moreover
wenzelm@32960
  1962
          from eval_e normal_s1 wt_e 
wenzelm@32960
  1963
          have "assigns_if True e \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1964
            by (rule assigns_if_good_approx' [elim_format]) (simp add: True)
wenzelm@32960
  1965
          ultimately 
wenzelm@32960
  1966
          have "dom (locals (store ((Norm s0)::state))) 
schirmer@13688
  1967
                 \<union> assigns_if True e \<subseteq> dom (locals (store s1))"
wenzelm@32960
  1968
            by (rule Un_least)
wenzelm@32960
  1969
          with da_c show thesis
wenzelm@32960
  1970
            by (rule da_weakenE) (rule that)
wenzelm@32960
  1971
        qed
wenzelm@32960
  1972
        with conf_s1 wt_c  
wenzelm@32960
  1973
        obtain conf_s2:  "s2\<Colon>\<preceq>(G, L)" and error_free_s2: "error_free s2"
wenzelm@32960
  1974
          by (rule hyp_c [elim_format]) (simp add: error_free_s1)
wenzelm@32960
  1975
        from error_free_s2 
wenzelm@32960
  1976
        have error_free_ab_s2: "error_free (abupd (absorb (Cont l)) s2)"
wenzelm@32960
  1977
          by simp
wenzelm@32960
  1978
        from conf_s2 have "abupd (absorb (Cont l)) s2 \<Colon>\<preceq>(G, L)"
wenzelm@32960
  1979
          by (cases s2) (auto intro: conforms_absorb)
wenzelm@32960
  1980
        moreover note wt
wenzelm@32960
  1981
        moreover
wenzelm@32960
  1982
        obtain A' where 
schirmer@13688
  1983
          "\<lparr>prg=G,cls=accC,lcl=L\<rparr>\<turnstile> 
schirmer@13688
  1984
              dom (locals(store (abupd (absorb (Cont l)) s2)))
schirmer@13688
  1985
                \<guillemotright>In1r (l\<bullet> While(e) c)\<guillemotright> A'"
wenzelm@32960
  1986
        proof -
wenzelm@32960
  1987
          note s0_s1
wenzelm@32960
  1988
          also from eval_c 
wenzelm@32960
  1989
          have "dom (locals (store s1)) \<subseteq> dom (locals (store s2))"
wenzelm@32960
  1990
            by (rule dom_locals_eval_mono_elim)
wenzelm@32960
  1991
          also have "\<dots> \<subseteq> dom (locals (store (abupd (absorb (Cont l)) s2)))"
wenzelm@32960
  1992
            by simp
wenzelm@32960
  1993
          finally
schirmer@13688
  1994
          have "dom (locals (store ((Norm s0)::state))) \<subseteq> \<dots>" .
wenzelm@32960
  1995
          with da show thesis
wenzelm@32960
  1996
            by (rule da_weakenE) (rule that)
wenzelm@32960
  1997
        qed
wenzelm@32960
  1998
        ultimately obtain "s3\<Colon>\<preceq>(G, L)" and "error_free s3"
wenzelm@32960
  1999
          by (rule hyp_w [elim_format]) (simp add: error_free_ab_s2)
wenzelm@32960
  2000
        with wt show ?thesis
wenzelm@32960
  2001
          by simp
schirmer@13688
  2002
      next
wenzelm@32960
  2003
        case False
wenzelm@32960
  2004
        with Loop.hyps have "s3=s1" by simp
wenzelm@32960
  2005
        with conf_s1 error_free_s1 wt
wenzelm@32960
  2006
        show ?thesis
wenzelm@32960
  2007
          by simp
schirmer@13688
  2008
      qed
schirmer@12925
  2009
    next
schirmer@12925
  2010
      case False
schirmer@13688
  2011
      have "s3=s1"
schirmer@13688
  2012
      proof -
wenzelm@32960
  2013
        from False obtain abr where abr: "abrupt s1 = Some abr"
wenzelm@32960
  2014
          by (cases s1) auto
wenzelm@32960
  2015
        from eval_e _ wt_e have no_jmp: "\<And> j. abrupt s1 \<noteq> Some (Jump j)"
wenzelm@32960
  2016
          by (rule eval_expression_no_jump 
schirmer@13688
  2017
               [where ?Env="\<lparr>prg=G,cls=accC,lcl=L\<rparr>",simplified]) 
schirmer@13688
  2018
             (simp_all add: wf)
wenzelm@32960
  2019
            
wenzelm@32960
  2020
        show ?thesis
wenzelm@32960
  2021
        proof (cases "the_Bool b")
wenzelm@32960
  2022
          case True  
wenzelm@32960
  2023
          with Loop.hyps obtain
schirmer@13688
  2024
            eval_c: "G\<turnstile>s1 \<midarrow>c\<rightarrow> s2" and 
schirmer@13688
  2025
            eval_while: "G\<turnstile>abupd (absorb (Cont l)) s2 \<midarrow>l\<bullet> While(e) c\<rightarrow> s3"
wenzelm@32960
  2026
            by simp
wenzelm@32960
  2027
          from eval_c abr have "s2=s1" by auto
wenzelm@32960
  2028
          moreover from calculation no_jmp have "abupd (absorb (Cont l)) s2=s2"
wenzelm@32960
  2029
            by (cases s1) (simp add: absorb_def)
wenzelm@32960
  2030
          ultimately show ?thesis
wenzelm@32960
  2031
            using eval_while abr
wenzelm@32960
  2032
            by auto
wenzelm@32960
  2033
        next
wenzelm@32960
  2034
          case False
wenzelm@32960
  2035
          with Loop.hyps show ?thesis by simp
wenzelm@32960
  2036
        qed
schirmer@13688
  2037
      qed
schirmer@12925
  2038
      with conf_s1 error_free_s1 wt
schirmer@12925
  2039
      show ?thesis
wenzelm@32960
  2040
        by simp
schirmer@12925
  2041
    qed
schirmer@12925
  2042
  next
berghofe@21765
  2043
    case (Jmp s j L accC T A)
wenzelm@23350
  2044
    note `Norm s\<Colon>\<preceq>(G, L)`
schirmer@13688
  2045
    moreover
schirmer@13688
  2046
    from Jmp.prems 
schirmer@13688
  2047
    have "j=Ret \<longrightarrow> Result \<in> dom (locals (store ((Norm s)::state)))"
schirmer@13688
  2048
      by (elim da_elim_cases)
schirmer@13688
  2049
    ultimately have "(Some (Jump j), s)\<Colon>\<preceq>(G, L)" by auto
schirmer@12925
  2050
    then 
schirmer@12925
  2051
    show "(Some (Jump j), s)\<Colon>\<preceq>(G, L) \<and>
schirmer@12925
  2052