| author | haftmann | 
| Tue, 05 Jan 2010 11:38:51 +0100 | |
| changeset 34271 | 70af06abb13d | 
| parent 33954 | 1bc3b688548c | 
| child 35416 | d8d7d1b785af | 
| permissions | -rwxr-xr-x | 
| 12516 | 1 | (* Title: HOL/MicroJava/BV/JVM.thy | 
| 2 | Author: Tobias Nipkow, Gerwin Klein | |
| 10592 | 3 | Copyright 2000 TUM | 
| 4 | *) | |
| 5 | ||
| 12911 | 6 | header {* \isaheader{Kildall for the JVM}\label{sec:JVM} *}
 | 
| 10592 | 7 | |
| 33954 
1bc3b688548c
backported parts of abstract byte code verifier from AFP/Jinja
 haftmann parents: 
33639diff
changeset | 8 | theory JVM | 
| 
1bc3b688548c
backported parts of abstract byte code verifier from AFP/Jinja
 haftmann parents: 
33639diff
changeset | 9 | imports Typing_Framework_JVM | 
| 
1bc3b688548c
backported parts of abstract byte code verifier from AFP/Jinja
 haftmann parents: 
33639diff
changeset | 10 | begin | 
| 10592 | 11 | |
| 12 | constdefs | |
| 13006 | 13 | kiljvm :: "jvm_prog \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> ty \<Rightarrow> exception_table \<Rightarrow> | 
| 26450 | 14 | instr list \<Rightarrow> JVMType.state list \<Rightarrow> JVMType.state list" | 
| 12516 | 15 | "kiljvm G maxs maxr rT et bs == | 
| 16 | kildall (JVMType.le G maxs maxr) (JVMType.sup G maxs maxr) (exec G maxs rT et bs)" | |
| 10592 | 17 | |
| 12516 | 18 | wt_kil :: "jvm_prog \<Rightarrow> cname \<Rightarrow> ty list \<Rightarrow> ty \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> | 
| 19 | exception_table \<Rightarrow> instr list \<Rightarrow> bool" | |
| 20 | "wt_kil G C pTs rT mxs mxl et ins == | |
| 13066 | 21 | check_bounded ins et \<and> 0 < size ins \<and> | 
| 10637 | 22 | (let first = Some ([],(OK (Class C))#((map OK pTs))@(replicate mxl Err)); | 
| 11701 
3d51fbf81c17
sane numerals (stage 1): added generic 1, removed 1' and 2 on nat,
 wenzelm parents: 
11299diff
changeset | 23 | start = OK first#(replicate (size ins - 1) (OK None)); | 
| 12516 | 24 | result = kiljvm G mxs (1+size pTs+mxl) rT et ins start | 
| 10637 | 25 | in \<forall>n < size ins. result!n \<noteq> Err)" | 
| 26 | ||
| 13006 | 27 | wt_jvm_prog_kildall :: "jvm_prog \<Rightarrow> bool" | 
| 10637 | 28 | "wt_jvm_prog_kildall G == | 
| 12516 | 29 | wf_prog (\<lambda>G C (sig,rT,(maxs,maxl,b,et)). wt_kil G C (snd sig) rT maxs maxl et b) G" | 
| 10592 | 30 | |
| 31 | ||
| 32 | theorem is_bcv_kiljvm: | |
| 13066 | 33 | "\<lbrakk> wf_prog wf_mb G; bounded (exec G maxs rT et bs) (size bs) \<rbrakk> \<Longrightarrow> | 
| 12516 | 34 | is_bcv (JVMType.le G maxs maxr) Err (exec G maxs rT et bs) | 
| 35 | (size bs) (states G maxs maxr) (kiljvm G maxs maxr rT et bs)" | |
| 10592 | 36 | apply (unfold kiljvm_def sl_triple_conv) | 
| 37 | apply (rule is_bcv_kildall) | |
| 38 | apply (simp (no_asm) add: sl_triple_conv [symmetric]) | |
| 14045 | 39 | apply (force intro!: semilat_JVM_slI dest: wf_acyclic | 
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
26450diff
changeset | 40 | simp add: symmetric sl_triple_conv) | 
| 10592 | 41 | apply (simp (no_asm) add: JVM_le_unfold) | 
| 42 | apply (blast intro!: order_widen wf_converse_subcls1_impl_acc_subtype | |
| 33954 
1bc3b688548c
backported parts of abstract byte code verifier from AFP/Jinja
 haftmann parents: 
33639diff
changeset | 43 | dest: wf_subcls1 wf_acyclic wf_prog_ws_prog) | 
| 10592 | 44 | apply (simp add: JVM_le_unfold) | 
| 45 | apply (erule exec_pres_type) | |
| 13066 | 46 | apply assumption | 
| 14045 | 47 | apply (drule wf_prog_ws_prog, erule exec_mono, assumption) | 
| 10592 | 48 | done | 
| 49 | ||
| 13224 | 50 | lemma subset_replicate: "set (replicate n x) \<subseteq> {x}"
 | 
| 51 | by (induct n) auto | |
| 52 | ||
| 53 | lemma in_set_replicate: | |
| 54 | "x \<in> set (replicate n y) \<Longrightarrow> x = y" | |
| 55 | proof - | |
| 56 | assume "x \<in> set (replicate n y)" | |
| 57 |   also have "set (replicate n y) \<subseteq> {y}" by (rule subset_replicate)
 | |
| 58 |   finally have "x \<in> {y}" .
 | |
| 59 | thus ?thesis by simp | |
| 60 | qed | |
| 10637 | 61 | |
| 62 | theorem wt_kil_correct: | |
| 13224 | 63 | assumes wf: "wf_prog wf_mb G" | 
| 64 | assumes C: "is_class G C" | |
| 65 | assumes pTs: "set pTs \<subseteq> types G" | |
| 66 | ||
| 67 | assumes wtk: "wt_kil G C pTs rT maxs mxl et bs" | |
| 68 | ||
| 69 | shows "\<exists>phi. wt_method G C pTs rT maxs mxl bs et phi" | |
| 10592 | 70 | proof - | 
| 71 | let ?start = "OK (Some ([],(OK (Class C))#((map OK pTs))@(replicate mxl Err))) | |
| 11701 
3d51fbf81c17
sane numerals (stage 1): added generic 1, removed 1' and 2 on nat,
 wenzelm parents: 
11299diff
changeset | 72 | #(replicate (size bs - 1) (OK None))" | 
| 10592 | 73 | |
| 13224 | 74 | from wtk obtain maxr r where | 
| 13066 | 75 | bounded: "check_bounded bs et" and | 
| 12516 | 76 | result: "r = kiljvm G maxs maxr rT et bs ?start" and | 
| 10637 | 77 | success: "\<forall>n < size bs. r!n \<noteq> Err" and | 
| 78 | instrs: "0 < size bs" and | |
| 79 | maxr: "maxr = Suc (length pTs + mxl)" | |
| 80 | by (unfold wt_kil_def) simp | |
| 10592 | 81 | |
| 13066 | 82 | from bounded have "bounded (exec G maxs rT et bs) (size bs)" | 
| 83 | by (unfold exec_def) (intro bounded_lift check_bounded_is_bounded) | |
| 84 | with wf have bcv: | |
| 12516 | 85 | "is_bcv (JVMType.le G maxs maxr) Err (exec G maxs rT et bs) | 
| 13066 | 86 | (size bs) (states G maxs maxr) (kiljvm G maxs maxr rT et bs)" | 
| 10592 | 87 | by (rule is_bcv_kiljvm) | 
| 13066 | 88 | |
| 13224 | 89 | from C pTs instrs maxr | 
| 10592 | 90 | have "?start \<in> list (length bs) (states G maxs maxr)" | 
| 13224 | 91 | apply (unfold JVM_states_unfold) | 
| 92 | apply (rule listI) | |
| 93 | apply (auto intro: list_appendI dest!: in_set_replicate) | |
| 94 | apply force | |
| 95 | done | |
| 96 | ||
| 12516 | 97 | with bcv success result have | 
| 10592 | 98 | "\<exists>ts\<in>list (length bs) (states G maxs maxr). | 
| 10812 
ead84e90bfeb
merged semilattice orders with <=' from Convert.thy (now defined in JVMType.thy)
 kleing parents: 
10657diff
changeset | 99 | ?start <=[JVMType.le G maxs maxr] ts \<and> | 
| 12516 | 100 | wt_step (JVMType.le G maxs maxr) Err (exec G maxs rT et bs) ts" | 
| 10592 | 101 | by (unfold is_bcv_def) auto | 
| 102 | then obtain phi' where | |
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 103 | phi': "phi' \<in> list (length bs) (states G maxs maxr)" and | 
| 10812 
ead84e90bfeb
merged semilattice orders with <=' from Convert.thy (now defined in JVMType.thy)
 kleing parents: 
10657diff
changeset | 104 | s: "?start <=[JVMType.le G maxs maxr] phi'" and | 
| 12516 | 105 | w: "wt_step (JVMType.le G maxs maxr) Err (exec G maxs rT et bs) phi'" | 
| 10592 | 106 | by blast | 
| 13066 | 107 | hence wt_err_step: | 
| 108 | "wt_err_step (sup_state_opt G) (exec G maxs rT et bs) phi'" | |
| 109 | by (simp add: wt_err_step_def exec_def JVM_le_Err_conv) | |
| 10592 | 110 | |
| 12516 | 111 | from s have le: "JVMType.le G maxs maxr (?start ! 0) (phi'!0)" | 
| 10592 | 112 | by (drule_tac p=0 in le_listD) (simp add: lesub_def)+ | 
| 113 | ||
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 114 | from phi' have l: "size phi' = size bs" by simp | 
| 12516 | 115 | with instrs w have "phi' ! 0 \<noteq> Err" by (unfold wt_step_def) simp | 
| 116 | with instrs l have phi0: "OK (map ok_val phi' ! 0) = phi' ! 0" | |
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 117 | by (clarsimp simp add: not_Err_eq) | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 118 | |
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 119 | from phi' have "check_types G maxs maxr phi'" by(simp add: check_types_def) | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 120 | also from w have "phi' = map OK (map ok_val phi')" | 
| 33639 
603320b93668
New list theorems; added map_map to simpset, this is the prefered direction; allow sorting by a key
 hoelzl parents: 
