src/HOL/Bali/TypeRel.thy
author kuncar
Fri Dec 09 18:07:04 2011 +0100 (2011-12-09)
changeset 45802 b16f976db515
parent 45605 a89b4bc311a5
child 46212 d86ef6b96097
permissions -rw-r--r--
Quotient_Info stores only relation maps
wenzelm@12857
     1
(*  Title:      HOL/Bali/TypeRel.thy
schirmer@12854
     2
    Author:     David von Oheimb
schirmer@12854
     3
*)
schirmer@12854
     4
header {* The relations between Java types *}
schirmer@12854
     5
haftmann@16417
     6
theory TypeRel imports Decl begin
schirmer@12854
     7
schirmer@12854
     8
text {*
schirmer@12854
     9
simplifications:
schirmer@12854
    10
\begin{itemize}
schirmer@12854
    11
\item subinterface, subclass and widening relation includes identity
schirmer@12854
    12
\end{itemize}
schirmer@12854
    13
improvements over Java Specification 1.0:
schirmer@12854
    14
\begin{itemize}
schirmer@12854
    15
\item narrowing reference conversion also in cases where the return types of a 
schirmer@12854
    16
      pair of methods common to both types are in widening (rather identity) 
schirmer@12854
    17
      relation
schirmer@12854
    18
\item one could add similar constraints also for other cases
schirmer@12854
    19
\end{itemize}
schirmer@12854
    20
design issues:
schirmer@12854
    21
\begin{itemize}
schirmer@12854
    22
\item the type relations do not require @{text is_type} for their arguments
schirmer@12854
    23
\item the subint1 and subcls1 relations imply @{text is_iface}/@{text is_class}
schirmer@12854
    24
      for their first arguments, which is required for their finiteness
schirmer@12854
    25
\end{itemize}
schirmer@12854
    26
*}
schirmer@12854
    27
wenzelm@14674
    28
(*subint1, in Decl.thy*)                     (* direct subinterface       *)
wenzelm@14674
    29
(*subint , by translation*)                  (* subinterface (+ identity) *)
wenzelm@14674
    30
(*subcls1, in Decl.thy*)                     (* direct subclass           *)
wenzelm@14674
    31
(*subcls , by translation*)                  (*        subclass           *)
wenzelm@14674
    32
(*subclseq, by translation*)                 (* subclass + identity       *)
wenzelm@37956
    33
wenzelm@37956
    34
definition
wenzelm@37956
    35
  implmt1 :: "prog \<Rightarrow> (qtname \<times> qtname) set" --{* direct implementation *}
wenzelm@37956
    36
  --{* direct implementation, cf. 8.1.3 *}
wenzelm@37956
    37
  where "implmt1 G = {(C,I). C\<noteq>Object \<and> (\<exists>c\<in>class G C: I\<in>set (superIfs c))}"
wenzelm@37956
    38
schirmer@12854
    39
wenzelm@35067
    40
abbreviation
wenzelm@35067
    41
  subint1_syntax :: "prog => [qtname, qtname] => bool" ("_|-_<:I1_" [71,71,71] 70)
wenzelm@35067
    42
  where "G|-I <:I1 J == (I,J) \<in> subint1 G"
schirmer@12854
    43
wenzelm@35067
    44
abbreviation
wenzelm@35067
    45
  subint_syntax :: "prog => [qtname, qtname] => bool" ("_|-_<=:I _"[71,71,71] 70)
wenzelm@35067
    46
  where "G|-I <=:I J == (I,J) \<in>(subint1 G)^*" --{* cf. 9.1.3 *}
schirmer@12854
    47
wenzelm@35067
    48
abbreviation
wenzelm@35067
    49
  implmt1_syntax :: "prog => [qtname, qtname] => bool" ("_|-_~>1_"  [71,71,71] 70)
wenzelm@35067
    50
  where "G|-C ~>1 I == (C,I) \<in> implmt1 G"
schirmer@12854
    51
wenzelm@35067
    52
notation (xsymbols)
wenzelm@35067
    53
  subint1_syntax  ("_\<turnstile>_\<prec>I1_"  [71,71,71] 70) and
wenzelm@35067
    54
  subint_syntax  ("_\<turnstile>_\<preceq>I _"  [71,71,71] 70) and
wenzelm@35067
    55
  implmt1_syntax   ("_\<turnstile>_\<leadsto>1_"  [71,71,71] 70)
schirmer@12854
    56
schirmer@12854
    57
schirmer@12854
    58
section "subclass and subinterface relations"
schirmer@12854
    59
schirmer@12854
    60
  (* direct subinterface in Decl.thy, cf. 9.1.3 *)
schirmer@12854
    61
  (* direct subclass     in Decl.thy, cf. 8.1.3 *)
schirmer@12854
    62
wenzelm@45605
    63
lemmas subcls_direct = subcls1I [THEN r_into_rtrancl]
schirmer@12854
    64
schirmer@12854
    65
lemma subcls_direct1:
schirmer@12854
    66
 "\<lbrakk>class G C = Some c; C \<noteq> Object;D=super c\<rbrakk> \<Longrightarrow> G\<turnstile>C\<preceq>\<^sub>C D"
schirmer@12854
    67
apply (auto dest: subcls_direct)
schirmer@12854
    68
done
schirmer@12854
    69
schirmer@12854
    70
lemma subcls1I1:
haftmann@35416
    71
 "\<lbrakk>class G C = Some c; C \<noteq> Object;D=super c\<rbrakk> \<Longrightarrow> G\<turnstile>C\<prec>\<^sub>C1 D"
schirmer@12854
    72
apply (auto dest: subcls1I)
schirmer@12854
    73
done
schirmer@12854
    74
schirmer@12854
    75
lemma subcls_direct2:
schirmer@12854
    76
 "\<lbrakk>class G C = Some c; C \<noteq> Object;D=super c\<rbrakk> \<Longrightarrow> G\<turnstile>C\<prec>\<^sub>C D"
schirmer@12854
    77
apply (auto dest: subcls1I1)
schirmer@12854
    78
done
schirmer@12854
    79
schirmer@12854
    80
lemma subclseq_trans: "\<lbrakk>G\<turnstile>A \<preceq>\<^sub>C B; G\<turnstile>B \<preceq>\<^sub>C C\<rbrakk> \<Longrightarrow> G\<turnstile>A \<preceq>\<^sub>C C"
schirmer@12854
    81
by (blast intro: rtrancl_trans)
schirmer@12854
    82
schirmer@12854
    83
lemma subcls_trans: "\<lbrakk>G\<turnstile>A \<prec>\<^sub>C B; G\<turnstile>B \<prec>\<^sub>C C\<rbrakk> \<Longrightarrow> G\<turnstile>A \<prec>\<^sub>C C"
schirmer@12854
    84
by (blast intro: trancl_trans)
schirmer@12854
    85
schirmer@12854
    86
lemma SXcpt_subcls_Throwable_lemma: 
schirmer@12854
    87
"\<lbrakk>class G (SXcpt xn) = Some xc;
schirmer@12854
    88
  super xc = (if xn = Throwable then Object else  SXcpt Throwable)\<rbrakk> 
schirmer@12854
    89
\<Longrightarrow> G\<turnstile>SXcpt xn\<preceq>\<^sub>C SXcpt Throwable"
schirmer@12854
    90
apply (case_tac "xn = Throwable")
schirmer@12854
    91
apply  simp_all
schirmer@12854
    92
apply (drule subcls_direct)
schirmer@12854
    93
apply (auto dest: sym)
schirmer@12854
    94
done
schirmer@12854
    95
schirmer@12854
    96
lemma subcls_ObjectI: "\<lbrakk>is_class G C; ws_prog G\<rbrakk> \<Longrightarrow> G\<turnstile>C\<preceq>\<^sub>C Object"
schirmer@12854
    97
apply (erule ws_subcls1_induct)
schirmer@12854
    98
apply clarsimp
schirmer@12854
    99
apply (case_tac "C = Object")
schirmer@12854
   100
apply  (fast intro: r_into_rtrancl [THEN rtrancl_trans])+
schirmer@12854
   101
done
schirmer@12854
   102
schirmer@12854
   103
lemma subclseq_ObjectD [dest!]: "G\<turnstile>Object\<preceq>\<^sub>C C \<Longrightarrow> C = Object"
schirmer@12854
   104
apply (erule rtrancl_induct)
schirmer@12854
   105
apply  (auto dest: subcls1D)
schirmer@12854
   106
done
schirmer@12854
   107
schirmer@12854
   108
lemma subcls_ObjectD [dest!]: "G\<turnstile>Object\<prec>\<^sub>C C \<Longrightarrow> False"
schirmer@12854
   109
apply (erule trancl_induct)
schirmer@12854
   110
apply  (auto dest: subcls1D)
schirmer@12854
   111
done
schirmer@12854
   112
schirmer@12854
   113
lemma subcls_ObjectI1 [intro!]: 
schirmer@12854
   114
 "\<lbrakk>C \<noteq> Object;is_class G C;ws_prog G\<rbrakk> \<Longrightarrow> G\<turnstile>C \<prec>\<^sub>C Object" 
schirmer@12854
   115
apply (drule (1) subcls_ObjectI)
schirmer@12854
   116
apply (auto intro: rtrancl_into_trancl3)
schirmer@12854
   117
done
schirmer@12854
   118
schirmer@12854
   119
lemma subcls_is_class: "(C,D) \<in> (subcls1 G)^+ \<Longrightarrow> is_class G C"
schirmer@12854
   120
apply (erule trancl_trans_induct)
schirmer@12854
   121
apply (auto dest!: subcls1D)
schirmer@12854
   122
done
schirmer@12854
   123
schirmer@12854
   124
lemma subcls_is_class2 [rule_format (no_asm)]: 
schirmer@12854
   125
 "G\<turnstile>C\<preceq>\<^sub>C D \<Longrightarrow> is_class G D \<longrightarrow> is_class G C"
schirmer@12854
   126
apply (erule rtrancl_induct)
schirmer@12854
   127
apply (drule_tac [2] subcls1D)
schirmer@12854
   128
apply  auto
schirmer@12854
   129
done
schirmer@12854
   130
schirmer@12854
   131
lemma single_inheritance: 
haftmann@35416
   132
"\<lbrakk>G\<turnstile>A \<prec>\<^sub>C1 B; G\<turnstile>A \<prec>\<^sub>C1 C\<rbrakk> \<Longrightarrow> B = C"
schirmer@12854
   133
by (auto simp add: subcls1_def)
schirmer@12854
   134
  
schirmer@12854
   135
lemma subcls_compareable:
schirmer@12854
   136
"\<lbrakk>G\<turnstile>A \<preceq>\<^sub>C X; G\<turnstile>A \<preceq>\<^sub>C Y 
schirmer@12854
   137
 \<rbrakk> \<Longrightarrow> G\<turnstile>X \<preceq>\<^sub>C Y \<or> G\<turnstile>Y \<preceq>\<^sub>C X"
schirmer@12854
   138
by (rule triangle_lemma)  (auto intro: single_inheritance) 
schirmer@12854
   139
haftmann@35416
   140
lemma subcls1_irrefl: "\<lbrakk>G\<turnstile>C \<prec>\<^sub>C1 D; ws_prog G \<rbrakk>
schirmer@12854
   141
 \<Longrightarrow> C \<noteq> D"
schirmer@12854
   142
proof 
schirmer@12854
   143
  assume ws: "ws_prog G" and
haftmann@35416
   144
    subcls1: "G\<turnstile>C \<prec>\<^sub>C1 D" and
schirmer@12854
   145
     eq_C_D: "C=D"
schirmer@12854
   146
  from subcls1 obtain c 
schirmer@12854
   147
    where
schirmer@12854
   148
      neq_C_Object: "C\<noteq>Object" and
schirmer@12854
   149
              clsC: "class G C = Some c" and
schirmer@12854
   150
           super_c: "super c = D"
schirmer@12854
   151
    by (auto simp add: subcls1_def)
schirmer@12854
   152
  with super_c subcls1 eq_C_D 
schirmer@12854
   153
  have subcls_super_c_C: "G\<turnstile>super c \<prec>\<^sub>C C"
schirmer@12854
   154
    by auto
schirmer@12854
   155
  from ws clsC neq_C_Object 
schirmer@12854
   156
  have "\<not> G\<turnstile>super c \<prec>\<^sub>C C"
schirmer@12854
   157
    by (auto dest: ws_prog_cdeclD)
schirmer@12854
   158
  from this subcls_super_c_C 
schirmer@12854
   159
  show "False"
schirmer@12854
   160
    by (rule notE)
schirmer@12854
   161
qed
schirmer@12854
   162
schirmer@12854
   163
lemma no_subcls_Object: "G\<turnstile>C \<prec>\<^sub>C D \<Longrightarrow> C \<noteq> Object"
schirmer@12854
   164
by (erule converse_trancl_induct) (auto dest: subcls1D)
schirmer@12854
   165
schirmer@12854
   166
lemma subcls_acyclic: "\<lbrakk>G\<turnstile>C \<prec>\<^sub>C D; ws_prog G\<rbrakk> \<Longrightarrow> \<not> G\<turnstile>D \<prec>\<^sub>C C"
schirmer@12854
   167
proof -
schirmer@12854
   168
  assume         ws: "ws_prog G"
schirmer@12854
   169
  assume subcls_C_D: "G\<turnstile>C \<prec>\<^sub>C D"
schirmer@12854
   170
  then show ?thesis
schirmer@12854
   171
  proof (induct rule: converse_trancl_induct)
schirmer@12854
   172
    fix C
haftmann@35416
   173
    assume subcls1_C_D: "G\<turnstile>C \<prec>\<^sub>C1 D"
schirmer@12854
   174
    then obtain c  where
schirmer@12854
   175
        "C\<noteq>Object" and
schirmer@12854
   176
        "class G C = Some c" and
schirmer@12854
   177
        "super c = D"
schirmer@12854
   178
      by (auto simp add: subcls1_def)
schirmer@12854
   179
    with ws 
schirmer@12854
   180
    show "\<not> G\<turnstile>D \<prec>\<^sub>C C"