32960diff
changeset | 121 | by (auto simp add: wt_step_def not_Err_eq intro!: nth_equalityI) | 
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 122 | finally | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 123 | have check_types: | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 124 | "check_types G maxs maxr (map OK (map ok_val phi'))" . | 
| 10592 | 125 | |
| 12516 | 126 | from l bounded | 
| 13067 | 127 | have "bounded (\<lambda>pc. eff (bs!pc) G pc et) (length phi')" | 
| 13066 | 128 | by (simp add: exec_def check_bounded_is_bounded) | 
| 13067 | 129 | hence bounded': "bounded (exec G maxs rT et bs) (length bs)" | 
| 130 | by (auto intro: bounded_lift simp add: exec_def l) | |
| 13066 | 131 | with wt_err_step | 
| 132 | have "wt_app_eff (sup_state_opt G) (\<lambda>pc. app (bs!pc) G maxs rT pc et) | |
| 133 | (\<lambda>pc. eff (bs!pc) G pc et) (map ok_val phi')" | |
| 13067 | 134 | by (auto intro: wt_err_imp_wt_app_eff simp add: l exec_def) | 
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 135 | with instrs l le bounded bounded' check_types maxr | 
| 12516 | 136 | have "wt_method G C pTs rT maxs mxl bs et (map ok_val phi')" | 
| 13066 | 137 | apply (unfold wt_method_def wt_app_eff_def) | 
| 10592 | 138 | apply simp | 
| 139 | apply (rule conjI) | |
| 140 | apply (unfold wt_start_def) | |
| 141 | apply (rule JVM_le_convert [THEN iffD1]) | |
| 142 | apply (simp (no_asm) add: phi0) | |
| 143 | apply clarify | |
| 144 | apply (erule allE, erule impE, assumption) | |
| 145 | apply (elim conjE) | |
| 146 | apply (clarsimp simp add: lesub_def wt_instr_def) | |
| 13067 | 147 | apply (simp add: exec_def) | 
| 148 | apply (drule bounded_err_stepD, assumption+) | |
| 149 | apply blast | |
| 10592 | 150 | done | 
| 151 | ||
| 152 | thus ?thesis by blast | |
| 153 | qed | |
| 154 | ||
| 10651 | 155 | |
| 156 | theorem wt_kil_complete: | |
| 13224 | 157 | assumes wf: "wf_prog wf_mb G" | 
| 158 | assumes C: "is_class G C" | |
| 159 | assumes pTs: "set pTs \<subseteq> types G" | |
| 160 | ||
| 161 | assumes wtm: "wt_method G C pTs rT maxs mxl bs et phi" | |
| 162 | ||
| 163 | shows "wt_kil G C pTs rT maxs mxl et bs" | |
| 10651 | 164 | proof - | 
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 165 | let ?mxr = "1+size pTs+mxl" | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 166 | |
| 13224 | 167 | from wtm obtain | 
| 10651 | 168 | instrs: "0 < length bs" and | 
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 169 | len: "length phi = length bs" and | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 170 | bounded: "check_bounded bs et" and | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 171 | ck_types: "check_types G maxs ?mxr (map OK phi)" and | 
| 10651 | 172 | wt_start: "wt_start G C pTs mxl phi" and | 
| 173 | wt_ins: "\<forall>pc. pc < length bs \<longrightarrow> | |
| 12516 | 174 | wt_instr (bs ! pc) G rT phi maxs (length bs) et pc" | 
| 10651 | 175 | by (unfold wt_method_def) simp | 
| 176 | ||
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 177 | from ck_types len | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 178 | have istype_phi: | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 179 | "map OK phi \<in> list (length bs) (states G maxs (1+size pTs+mxl))" | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 180 | by (auto simp add: check_types_def intro!: listI) | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 181 | |
| 12516 | 182 | let ?eff = "\<lambda>pc. eff (bs!pc) G pc et" | 
| 183 | let ?app = "\<lambda>pc. app (bs!pc) G maxs rT pc et" | |
| 10651 | 184 | |
| 13066 | 185 | from bounded | 
| 186 | have bounded_exec: "bounded (exec G maxs rT et bs) (size bs)" | |
| 187 | by (unfold exec_def) (intro bounded_lift check_bounded_is_bounded) | |
| 12516 | 188 | |
| 10651 | 189 | from wt_ins | 
| 13066 | 190 | have "wt_app_eff (sup_state_opt G) ?app ?eff phi" | 
| 191 | apply (unfold wt_app_eff_def wt_instr_def lesub_def) | |
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 192 | apply (simp (no_asm) only: len) | 
| 10651 | 193 | apply blast | 
| 194 | done | |
| 13066 | 195 | with bounded_exec | 
| 196 | have "wt_err_step (sup_state_opt G) (err_step (size phi) ?app ?eff) (map OK phi)" | |
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 197 | by - (erule wt_app_eff_imp_wt_err,simp add: exec_def len) | 
| 13066 | 198 | hence wt_err: | 
| 199 | "wt_err_step (sup_state_opt G) (exec G maxs rT et bs) (map OK phi)" | |
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 200 | by (unfold exec_def) (simp add: len) | 
| 10651 | 201 | |
| 12516 | 202 | from wf bounded_exec | 
| 10651 | 203 | have is_bcv: | 
| 13224 | 204 | "is_bcv (JVMType.le G maxs ?mxr) Err (exec G maxs rT et bs) | 
| 205 | (size bs) (states G maxs ?mxr) (kiljvm G maxs ?mxr rT et bs)" | |
| 10651 | 206 | by (rule is_bcv_kiljvm) | 
| 207 | ||
| 208 | let ?start = "OK (Some ([],(OK (Class C))#((map OK pTs))@(replicate mxl Err))) | |
| 11701 
3d51fbf81c17
sane numerals (stage 1): added generic 1, removed 1' and 2 on nat,
 wenzelm parents: 
11299diff
changeset | 209 | #(replicate (size bs - 1) (OK None))" | 
| 10651 | 210 | |
| 13224 | 211 | from C pTs instrs | 
| 212 | have start: "?start \<in> list (length bs) (states G maxs ?mxr)" | |
| 213 | apply (unfold JVM_states_unfold) | |
| 214 | apply (rule listI) | |
| 215 | apply (auto intro!: list_appendI dest!: in_set_replicate) | |
| 216 | apply force | |
| 217 | done | |
| 10651 | 218 | |
| 12516 | 219 | let ?phi = "map OK phi" | 
| 13224 | 220 | have less_phi: "?start <=[JVMType.le G maxs ?mxr] ?phi" | 
| 10657 | 221 | proof - | 
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 222 | from len instrs | 
| 12516 | 223 | have "length ?start = length (map OK phi)" by simp | 
| 224 | moreover | |
| 10657 | 225 |     { fix n
 | 
| 226 | from wt_start | |
| 227 | have "G \<turnstile> ok_val (?start!0) <=' phi!0" | |
| 228 | by (simp add: wt_start_def) | |
| 229 | moreover | |
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 230 | from instrs len | 
| 10657 | 231 | have "0 < length phi" by simp | 
| 232 | ultimately | |
| 13224 | 233 | have "JVMType.le G maxs ?mxr (?start!0) (?phi!0)" | 
| 10657 | 234 | by (simp add: JVM_le_Err_conv Err.le_def lesub_def) | 
| 235 | moreover | |
| 236 |       { fix n'
 | |
| 13224 | 237 | have "JVMType.le G maxs ?mxr (OK None) (?phi!n)" | 
| 10657 | 238 | by (auto simp add: JVM_le_Err_conv Err.le_def lesub_def | 
| 239 | split: err.splits) | |
| 13006 | 240 | hence "\<lbrakk> n = Suc n'; n < length ?start \<rbrakk> | 
| 13224 | 241 | \<Longrightarrow> JVMType.le G maxs ?mxr (?start!n) (?phi!n)" | 
| 10657 | 242 | by simp | 
| 243 | } | |
| 244 | ultimately | |
| 13224 | 245 | have "n < length ?start \<Longrightarrow> (?start!n) <=_(JVMType.le G maxs ?mxr) (?phi!n)" | 
| 12516 | 246 | by (unfold lesub_def) (cases n, blast+) | 
| 247 | } | |
| 248 | ultimately show ?thesis by (rule le_listI) | |
| 10657 | 249 | qed | 
| 10651 | 250 | |
| 13066 | 251 | from wt_err | 
| 13224 | 252 | have "wt_step (JVMType.le G maxs ?mxr) Err (exec G maxs rT et bs) ?phi" | 
| 13066 | 253 | by (simp add: wt_err_step_def JVM_le_Err_conv) | 
| 12516 | 254 | with start istype_phi less_phi is_bcv | 
| 13224 | 255 | have "\<forall>p. p < length bs \<longrightarrow> kiljvm G maxs ?mxr rT et bs ?start ! p \<noteq> Err" | 
| 12516 | 256 | by (unfold is_bcv_def) auto | 
| 13066 | 257 | with bounded instrs | 
| 12516 | 258 | show "wt_kil G C pTs rT maxs mxl et bs" by (unfold wt_kil_def) simp | 
| 259 | qed | |
| 10651 | 260 | |
| 10637 | 261 | |
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 262 | theorem jvm_kildall_sound_complete: | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 263 | "wt_jvm_prog_kildall G = (\<exists>Phi. wt_jvm_prog G Phi)" | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 264 | proof | 
| 12516 | 265 | let ?Phi = "\<lambda>C sig. let (C,rT,(maxs,maxl,ins,et)) = the (method (G,C) sig) in | 
| 266 | SOME phi. wt_method G C (snd sig) rT maxs maxl ins et phi" | |
| 13224 | 267 | |
| 268 | assume "wt_jvm_prog_kildall G" | |
| 269 | hence "wt_jvm_prog G ?Phi" | |
| 270 | apply (unfold wt_jvm_prog_def wt_jvm_prog_kildall_def) | |
| 271 | apply (erule jvm_prog_lift) | |
| 272 | apply (auto dest!: wt_kil_correct intro: someI) | |
| 10637 | 273 | done | 
| 13224 | 274 | thus "\<exists>Phi. wt_jvm_prog G Phi" by fast | 
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 275 | next | 
| 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 276 | assume "\<exists>Phi. wt_jvm_prog G Phi" | 
| 13224 | 277 | thus "wt_jvm_prog_kildall G" | 
| 278 | apply (clarify) | |
| 279 | apply (unfold wt_jvm_prog_def wt_jvm_prog_kildall_def) | |
| 280 | apply (erule jvm_prog_lift) | |
| 281 | apply (auto intro: wt_kil_complete) | |
| 13214 
2aa33ed5f526
wt_method now checks bounded+types ==> wt_kildall <=> wt_method
 kleing parents: 
13074diff
changeset | 282 | done | 
| 10637 | 283 | qed | 
| 284 | ||
| 10592 | 285 | end |