schirmer@12854
   181
      by (auto dest: ws_prog_cdeclD)
schirmer@12854
   182
  next
schirmer@12854
   183
    fix C Z
haftmann@35416
   184
    assume subcls1_C_Z: "G\<turnstile>C \<prec>\<^sub>C1 Z" and
schirmer@12854
   185
            subcls_Z_D: "G\<turnstile>Z \<prec>\<^sub>C D" and
schirmer@12854
   186
           nsubcls_D_Z: "\<not> G\<turnstile>D \<prec>\<^sub>C Z"
schirmer@12854
   187
    show "\<not> G\<turnstile>D \<prec>\<^sub>C C"
schirmer@12854
   188
    proof
schirmer@12854
   189
      assume subcls_D_C: "G\<turnstile>D \<prec>\<^sub>C C"
schirmer@12854
   190
      show "False"
schirmer@12854
   191
      proof -
wenzelm@32960
   192
        from subcls_D_C subcls1_C_Z
wenzelm@32960
   193
        have "G\<turnstile>D \<prec>\<^sub>C Z"
wenzelm@32960
   194
          by (auto dest: r_into_trancl trancl_trans)
wenzelm@32960
   195
        with nsubcls_D_Z
wenzelm@32960
   196
        show ?thesis
wenzelm@32960
   197
          by (rule notE)
schirmer@12854
   198
      qed
schirmer@12854
   199
    qed
schirmer@12854
   200
  qed  
schirmer@12854
   201
qed
schirmer@12854
   202
schirmer@12854
   203
lemma subclseq_cases [consumes 1, case_names Eq Subcls]:
schirmer@12854
   204
 "\<lbrakk>G\<turnstile>C \<preceq>\<^sub>C D; C = D \<Longrightarrow> P; G\<turnstile>C \<prec>\<^sub>C D \<Longrightarrow> P\<rbrakk> \<Longrightarrow> P"
schirmer@12854
   205
by (blast intro: rtrancl_cases)
schirmer@12854
   206
schirmer@12854
   207
lemma subclseq_acyclic: 
schirmer@12854
   208
 "\<lbrakk>G\<turnstile>C \<preceq>\<^sub>C D; G\<turnstile>D \<preceq>\<^sub>C C; ws_prog G\<rbrakk> \<Longrightarrow> C=D"
schirmer@12854
   209
by (auto elim: subclseq_cases dest: subcls_acyclic)
schirmer@12854
   210
schirmer@12854
   211
lemma subcls_irrefl: "\<lbrakk>G\<turnstile>C \<prec>\<^sub>C D; ws_prog G\<rbrakk>
schirmer@12854
   212
 \<Longrightarrow> C \<noteq> D"
schirmer@12854
   213
proof -
schirmer@12854
   214
  assume     ws: "ws_prog G"
schirmer@12854
   215
  assume subcls: "G\<turnstile>C \<prec>\<^sub>C D"
schirmer@12854
   216
  then show ?thesis
schirmer@12854
   217
  proof (induct rule: converse_trancl_induct)
schirmer@12854
   218
    fix C
haftmann@35416
   219
    assume "G\<turnstile>C \<prec>\<^sub>C1 D"
schirmer@12854
   220
    with ws 
schirmer@12854
   221
    show "C\<noteq>D" 
schirmer@12854
   222
      by (blast dest: subcls1_irrefl)
schirmer@12854
   223
  next
schirmer@12854
   224
    fix C Z
haftmann@35416
   225
    assume subcls1_C_Z: "G\<turnstile>C \<prec>\<^sub>C1 Z" and
schirmer@12854
   226
            subcls_Z_D: "G\<turnstile>Z \<prec>\<^sub>C D" and
schirmer@12854
   227
               neq_Z_D: "Z \<noteq> D"
schirmer@12854
   228
    show "C\<noteq>D"
schirmer@12854
   229
    proof
schirmer@12854
   230
      assume eq_C_D: "C=D"
schirmer@12854
   231
      show "False"
schirmer@12854
   232
      proof -
wenzelm@32960
   233
        from subcls1_C_Z eq_C_D 
wenzelm@32960
   234
        have "G\<turnstile>D \<prec>\<^sub>C Z"
wenzelm@32960
   235
          by (auto)
wenzelm@32960
   236
        also
wenzelm@32960
   237
        from subcls_Z_D ws   
wenzelm@32960
   238
        have "\<not> G\<turnstile>D \<prec>\<^sub>C Z"
wenzelm@32960
   239
          by (rule subcls_acyclic)
wenzelm@32960
   240
        ultimately 
wenzelm@32960
   241
        show ?thesis 
wenzelm@32960
   242
          by - (rule notE)
schirmer@12854
   243
      qed
schirmer@12854
   244
    qed
schirmer@12854
   245
  qed
schirmer@12854
   246
qed
schirmer@12854
   247
schirmer@12854
   248
lemma invert_subclseq:
schirmer@12854
   249
"\<lbrakk>G\<turnstile>C \<preceq>\<^sub>C D; ws_prog G\<rbrakk>
schirmer@12854
   250
 \<Longrightarrow> \<not> G\<turnstile>D \<prec>\<^sub>C C"
schirmer@12854
   251
proof -
schirmer@12854
   252
  assume       ws: "ws_prog G" and
schirmer@12854
   253
     subclseq_C_D: "G\<turnstile>C \<preceq>\<^sub>C D"
schirmer@12854
   254
  show ?thesis
schirmer@12854
   255
  proof (cases "D=C")
schirmer@12854
   256
    case True
schirmer@12854
   257
    with ws 
schirmer@12854
   258
    show ?thesis 
schirmer@12854
   259
      by (auto dest: subcls_irrefl)
schirmer@12854
   260
  next
schirmer@12854
   261
    case False
schirmer@12854
   262
    with subclseq_C_D 
schirmer@12854
   263
    have "G\<turnstile>C \<prec>\<^sub>C D"
schirmer@12854
   264
      by (blast intro: rtrancl_into_trancl3) 
schirmer@12854
   265
    with ws 
schirmer@12854
   266
    show ?thesis 
schirmer@12854
   267
      by (blast dest: subcls_acyclic)
schirmer@12854
   268
  qed
schirmer@12854
   269
qed
schirmer@12854
   270
schirmer@12854
   271
lemma invert_subcls:
schirmer@12854
   272
"\<lbrakk>G\<turnstile>C \<prec>\<^sub>C D; ws_prog G\<rbrakk>
schirmer@12854
   273
 \<Longrightarrow> \<not> G\<turnstile>D \<preceq>\<^sub>C C"
schirmer@12854
   274
proof -
schirmer@12854
   275
  assume        ws: "ws_prog G" and
schirmer@12854
   276
        subcls_C_D: "G\<turnstile>C \<prec>\<^sub>C D"
schirmer@12854
   277
  then 
schirmer@12854
   278
  have nsubcls_D_C: "\<not> G\<turnstile>D \<prec>\<^sub>C C"
schirmer@12854
   279
    by (blast dest: subcls_acyclic)
schirmer@12854
   280
  show ?thesis
schirmer@12854
   281
  proof
schirmer@12854
   282
    assume "G\<turnstile>D \<preceq>\<^sub>C C"
schirmer@12854
   283
    then show "False"
schirmer@12854
   284
    proof (cases rule: subclseq_cases)
schirmer@12854
   285
      case Eq
schirmer@12854
   286
      with ws subcls_C_D
schirmer@12854
   287
      show ?thesis 
wenzelm@32960
   288
        by (auto dest: subcls_irrefl)
schirmer@12854
   289
    next
schirmer@12854
   290
      case Subcls
schirmer@12854
   291
      with nsubcls_D_C
schirmer@12854
   292
      show ?thesis
wenzelm@32960
   293
        by blast
schirmer@12854
   294
    qed
schirmer@12854
   295
  qed
schirmer@12854
   296
qed
schirmer@12854
   297
schirmer@12854
   298
lemma subcls_superD:
schirmer@12854
   299
 "\<lbrakk>G\<turnstile>C \<prec>\<^sub>C D; class G C = Some c\<rbrakk> \<Longrightarrow> G\<turnstile>(super c) \<preceq>\<^sub>C D"
schirmer@12854
   300
proof -
schirmer@12854
   301
  assume       clsC: "class G C = Some c"
schirmer@12854
   302
  assume subcls_C_C: "G\<turnstile>C \<prec>\<^sub>C D"
schirmer@12854
   303
  then obtain S where 
haftmann@35416
   304
                  "G\<turnstile>C \<prec>\<^sub>C1 S" and
schirmer@12854
   305
    subclseq_S_D: "G\<turnstile>S \<preceq>\<^sub>C D"
schirmer@12854
   306
    by (blast dest: tranclD)
schirmer@12854
   307
  with clsC 
schirmer@12854
   308
  have "S=super c" 
schirmer@12854
   309
    by (auto dest: subcls1D)
schirmer@12854
   310
  with subclseq_S_D show ?thesis by simp
schirmer@12854
   311
qed
schirmer@12854
   312
 
schirmer@12854
   313
schirmer@12854
   314
lemma subclseq_superD:
schirmer@12854
   315
 "\<lbrakk>G\<turnstile>C \<preceq>\<^sub>C D; C\<noteq>D;class G C = Some c\<rbrakk> \<Longrightarrow> G\<turnstile>(super c) \<preceq>\<^sub>C D"
schirmer@12854
   316
proof -
schirmer@12854
   317
  assume neq_C_D: "C\<noteq>D"
schirmer@12854
   318
  assume    clsC: "class G C = Some c"
schirmer@12854
   319
  assume subclseq_C_D: "G\<turnstile>C \<preceq>\<^sub>C D" 
schirmer@12854
   320
  then show ?thesis
schirmer@12854
   321
  proof (cases rule: subclseq_cases)
schirmer@12854
   322
    case Eq with neq_C_D show ?thesis by contradiction
schirmer@12854
   323
  next
schirmer@12854
   324
    case Subcls
schirmer@12854
   325
    with clsC show ?thesis by (blast dest: subcls_superD)
schirmer@12854
   326
  qed
schirmer@12854
   327
qed
schirmer@12854
   328
schirmer@12854
   329
section "implementation relation"
schirmer@12854
   330
schirmer@12854
   331
lemma implmt1D: "G\<turnstile>C\<leadsto>1I \<Longrightarrow> C\<noteq>Object \<and> (\<exists>c\<in>class G C: I\<in>set (superIfs c))"
schirmer@12854
   332
apply (unfold implmt1_def)
schirmer@12854
   333
apply auto
schirmer@12854
   334
done
schirmer@12854
   335
berghofe@23747
   336
inductive --{* implementation, cf. 8.1.4 *}
berghofe@21765
   337
  implmt :: "prog \<Rightarrow> qtname \<Rightarrow> qtname \<Rightarrow> bool" ("_\<turnstile>_\<leadsto>_" [71,71,71] 70)
berghofe@21765
   338
  for G :: prog
berghofe@21765
   339
where
schirmer@12854
   340
  direct:         "G\<turnstile>C\<leadsto>1J     \<spacespace>\<spacespace>     \<Longrightarrow> G\<turnstile>C\<leadsto>J"
berghofe@21765
   341
| subint:        "\<lbrakk>G\<turnstile>C\<leadsto>1I; G\<turnstile>I\<preceq>I J\<rbrakk>  \<Longrightarrow> G\<turnstile>C\<leadsto>J"
haftmann@35416
   342
| subcls1:       "\<lbrakk>G\<turnstile>C\<prec>\<^sub>C1D; G\<turnstile>D\<leadsto>J \<rbrakk>  \<Longrightarrow> G\<turnstile>C\<leadsto>J"
schirmer@12854
   343
haftmann@35416
   344
lemma implmtD: "G\<turnstile>C\<leadsto>J \<Longrightarrow> (\<exists>I. G\<turnstile>C\<leadsto>1I \<and> G\<turnstile>I\<preceq>I J) \<or> (\<exists>D. G\<turnstile>C\<prec>\<^sub>C1D \<and> G\<turnstile>D\<leadsto>J)" 
schirmer@12854
   345
apply (erule implmt.induct)
schirmer@12854
   346
apply fast+
schirmer@12854
   347
done
schirmer@12854
   348
schirmer@12854
   349
lemma implmt_ObjectE [elim!]: "G\<turnstile>Object\<leadsto>I \<Longrightarrow> R"
schirmer@12854
   350
by (auto dest!: implmtD implmt1D subcls1D)
schirmer@12854
   351
schirmer@12854
   352
lemma subcls_implmt [rule_format (no_asm)]: "G\<turnstile>A\<preceq>\<^sub>C B \<Longrightarrow> G\<turnstile>B\<leadsto>K \<longrightarrow> G\<turnstile>A\<leadsto>K"
schirmer@12854
   353
apply (erule rtrancl_induct)
schirmer@12854
   354
apply  (auto intro: implmt.subcls1)
schirmer@12854
   355
done
schirmer@12854
   356
schirmer@12854
   357
lemma implmt_subint2: "\<lbrakk> G\<turnstile>A\<leadsto>J; G\<turnstile>J\<preceq>I K\<rbrakk> \<Longrightarrow> G\<turnstile>A\<leadsto>K"
wenzelm@24038
   358
apply (erule rev_mp, erule implmt.induct)
schirmer@12854
   359
apply (auto dest: implmt.subint rtrancl_trans implmt.subcls1)
schirmer@12854
   360
done
schirmer@12854
   361
schirmer@12854
   362
lemma implmt_is_class: "G\<turnstile>C\<leadsto>I \<Longrightarrow> is_class G C"
schirmer@12854
   363
apply (erule implmt.induct)
paulson@18447
   364
apply (auto dest: implmt1D subcls1D)
schirmer@12854
   365
done
schirmer@12854
   366
schirmer@12854
   367
schirmer@12854
   368
section "widening relation"
schirmer@12854
   369
berghofe@23747
   370
inductive
schirmer@13688
   371
 --{*widening, viz. method invocation conversion, cf. 5.3
wenzelm@32960
   372
                            i.e. kind of syntactic subtyping *}
berghofe@21765
   373
  widen :: "prog \<Rightarrow> ty \<Rightarrow> ty \<Rightarrow> bool" ("_\<turnstile>_\<preceq>_" [71,71,71] 70)
berghofe@21765
   374
  for G :: prog
berghofe@21765
   375
where
schirmer@13688
   376
  refl:    "G\<turnstile>T\<preceq>T" --{*identity conversion, cf. 5.1.1 *}
berghofe@21765
   377
| subint:  "G\<turnstile>I\<preceq>I J  \<Longrightarrow> G\<turnstile>Iface I\<preceq> Iface J" --{*wid.ref.conv.,cf. 5.1.4 *}
berghofe@21765
   378
| int_obj: "G\<turnstile>Iface I\<preceq> Class Object"
berghofe@21765
   379
| subcls:  "G\<turnstile>C\<preceq>\<^sub>C D  \<Longrightarrow> G\<turnstile>Class C\<preceq> Class D"
berghofe@21765
   380
| implmt:  "G\<turnstile>C\<leadsto>I   \<Longrightarrow> G\<turnstile>Class C\<preceq> Iface I"
berghofe@21765
   381
| null:    "G\<turnstile>NT\<preceq> RefT R"
berghofe@21765
   382
| arr_obj: "G\<turnstile>T.[]\<preceq> Class Object"
berghofe@21765
   383
| array:   "G\<turnstile>RefT S\<preceq>RefT T \<Longrightarrow> G\<turnstile>RefT S.[]\<preceq> RefT T.[]"
schirmer@12854
   384
schirmer@12854
   385
declare widen.refl [intro!]
schirmer@12854
   386
declare widen.intros [simp]
schirmer@12854
   387
schirmer@12854
   388
(* too strong in general:
schirmer@12854
   389
lemma widen_PrimT: "G\<turnstile>PrimT x\<preceq>T \<Longrightarrow> T = PrimT x"
schirmer@12854
   390
*)
schirmer@12854
   391
lemma widen_PrimT: "G\<turnstile>PrimT x\<preceq>T \<Longrightarrow> (\<exists>y. T = PrimT y)"
berghofe@23747
   392
apply (ind_cases "G\<turnstile>PrimT x\<preceq>T")
schirmer@12854
   393
by auto
schirmer@12854
   394
schirmer@12854
   395
(* too strong in general:
schirmer@12854
   396
lemma widen_PrimT2: "G\<turnstile>S\<preceq>PrimT x \<Longrightarrow> S = PrimT x"
schirmer@12854
   397
*)
schirmer@12854
   398
lemma widen_PrimT2: "G\<turnstile>S\<preceq>PrimT x \<Longrightarrow> \<exists>y. S = PrimT y"
berghofe@23747
   399
apply (ind_cases "G\<turnstile>S\<preceq>PrimT x")
schirmer@12854
   400
by auto
schirmer@12854
   401
schirmer@13688
   402
text {* 
schirmer@13688
   403
   These widening lemmata hold in Bali but are to strong for ordinary
schirmer@13688
   404
   Java. They  would not work for real Java Integral Types, like short, 
schirmer@13688
   405
   long, int. These lemmata are just for documentation and are not used.
schirmer@13688
   406
 *}
schirmer@13688
   407
schirmer@13688
   408
lemma widen_PrimT_strong: "G\<turnstile>PrimT x\<preceq>T \<Longrightarrow> T = PrimT x"
berghofe@23747
   409
by (ind_cases "G\<turnstile>PrimT x\<preceq>T") simp_all
schirmer@13688
   410
schirmer@13688
   411
lemma widen_PrimT2_strong: "G\<turnstile>S\<preceq>PrimT x \<Longrightarrow> S = PrimT x"
berghofe@23747
   412
by (ind_cases "G\<turnstile>S\<preceq>PrimT x") simp_all
schirmer@13688
   413
schirmer@13688
   414
text {* Specialized versions for booleans also would work for real Java *}
schirmer@13688
   415
schirmer@13688
   416
lemma widen_Boolean: "G\<turnstile>PrimT Boolean\<preceq>T \<Longrightarrow> T = PrimT Boolean"
berghofe@23747
   417
by (ind_cases "G\<turnstile>PrimT Boolean\<preceq>T") simp_all
schirmer@13688
   418
schirmer@13688
   419
lemma widen_Boolean2: "G\<turnstile>S\<preceq>PrimT Boolean \<Longrightarrow> S = PrimT Boolean"
berghofe@23747
   420
by (ind_cases "G\<turnstile>S\<preceq>PrimT Boolean") simp_all
schirmer@13688
   421
schirmer@12854
   422
lemma widen_RefT: "G\<turnstile>RefT R\<preceq>T \<Longrightarrow> \<exists>t. T=RefT t"
berghofe@23747
   423
apply (ind_cases "G\<turnstile>RefT R\<preceq>T")
schirmer@12854
   424
by auto
schirmer@12854
   425
schirmer@12854
   426
lemma widen_RefT2: "G\<turnstile>S\<preceq>RefT R \<Longrightarrow> \<exists>t. S=RefT t"
berghofe@23747
   427
apply (ind_cases "G\<turnstile>S\<preceq>RefT R")
schirmer@12854
   428
by auto
schirmer@12854
   429
schirmer@12854
   430
lemma widen_Iface: "G\<turnstile>Iface I\<preceq>T \<Longrightarrow> T=Class Object \<or> (\<exists>J. T=Iface J)"
berghofe@23747
   431
apply (ind_cases "G\<turnstile>Iface I\<preceq>T")
schirmer@12854
   432
by auto
schirmer@12854
   433
schirmer@12854
   434
lemma widen_Iface2: "G\<turnstile>S\<preceq> Iface J \<Longrightarrow> S = NT \<or> (\<exists>I. S = Iface I) \<or> (\<exists>D. S = Class D)"
berghofe@23747
   435
apply (ind_cases "G\<turnstile>S\<preceq> Iface J")
schirmer@12854
   436
by auto
schirmer@12854
   437
schirmer@12854
   438
lemma widen_Iface_Iface: "G\<turnstile>Iface I\<preceq> Iface J \<Longrightarrow> G\<turnstile>I\<preceq>I J"
berghofe@23747
   439
apply (ind_cases "G\<turnstile>Iface I\<preceq> Iface J")
schirmer@12854
   440
by auto
schirmer@12854
   441
schirmer@12854
   442
lemma widen_Iface_Iface_eq [simp]: "G\<turnstile>Iface I\<preceq> Iface J = G\<turnstile>I\<preceq>I J"
schirmer@12854
   443
apply (rule iffI)
schirmer@12854
   444
apply  (erule widen_Iface_Iface)
schirmer@12854
   445
apply (erule widen.subint)
schirmer@12854
   446
done
schirmer@12854
   447
schirmer@12854
   448
lemma widen_Class: "G\<turnstile>Class C\<preceq>T \<Longrightarrow>  (\<exists>D. T=Class D) \<or> (\<exists>I. T=Iface I)"
berghofe@23747
   449
apply (ind_cases "G\<turnstile>Class C\<preceq>T")
schirmer@12854
   450
by auto
schirmer@12854
   451
schirmer@12854
   452
lemma widen_Class2: "G\<turnstile>S\<preceq> Class C \<Longrightarrow> C = Object \<or> S = NT \<or> (\<exists>D. S = Class D)"
berghofe@23747
   453
apply (ind_cases "G\<turnstile>S\<preceq> Class C")
schirmer@12854
   454
by auto
schirmer@12854
   455
schirmer@12854
   456
lemma widen_Class_Class: "G\<turnstile>Class C\<preceq> Class cm \<Longrightarrow> G\<turnstile>C\<preceq>\<^sub>C cm"
berghofe@23747
   457
apply (ind_cases "G\<turnstile>Class C\<preceq> Class cm")
schirmer@12854
   458
by auto
schirmer@12854
   459
schirmer@12854
   460
lemma widen_Class_Class_eq [simp]: "G\<turnstile>Class C\<preceq> Class cm = G\<turnstile>C\<preceq>\<^sub>C cm"
schirmer@12854
   461
apply (rule iffI)
schirmer@12854
   462
apply  (erule widen_Class_Class)
schirmer@12854
   463
apply (erule widen.subcls)
schirmer@12854
   464
done
schirmer@12854
   465
schirmer@12854
   466
lemma widen_Class_Iface: "G\<turnstile>Class C\<preceq> Iface I \<Longrightarrow> G\<turnstile>C\<leadsto>I"
berghofe@23747
   467
apply (ind_cases "G\<turnstile>Class C\<preceq> Iface I")
schirmer@12854
   468
by auto
schirmer@12854
   469
schirmer@12854
   470
lemma widen_Class_Iface_eq [simp]: "G\<turnstile>Class C\<preceq> Iface I = G\<turnstile>C\<leadsto>I"
schirmer@12854
   471
apply (rule iffI)
schirmer@12854
   472
apply  (erule widen_Class_Iface)
schirmer@12854
   473
apply (erule widen.implmt)
schirmer@12854
   474
done
schirmer@12854
   475
schirmer@12854
   476
lemma widen_Array: "G\<turnstile>S.[]\<preceq>T \<Longrightarrow> T=Class Object \<or> (\<exists>T'. T=T'.[] \<and> G\<turnstile>S\<preceq>T')"
berghofe@23747
   477
apply (ind_cases "G\<turnstile>S.[]\<preceq>T")
schirmer@12854
   478
by auto
schirmer@12854
   479
schirmer@12854
   480
lemma widen_Array2: "G\<turnstile>S\<preceq>T.[] \<Longrightarrow> S = NT \<or> (\<exists>S'. S=S'.[] \<and> G\<turnstile>S'\<preceq>T)"
berghofe@23747
   481
apply (ind_cases "G\<turnstile>S\<preceq>T.[]")
schirmer@12854
   482
by auto
schirmer@12854
   483
schirmer@12854
   484
schirmer@12854
   485
lemma widen_ArrayPrimT: "G\<turnstile>PrimT t.[]\<preceq>T \<Longrightarrow> T=Class Object \<or> T=PrimT t.[]"
berghofe@23747
   486
apply (ind_cases "G\<turnstile>PrimT t.[]\<preceq>T")
schirmer@12854
   487
by auto
schirmer@12854
   488
schirmer@12854
   489
lemma widen_ArrayRefT: 
schirmer@12854
   490
  "G\<turnstile>RefT t.[]\<preceq>T \<Longrightarrow> T=Class Object \<or> (\<exists>s. T=RefT s.[] \<and> G\<turnstile>RefT t\<preceq>RefT s)"
berghofe@23747
   491
apply (ind_cases "G\<turnstile>RefT t.[]\<preceq>T")
schirmer@12854
   492
by auto
schirmer@12854
   493
schirmer@12854
   494
lemma widen_ArrayRefT_ArrayRefT_eq [simp]: 
schirmer@12854
   495
  "G\<turnstile>RefT T.[]\<preceq>RefT T'.[] = G\<turnstile>RefT T\<preceq>RefT T'"
schirmer@12854
   496
apply (rule iffI)
schirmer@12854
   497
apply (drule widen_ArrayRefT)
schirmer@12854
   498
apply simp
schirmer@12854
   499
apply (erule widen.array)
schirmer@12854
   500
done
schirmer@12854
   501
schirmer@12854
   502
lemma widen_Array_Array: "G\<turnstile>T.[]\<preceq>T'.[] \<Longrightarrow> G\<turnstile>T\<preceq>T'"
schirmer@12854
   503
apply (drule widen_Array)
schirmer@12854
   504
apply auto
schirmer@12854
   505
done
schirmer@12854
   506
schirmer@12854
   507
lemma widen_Array_Class: "G\<turnstile>S.[] \<preceq> Class C \<Longrightarrow> C=Object"
schirmer@12854
   508
by (auto dest: widen_Array)
schirmer@12854
   509
schirmer@13688
   510
schirmer@12854
   511
lemma widen_NT2: "G\<turnstile>S\<preceq>NT \<Longrightarrow> S = NT"
berghofe@23747
   512
apply (ind_cases "G\<turnstile>S\<preceq>NT")
schirmer@12854
   513
by auto
schirmer@12854
   514
haftmann@38541
   515
lemma widen_Object:
haftmann@38541
   516
  assumes "isrtype G T" and "ws_prog G"
haftmann@38541
   517
  shows "G\<turnstile>RefT T \<preceq> Class Object"
haftmann@38541
   518
proof (cases T)
haftmann@38541
   519
  case (ClassT C) with assms have "G\<turnstile>C\<preceq>\<^sub>C Object" by (auto intro: subcls_ObjectI)
haftmann@38541
   520
  with ClassT show ?thesis by auto
haftmann@38541
   521
qed simp_all
schirmer@12854
   522
schirmer@12854
   523
lemma widen_trans_lemma [rule_format (no_asm)]: 
schirmer@12854
   524
  "\<lbrakk>G\<turnstile>S\<preceq>U; \<forall>C. is_class G C \<longrightarrow> G\<turnstile>C\<preceq>\<^sub>C Object\<rbrakk> \<Longrightarrow> \<forall>T. G\<turnstile>U\<preceq>T \<longrightarrow> G\<turnstile>S\<preceq>T"
schirmer@12854
   525
apply (erule widen.induct)
schirmer@12854
   526
apply        safe
schirmer@12854
   527
prefer      5 apply (drule widen_RefT) apply clarsimp
schirmer@12854
   528
apply      (frule_tac [1] widen_Iface)
schirmer@12854
   529
apply      (frule_tac [2] widen_Class)
schirmer@12854
   530
apply      (frule_tac [3] widen_Class)
schirmer@12854
   531
apply      (frule_tac [4] widen_Iface)
schirmer@12854
   532
apply      (frule_tac [5] widen_Class)
schirmer@12854
   533
apply      (frule_tac [6] widen_Array)
schirmer@12854
   534
apply      safe
schirmer@12854
   535
apply            (rule widen.int_obj)
schirmer@12854
   536
prefer          6 apply (drule implmt_is_class) apply simp
schirmer@12854
   537
apply (tactic "ALLGOALS (etac thin_rl)")
schirmer@12854
   538
prefer         6 apply simp
schirmer@12854
   539
apply          (rule_tac [9] widen.arr_obj)
schirmer@12854
   540
apply         (rotate_tac [9] -1)
schirmer@12854
   541
apply         (frule_tac [9] widen_RefT)
schirmer@12854
   542
apply         (auto elim!: rtrancl_trans subcls_implmt implmt_subint2)
schirmer@12854
   543
done
schirmer@12854
   544
schirmer@12854
   545
lemma ws_widen_trans: "\<lbrakk>G\<turnstile>S\<preceq>U; G\<turnstile>U\<preceq>T; ws_prog G\<rbrakk> \<Longrightarrow> G\<turnstile>S\<preceq>T"
schirmer@12854
   546
by (auto intro: widen_trans_lemma subcls_ObjectI)
schirmer@12854
   547
schirmer@12854
   548
lemma widen_antisym_lemma [rule_format (no_asm)]: "\<lbrakk>G\<turnstile>S\<preceq>T;  
schirmer@12854
   549
 \<forall>I J. G\<turnstile>I\<preceq>I J \<and> G\<turnstile>J\<preceq>I I \<longrightarrow> I = J;  
schirmer@12854
   550
 \<forall>C D. G\<turnstile>C\<preceq>\<^sub>C D \<and> G\<turnstile>D\<preceq>\<^sub>C C \<longrightarrow> C = D;  
schirmer@12854
   551
 \<forall>I  . G\<turnstile>Object\<leadsto>I        \<longrightarrow> False\<rbrakk> \<Longrightarrow> G\<turnstile>T\<preceq>S \<longrightarrow> S = T"
schirmer@12854
   552
apply (erule widen.induct)
schirmer@12854
   553
apply (auto dest: widen_Iface widen_NT2 widen_Class)
schirmer@12854
   554
done
schirmer@12854
   555
schirmer@12854
   556
lemmas subint_antisym = 
wenzelm@45605
   557
       subint1_acyclic [THEN acyclic_impl_antisym_rtrancl]
schirmer@12854
   558
lemmas subcls_antisym = 
wenzelm@45605
   559
       subcls1_acyclic [THEN acyclic_impl_antisym_rtrancl]
schirmer@12854
   560
schirmer@12854
   561
lemma widen_antisym: "\<lbrakk>G\<turnstile>S\<preceq>T; G\<turnstile>T\<preceq>S; ws_prog G\<rbrakk> \<Longrightarrow> S=T"
schirmer@12854
   562
by (fast elim: widen_antisym_lemma subint_antisym [THEN antisymD] 
schirmer@12854
   563
                                   subcls_antisym [THEN antisymD])
schirmer@12854
   564
schirmer@12854
   565
lemma widen_ObjectD [dest!]: "G\<turnstile>Class Object\<preceq>T \<Longrightarrow> T=Class Object"
schirmer@12854
   566
apply (frule widen_Class)
schirmer@12854
   567
apply (fast dest: widen_Class_Class widen_Class_Iface)
schirmer@12854
   568
done
schirmer@12854
   569
wenzelm@37956
   570
definition
wenzelm@37956
   571
  widens :: "prog \<Rightarrow> [ty list, ty list] \<Rightarrow> bool" ("_\<turnstile>_[\<preceq>]_" [71,71,71] 70)
wenzelm@37956
   572
  where "G\<turnstile>Ts[\<preceq>]Ts' = list_all2 (\<lambda>T T'. G\<turnstile>T\<preceq>T') Ts Ts'"
schirmer@12854
   573
schirmer@12854
   574
lemma widens_Nil [simp]: "G\<turnstile>[][\<preceq>][]"
schirmer@12854
   575
apply (unfold widens_def)
schirmer@12854
   576
apply auto
schirmer@12854
   577
done
schirmer@12854
   578
schirmer@12854
   579
lemma widens_Cons [simp]: "G\<turnstile>(S#Ss)[\<preceq>](T#Ts) = (G\<turnstile>S\<preceq>T \<and> G\<turnstile>Ss[\<preceq>]Ts)"
schirmer@12854
   580
apply (unfold widens_def)
schirmer@12854
   581
apply auto
schirmer@12854
   582
done
schirmer@12854
   583
schirmer@12854
   584
schirmer@12854
   585
section "narrowing relation"
schirmer@12854
   586
schirmer@12854
   587
(* all properties of narrowing and casting conversions we actually need *)
schirmer@12854
   588
(* these can easily be proven from the definitions below *)
schirmer@12854
   589
(*
schirmer@12854
   590
rules
schirmer@12854
   591
  cast_RefT2   "G\<turnstile>S\<preceq>? RefT R   \<Longrightarrow> \<exists>t. S=RefT t" 
schirmer@12854
   592
  cast_PrimT2  "G\<turnstile>S\<preceq>? PrimT pt \<Longrightarrow> \<exists>t. S=PrimT t \<and> G\<turnstile>PrimT t\<preceq>PrimT pt"
schirmer@12854
   593
*)
schirmer@12854
   594
schirmer@12854
   595
(* more detailed than necessary for type-safety, see above rules. *)
berghofe@23747
   596
inductive --{* narrowing reference conversion, cf. 5.1.5 *}
berghofe@21765
   597
  narrow :: "prog \<Rightarrow> ty \<Rightarrow> ty \<Rightarrow> bool" ("_\<turnstile>_\<succ>_" [71,71,71] 70)
berghofe@21765
   598
  for G :: prog
berghofe@21765
   599
where
schirmer@12854
   600
  subcls:  "G\<turnstile>C\<preceq>\<^sub>C D \<Longrightarrow> G\<turnstile>     Class D\<succ>Class C"
berghofe@21765
   601
| implmt:  "\<not>G\<turnstile>C\<leadsto>I \<Longrightarrow> G\<turnstile>     Class C\<succ>Iface I"
berghofe@21765
   602
| obj_arr: "G\<turnstile>Class Object\<succ>T.[]"
berghofe@21765
   603
| int_cls: "G\<turnstile>     Iface I\<succ>Class C"
berghofe@21765
   604
| subint:  "imethds G I hidings imethds G J entails 
wenzelm@32960
   605
           (\<lambda>(md, mh   ) (md',mh').\<spacespace>G\<turnstile>mrt mh\<preceq>mrt mh') \<Longrightarrow>
wenzelm@32960
   606
           \<not>G\<turnstile>I\<preceq>I J         \<spacespace>\<spacespace>\<spacespace>\<Longrightarrow> G\<turnstile>     Iface I\<succ>Iface J"
berghofe@21765
   607
| array:   "G\<turnstile>RefT S\<succ>RefT T   \<spacespace>\<Longrightarrow> G\<turnstile>   RefT S.[]\<succ>RefT T.[]"
schirmer@12854
   608
schirmer@12854
   609
(*unused*)
schirmer@12854
   610
lemma narrow_RefT: "G\<turnstile>RefT R\<succ>T \<Longrightarrow> \<exists>t. T=RefT t"
berghofe@23747
   611
apply (ind_cases "G\<turnstile>RefT R\<succ>T")
schirmer@12854
   612
by auto
schirmer@12854
   613
schirmer@12854
   614
lemma narrow_RefT2: "G\<turnstile>S\<succ>RefT R \<Longrightarrow> \<exists>t. S=RefT t"
berghofe@23747
   615
apply (ind_cases "G\<turnstile>S\<succ>RefT R")
schirmer@12854
   616
by auto
schirmer@12854
   617
schirmer@12854
   618
(*unused*)
schirmer@12854
   619
lemma narrow_PrimT: "G\<turnstile>PrimT pt\<succ>T \<Longrightarrow> \<exists>t. T=PrimT t"
berghofe@23747
   620
by (ind_cases "G\<turnstile>PrimT pt\<succ>T")
schirmer@12854
   621
schirmer@12854
   622
lemma narrow_PrimT2: "G\<turnstile>S\<succ>PrimT pt \<Longrightarrow>  
wenzelm@32960
   623
                                  \<exists>t. S=PrimT t \<and> G\<turnstile>PrimT t\<preceq>PrimT pt"
berghofe@23747
   624
by (ind_cases "G\<turnstile>S\<succ>PrimT pt")
schirmer@12854
   625
schirmer@13688
   626
text {* 
schirmer@13688
   627
   These narrowing lemmata hold in Bali but are to strong for ordinary
schirmer@13688
   628
   Java. They  would not work for real Java Integral Types, like short, 
schirmer@13688
   629
   long, int. These lemmata are just for documentation and are not used.
schirmer@13688
   630
 *}
schirmer@13688
   631
lemma narrow_PrimT_strong: "G\<turnstile>PrimT pt\<succ>T \<Longrightarrow> T=PrimT pt"
berghofe@23747
   632
by (ind_cases "G\<turnstile>PrimT pt\<succ>T")
schirmer@13688
   633
schirmer@13688
   634
lemma narrow_PrimT2_strong: "G\<turnstile>S\<succ>PrimT pt \<Longrightarrow> S=PrimT pt"
berghofe@23747
   635
by (ind_cases "G\<turnstile>S\<succ>PrimT pt")
schirmer@13688
   636
schirmer@13688
   637
text {* Specialized versions for booleans also would work for real Java *}
schirmer@13688
   638
schirmer@13688
   639
lemma narrow_Boolean: "G\<turnstile>PrimT Boolean\<succ>T \<Longrightarrow> T=PrimT Boolean"
berghofe@23747
   640
by (ind_cases "G\<turnstile>PrimT Boolean\<succ>T")
schirmer@13688
   641
schirmer@13688
   642
lemma narrow_Boolean2: "G\<turnstile>S\<succ>PrimT Boolean \<Longrightarrow> S=PrimT Boolean"
berghofe@23747
   643
by (ind_cases "G\<turnstile>S\<succ>PrimT Boolean")
schirmer@12854
   644
schirmer@12854
   645
section "casting relation"
schirmer@12854
   646
berghofe@23747
   647
inductive --{* casting conversion, cf. 5.5 *}
berghofe@21765
   648
  cast :: "prog \<Rightarrow> ty \<Rightarrow> ty \<Rightarrow> bool" ("_\<turnstile>_\<preceq>? _" [71,71,71] 70)
berghofe@21765
   649
  for G :: prog
berghofe@21765
   650
where
schirmer@12854
   651
  widen:   "G\<turnstile>S\<preceq>T \<Longrightarrow> G\<turnstile>S\<preceq>? T"
berghofe@21765
   652
| narrow:  "G\<turnstile>S\<succ>T \<Longrightarrow> G\<turnstile>S\<preceq>? T"
schirmer@12854
   653
schirmer@12854
   654
(*unused*)
schirmer@12854
   655
lemma cast_RefT: "G\<turnstile>RefT R\<preceq>? T \<Longrightarrow> \<exists>t. T=RefT t"
berghofe@23747
   656
apply (ind_cases "G\<turnstile>RefT R\<preceq>? T")
schirmer@12854
   657
by (auto dest: widen_RefT narrow_RefT)
schirmer@12854
   658
schirmer@12854
   659
lemma cast_RefT2: "G\<turnstile>S\<preceq>? RefT R \<Longrightarrow> \<exists>t. S=RefT t"
berghofe@23747
   660
apply (ind_cases "G\<turnstile>S\<preceq>? RefT R")
schirmer@12854
   661
by (auto dest: widen_RefT2 narrow_RefT2)
schirmer@12854
   662
schirmer@12854
   663
(*unused*)
schirmer@12854
   664
lemma cast_PrimT: "G\<turnstile>PrimT pt\<preceq>? T \<Longrightarrow> \<exists>t. T=PrimT t"
berghofe@23747
   665
apply (ind_cases "G\<turnstile>PrimT pt\<preceq>? T")
schirmer@12854
   666
by (auto dest: widen_PrimT narrow_PrimT)
schirmer@12854
   667
schirmer@12854
   668
lemma cast_PrimT2: "G\<turnstile>S\<preceq>? PrimT pt \<Longrightarrow> \<exists>t. S=PrimT t \<and> G\<turnstile>PrimT t\<preceq>PrimT pt"
berghofe@23747
   669
apply (ind_cases "G\<turnstile>S\<preceq>? PrimT pt")
schirmer@12854
   670
by (auto dest: widen_PrimT2 narrow_PrimT2)
schirmer@12854
   671
schirmer@13688
   672
lemma cast_Boolean: 
schirmer@13688
   673
  assumes bool_cast: "G\<turnstile>PrimT Boolean\<preceq>? T" 
schirmer@13688
   674
  shows "T=PrimT Boolean"
schirmer@13688
   675
using bool_cast 
schirmer@13688
   676
proof (cases)
schirmer@13688
   677
  case widen 
schirmer@13688
   678
  hence "G\<turnstile>PrimT Boolean\<preceq> T"
schirmer@13688
   679
    by simp
schirmer@13688
   680
  thus ?thesis by  (rule widen_Boolean)
schirmer@13688
   681
next
schirmer@13688
   682
  case narrow
schirmer@13688
   683
  hence "G\<turnstile>PrimT Boolean\<succ>T"
schirmer@13688
   684
    by simp
schirmer@13688
   685
  thus ?thesis by (rule narrow_Boolean)
schirmer@13688
   686
qed
schirmer@13688
   687
schirmer@13688
   688
lemma cast_Boolean2: 
schirmer@13688
   689
  assumes bool_cast: "G\<turnstile>S\<preceq>? PrimT Boolean" 
schirmer@13688
   690
  shows "S = PrimT Boolean"
schirmer@13688
   691
using bool_cast 
schirmer@13688
   692
proof (cases)
schirmer@13688
   693
  case widen 
schirmer@13688
   694
  hence "G\<turnstile>S\<preceq> PrimT Boolean"
schirmer@13688
   695
    by simp
schirmer@13688
   696
  thus ?thesis by  (rule widen_Boolean2)
schirmer@13688
   697
next
schirmer@13688
   698
  case narrow
schirmer@13688
   699
  hence "G\<turnstile>S\<succ>PrimT Boolean"
schirmer@13688
   700
    by simp
schirmer@13688
   701
  thus ?thesis by (rule narrow_Boolean2)
schirmer@13688
   702
qed
schirmer@13688
   703
schirmer@12854
   704
end