author | kleing |
Sun, 24 Mar 2002 14:06:21 +0100 | |
changeset 13066 | b57d926d1de2 |
parent 13006 | 51c5f3f11d16 |
child 13067 | a59af3a83c61 |
permissions | -rw-r--r-- |
12516 | 1 |
(* Title: HOL/MicroJava/BV/JVM.thy |
10592 | 2 |
ID: $Id$ |
12516 | 3 |
Author: Tobias Nipkow, Gerwin Klein |
10592 | 4 |
Copyright 2000 TUM |
5 |
*) |
|
6 |
||
12911 | 7 |
header {* \isaheader{Kildall for the JVM}\label{sec:JVM} *} |
10592 | 8 |
|
13066 | 9 |
theory JVM = Kildall_Lift + JVMType + EffectMono + BVSpec: |
10 |
||
10592 | 11 |
|
12 |
constdefs |
|
13066 | 13 |
check_bounded :: "instr list \<Rightarrow> exception_table \<Rightarrow> bool" |
14 |
"check_bounded ins et \<equiv> (\<forall>pc < length ins. \<forall>pc' \<in> set (succs (ins!pc) pc). pc' < length ins) \<and> |
|
15 |
(\<forall>e \<in> set et. fst (snd (snd e)) < length ins)" |
|
16 |
||
12516 | 17 |
exec :: "jvm_prog \<Rightarrow> nat \<Rightarrow> ty \<Rightarrow> exception_table \<Rightarrow> instr list \<Rightarrow> state step_type" |
18 |
"exec G maxs rT et bs == |
|
13066 | 19 |
err_step (size bs) (\<lambda>pc. app (bs!pc) G maxs rT pc et) (\<lambda>pc. eff (bs!pc) G pc et)" |
10592 | 20 |
|
13006 | 21 |
kiljvm :: "jvm_prog \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> ty \<Rightarrow> exception_table \<Rightarrow> |
22 |
instr list \<Rightarrow> state list \<Rightarrow> state list" |
|
12516 | 23 |
"kiljvm G maxs maxr rT et bs == |
24 |
kildall (JVMType.le G maxs maxr) (JVMType.sup G maxs maxr) (exec G maxs rT et bs)" |
|
10592 | 25 |
|
12516 | 26 |
wt_kil :: "jvm_prog \<Rightarrow> cname \<Rightarrow> ty list \<Rightarrow> ty \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> |
27 |
exception_table \<Rightarrow> instr list \<Rightarrow> bool" |
|
28 |
"wt_kil G C pTs rT mxs mxl et ins == |
|
13066 | 29 |
check_bounded ins et \<and> 0 < size ins \<and> |
10637 | 30 |
(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:
11299
diff
changeset
|
31 |
start = OK first#(replicate (size ins - 1) (OK None)); |
12516 | 32 |
result = kiljvm G mxs (1+size pTs+mxl) rT et ins start |
10637 | 33 |
in \<forall>n < size ins. result!n \<noteq> Err)" |
34 |
||
13006 | 35 |
wt_jvm_prog_kildall :: "jvm_prog \<Rightarrow> bool" |
10637 | 36 |
"wt_jvm_prog_kildall G == |
12516 | 37 |
wf_prog (\<lambda>G C (sig,rT,(maxs,maxl,b,et)). wt_kil G C (snd sig) rT maxs maxl et b) G" |
10592 | 38 |
|
39 |
||
13066 | 40 |
|
41 |
text {* |
|
42 |
Executability of @{term check_bounded}: |
|
43 |
*} |
|
44 |
consts |
|
45 |
list_all'_rec :: "('a \<Rightarrow> nat \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> 'a list \<Rightarrow> bool" |
|
46 |
primrec |
|
47 |
"list_all'_rec P n [] = True" |
|
48 |
"list_all'_rec P n (x#xs) = (P x n \<and> list_all'_rec P (Suc n) xs)" |
|
49 |
||
50 |
constdefs |
|
51 |
list_all' :: "('a \<Rightarrow> nat \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> bool" |
|
52 |
"list_all' P xs \<equiv> list_all'_rec P 0 xs" |
|
53 |
||
54 |
lemma list_all'_rec: |
|
55 |
"\<And>n. list_all'_rec P n xs = (\<forall>p < size xs. P (xs!p) (p+n))" |
|
56 |
apply (induct xs) |
|
57 |
apply auto |
|
58 |
apply (case_tac p) |
|
59 |
apply auto |
|
60 |
done |
|
61 |
||
62 |
lemma list_all' [iff]: |
|
63 |
"list_all' P xs = (\<forall>n < size xs. P (xs!n) n)" |
|
64 |
by (unfold list_all'_def) (simp add: list_all'_rec) |
|
65 |
||
66 |
lemma list_all_ball: |
|
67 |
"list_all P xs = (\<forall>x \<in> set xs. P x)" |
|
68 |
by (induct xs) auto |
|
69 |
||
70 |
lemma [code]: |
|
71 |
"check_bounded ins et = |
|
72 |
(list_all' (\<lambda>i pc. list_all (\<lambda>pc'. pc' < length ins) (succs i pc)) ins \<and> |
|
73 |
list_all (\<lambda>e. fst (snd (snd e)) < length ins) et)" |
|
74 |
by (simp add: list_all_ball check_bounded_def) |
|
75 |
||
76 |
text {* |
|
77 |
Lemmas for Kildall instantiation |
|
78 |
*} |
|
79 |
||
80 |
lemma check_bounded_is_bounded: |
|
81 |
"check_bounded ins et \<Longrightarrow> bounded (\<lambda>pc. eff (ins!pc) G pc et) (length ins)" |
|
82 |
apply (unfold bounded_def eff_def) |
|
83 |
apply clarify |
|
84 |
apply simp |
|
85 |
apply (unfold check_bounded_def) |
|
86 |
apply clarify |
|
87 |
apply (erule disjE) |
|
88 |
apply blast |
|
89 |
apply (erule allE, erule impE, assumption) |
|
90 |
apply (unfold xcpt_eff_def) |
|
91 |
apply clarsimp |
|
92 |
apply (drule xcpt_names_in_et) |
|
93 |
apply clarify |
|
94 |
apply (drule bspec, assumption) |
|
95 |
apply simp |
|
96 |
done |
|
97 |
||
98 |
||
10592 | 99 |
lemma special_ex_swap_lemma [iff]: |
100 |
"(? X. (? n. X = A n & P n) & Q X) = (? n. Q(A n) & P n)" |
|
101 |
by blast |
|
102 |
||
10630 | 103 |
lemmas [iff del] = not_None_eq |
104 |
||
12516 | 105 |
lemma non_empty_succs: "succs i pc \<noteq> []" |
106 |
by (cases i) auto |
|
107 |
||
108 |
lemma non_empty: |
|
109 |
"non_empty (\<lambda>pc. eff (bs!pc) G pc et)" |
|
110 |
by (simp add: non_empty_def eff_def non_empty_succs) |
|
111 |
||
10592 | 112 |
theorem exec_pres_type: |
13006 | 113 |
"wf_prog wf_mb S \<Longrightarrow> |
12516 | 114 |
pres_type (exec S maxs rT et bs) (size bs) (states S maxs maxr)" |
115 |
apply (unfold exec_def JVM_states_unfold) |
|
116 |
apply (rule pres_type_lift) |
|
117 |
apply clarify |
|
118 |
apply (case_tac s) |
|
119 |
apply simp |
|
120 |
apply (drule effNone) |
|
121 |
apply simp |
|
122 |
apply (simp add: eff_def xcpt_eff_def norm_eff_def) |
|
123 |
apply (case_tac "bs!p") |
|
124 |
||
125 |
apply (clarsimp simp add: not_Err_eq) |
|
126 |
apply (drule listE_nth_in, assumption) |
|
127 |
apply fastsimp |
|
128 |
||
129 |
apply (fastsimp simp add: not_None_eq) |
|
130 |
||
131 |
apply (fastsimp simp add: not_None_eq typeof_empty_is_type) |
|
132 |
||
133 |
apply clarsimp |
|
134 |
apply (erule disjE) |
|
135 |
apply fastsimp |
|
136 |
apply clarsimp |
|
137 |
apply (rule_tac x="1" in exI) |
|
138 |
apply fastsimp |
|
10592 | 139 |
|
12516 | 140 |
apply clarsimp |
141 |
apply (erule disjE) |
|
142 |
apply (fastsimp dest: field_fields fields_is_type) |
|
12951 | 143 |
apply (simp add: match_some_entry split: split_if_asm) |
12516 | 144 |
apply (rule_tac x=1 in exI) |
145 |
apply fastsimp |
|
146 |
||
147 |
apply clarsimp |
|
148 |
apply (erule disjE) |
|
149 |
apply fastsimp |
|
12951 | 150 |
apply (simp add: match_some_entry split: split_if_asm) |
12516 | 151 |
apply (rule_tac x=1 in exI) |
152 |
apply fastsimp |
|
153 |
||
154 |
apply clarsimp |
|
155 |
apply (erule disjE) |
|
156 |
apply fastsimp |
|
157 |
apply clarsimp |
|
158 |
apply (rule_tac x=1 in exI) |
|
159 |
apply fastsimp |
|
160 |
||
161 |
defer |
|
162 |
||
163 |
apply fastsimp |
|
164 |
apply fastsimp |
|
165 |
||
166 |
apply clarsimp |
|
167 |
apply (rule_tac x="n'+2" in exI) |
|
168 |
apply simp |
|
169 |
apply (drule listE_length)+ |
|
170 |
apply fastsimp |
|
10592 | 171 |
|
12516 | 172 |
apply clarsimp |
173 |
apply (rule_tac x="Suc (Suc (Suc (length ST)))" in exI) |
|
174 |
apply simp |
|
175 |
apply (drule listE_length)+ |
|
176 |
apply fastsimp |
|
177 |
||
178 |
apply clarsimp |
|
179 |
apply (rule_tac x="Suc (Suc (Suc (Suc (length ST))))" in exI) |
|
180 |
apply simp |
|
181 |
apply (drule listE_length)+ |
|
182 |
apply fastsimp |
|
183 |
||
184 |
apply fastsimp |
|
185 |
apply fastsimp |
|
186 |
apply fastsimp |
|
187 |
apply fastsimp |
|
10592 | 188 |
|
12516 | 189 |
apply clarsimp |
190 |
apply (erule disjE) |
|
191 |
apply fastsimp |
|
192 |
apply clarsimp |
|
193 |
apply (rule_tac x=1 in exI) |
|
194 |
apply fastsimp |
|
195 |
||
196 |
apply (erule disjE) |
|
197 |
apply (clarsimp simp add: Un_subset_iff) |
|
198 |
apply (drule method_wf_mdecl, assumption+) |
|
199 |
apply (clarsimp simp add: wf_mdecl_def wf_mhead_def) |
|
200 |
apply fastsimp |
|
201 |
apply clarsimp |
|
202 |
apply (rule_tac x=1 in exI) |
|
203 |
apply fastsimp |
|
204 |
done |
|
10630 | 205 |
|
206 |
lemmas [iff] = not_None_eq |
|
207 |
||
12516 | 208 |
|
209 |
lemma sup_state_opt_unfold: |
|
210 |
"sup_state_opt G \<equiv> Opt.le (Product.le (Listn.le (subtype G)) (Listn.le (Err.le (subtype G))))" |
|
211 |
by (simp add: sup_state_opt_def sup_state_def sup_loc_def sup_ty_opt_def) |
|
212 |
||
213 |
constdefs |
|
214 |
opt_states :: "'c prog \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> (ty list \<times> ty err list) option set" |
|
215 |
"opt_states G maxs maxr \<equiv> opt (\<Union>{list n (types G) |n. n \<le> maxs} \<times> list maxr (err (types G)))" |
|
216 |
||
217 |
lemma app_mono: |
|
218 |
"app_mono (sup_state_opt G) (\<lambda>pc. app (bs!pc) G maxs rT pc et) (length bs) (opt_states G maxs maxr)" |
|
219 |
by (unfold app_mono_def lesub_def) (blast intro: EffectMono.app_mono) |
|
13066 | 220 |
|
12516 | 221 |
|
13066 | 222 |
lemma lesubstep_type_simple: |
223 |
"a <=[Product.le (op =) r] b \<Longrightarrow> a <=|r| b" |
|
224 |
apply (unfold lesubstep_type_def) |
|
225 |
apply clarify |
|
226 |
apply (simp add: set_conv_nth) |
|
227 |
apply clarify |
|
228 |
apply (drule le_listD, assumption) |
|
229 |
apply (clarsimp simp add: lesub_def Product.le_def) |
|
230 |
apply (rule exI) |
|
231 |
apply (rule conjI) |
|
232 |
apply (rule exI) |
|
233 |
apply (rule conjI) |
|
234 |
apply (rule sym) |
|
235 |
apply assumption |
|
236 |
apply assumption |
|
237 |
apply assumption |
|
12516 | 238 |
done |
239 |
||
13066 | 240 |
|
12516 | 241 |
lemma eff_mono: |
242 |
"\<lbrakk>p < length bs; s <=_(sup_state_opt G) t; app (bs!p) G maxs rT pc et t\<rbrakk> |
|
243 |
\<Longrightarrow> eff (bs!p) G p et s <=|sup_state_opt G| eff (bs!p) G p et t" |
|
244 |
apply (unfold eff_def) |
|
13066 | 245 |
apply (rule lesubstep_type_simple) |
12516 | 246 |
apply (rule le_list_appendI) |
247 |
apply (simp add: norm_eff_def) |
|
248 |
apply (rule le_listI) |
|
249 |
apply simp |
|
250 |
apply simp |
|
251 |
apply (simp add: lesub_def) |
|
252 |
apply (case_tac s) |
|
253 |
apply simp |
|
254 |
apply (simp del: split_paired_All split_paired_Ex) |
|
255 |
apply (elim exE conjE) |
|
256 |
apply simp |
|
257 |
apply (drule eff'_mono, assumption) |
|
258 |
apply assumption |
|
259 |
apply (simp add: xcpt_eff_def) |
|
260 |
apply (rule le_listI) |
|
261 |
apply simp |
|
262 |
apply simp |
|
263 |
apply (simp add: lesub_def) |
|
264 |
apply (case_tac s) |
|
265 |
apply simp |
|
266 |
apply simp |
|
267 |
apply (case_tac t) |
|
268 |
apply simp |
|
269 |
apply (clarsimp simp add: sup_state_conv) |
|
270 |
done |
|
271 |
||
272 |
lemma order_sup_state_opt: |
|
273 |
"wf_prog wf_mb G \<Longrightarrow> order (sup_state_opt G)" |
|
274 |
by (unfold sup_state_opt_unfold) (blast dest: acyclic_subcls1 order_widen) |
|
10630 | 275 |
|
10592 | 276 |
theorem exec_mono: |
13066 | 277 |
"wf_prog wf_mb G \<Longrightarrow> bounded (exec G maxs rT et bs) (size bs) \<Longrightarrow> |
12516 | 278 |
mono (JVMType.le G maxs maxr) (exec G maxs rT et bs) (size bs) (states G maxs maxr)" |
279 |
apply (unfold exec_def JVM_le_unfold JVM_states_unfold) |
|
280 |
apply (rule mono_lift) |
|
281 |
apply (fold sup_state_opt_unfold opt_states_def) |
|
282 |
apply (erule order_sup_state_opt) |
|
13066 | 283 |
apply (rule app_mono) |
284 |
apply assumption |
|
10592 | 285 |
apply clarify |
12516 | 286 |
apply (rule eff_mono) |
287 |
apply assumption+ |
|
10592 | 288 |
done |
289 |
||
290 |
theorem semilat_JVM_slI: |
|
13006 | 291 |
"wf_prog wf_mb G \<Longrightarrow> semilat (JVMType.sl G maxs maxr)" |
10812
ead84e90bfeb
merged semilattice orders with <=' from Convert.thy (now defined in JVMType.thy)
kleing
parents:
10657
diff
changeset
|
292 |
apply (unfold JVMType.sl_def stk_esl_def reg_sl_def) |
10592 | 293 |
apply (rule semilat_opt) |
294 |
apply (rule err_semilat_Product_esl) |
|
295 |
apply (rule err_semilat_upto_esl) |
|
296 |
apply (rule err_semilat_JType_esl, assumption+) |
|
297 |
apply (rule err_semilat_eslI) |
|
298 |
apply (rule semilat_Listn_sl) |
|
299 |
apply (rule err_semilat_JType_esl, assumption+) |
|
300 |
done |
|
301 |
||
302 |
lemma sl_triple_conv: |
|
10812
ead84e90bfeb
merged semilattice orders with <=' from Convert.thy (now defined in JVMType.thy)
kleing
parents:
10657
diff
changeset
|
303 |
"JVMType.sl G maxs maxr == |
ead84e90bfeb
merged semilattice orders with <=' from Convert.thy (now defined in JVMType.thy)
kleing
parents:
10657
diff
changeset
|
304 |
(states G maxs maxr, JVMType.le G maxs maxr, JVMType.sup G maxs maxr)" |
ead84e90bfeb
merged semilattice orders with <=' from Convert.thy (now defined in JVMType.thy)
kleing
parents:
10657
diff
changeset
|
305 |
by (simp (no_asm) add: states_def JVMType.le_def JVMType.sup_def) |
10592 | 306 |
|
307 |
||
308 |
theorem is_bcv_kiljvm: |
|
13066 | 309 |
"\<lbrakk> wf_prog wf_mb G; bounded (exec G maxs rT et bs) (size bs) \<rbrakk> \<Longrightarrow> |
12516 | 310 |
is_bcv (JVMType.le G maxs maxr) Err (exec G maxs rT et bs) |
311 |
(size bs) (states G maxs maxr) (kiljvm G maxs maxr rT et bs)" |
|
10592 | 312 |
apply (unfold kiljvm_def sl_triple_conv) |
313 |
apply (rule is_bcv_kildall) |
|
314 |
apply (simp (no_asm) add: sl_triple_conv [symmetric]) |
|
315 |
apply (force intro!: semilat_JVM_slI dest: wf_acyclic simp add: symmetric sl_triple_conv) |
|
316 |
apply (simp (no_asm) add: JVM_le_unfold) |
|
317 |
apply (blast intro!: order_widen wf_converse_subcls1_impl_acc_subtype |
|
318 |
dest: wf_subcls1 wf_acyclic) |
|
319 |
apply (simp add: JVM_le_unfold) |
|
320 |
apply (erule exec_pres_type) |
|
13066 | 321 |
apply assumption |
322 |
apply (erule exec_mono, assumption) |
|
10592 | 323 |
done |
324 |
||
10637 | 325 |
|
326 |
theorem wt_kil_correct: |
|
13006 | 327 |
"\<lbrakk> wt_kil G C pTs rT maxs mxl et bs; wf_prog wf_mb G; |
328 |
is_class G C; \<forall>x \<in> set pTs. is_type G x \<rbrakk> |
|
329 |
\<Longrightarrow> \<exists>phi. wt_method G C pTs rT maxs mxl bs et phi" |
|
10592 | 330 |
proof - |
331 |
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:
11299
diff
changeset
|
332 |
#(replicate (size bs - 1) (OK None))" |
10592 | 333 |
|
10637 | 334 |
assume wf: "wf_prog wf_mb G" |
335 |
assume isclass: "is_class G C" |
|
336 |
assume istype: "\<forall>x \<in> set pTs. is_type G x" |
|
337 |
||
12516 | 338 |
assume "wt_kil G C pTs rT maxs mxl et bs" |
10637 | 339 |
then obtain maxr r where |
13066 | 340 |
bounded: "check_bounded bs et" and |
12516 | 341 |
result: "r = kiljvm G maxs maxr rT et bs ?start" and |
10637 | 342 |
success: "\<forall>n < size bs. r!n \<noteq> Err" and |
343 |
instrs: "0 < size bs" and |
|
344 |
maxr: "maxr = Suc (length pTs + mxl)" |
|
345 |
by (unfold wt_kil_def) simp |
|
10592 | 346 |
|
13066 | 347 |
from bounded have "bounded (exec G maxs rT et bs) (size bs)" |
348 |
by (unfold exec_def) (intro bounded_lift check_bounded_is_bounded) |
|
349 |
with wf have bcv: |
|
12516 | 350 |
"is_bcv (JVMType.le G maxs maxr) Err (exec G maxs rT et bs) |
13066 | 351 |
(size bs) (states G maxs maxr) (kiljvm G maxs maxr rT et bs)" |
10592 | 352 |
by (rule is_bcv_kiljvm) |
13066 | 353 |
|
12516 | 354 |
{ fix l x have "set (replicate l x) \<subseteq> {x}" by (cases "0 < l") simp+ |
10592 | 355 |
} note subset_replicate = this |
12516 | 356 |
from istype have "set pTs \<subseteq> types G" by auto |
357 |
hence "OK ` set pTs \<subseteq> err (types G)" by auto |
|
10592 | 358 |
with instrs maxr isclass |
359 |
have "?start \<in> list (length bs) (states G maxs maxr)" |
|
360 |
apply (unfold list_def JVM_states_unfold) |
|
361 |
apply simp |
|
362 |
apply (rule conjI) |
|
363 |
apply (simp add: Un_subset_iff) |
|
364 |
apply (rule_tac B = "{Err}" in subset_trans) |
|
365 |
apply (simp add: subset_replicate) |
|
366 |
apply simp |
|
367 |
apply (rule_tac B = "{OK None}" in subset_trans) |
|
368 |
apply (simp add: subset_replicate) |
|
369 |
apply simp |
|
370 |
done |
|
12516 | 371 |
with bcv success result have |
10592 | 372 |
"\<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:
10657
diff
changeset
|
373 |
?start <=[JVMType.le G maxs maxr] ts \<and> |
12516 | 374 |
wt_step (JVMType.le G maxs maxr) Err (exec G maxs rT et bs) ts" |
10592 | 375 |
by (unfold is_bcv_def) auto |
376 |
then obtain phi' where |
|
377 |
l: "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:
10657
diff
changeset
|
378 |
s: "?start <=[JVMType.le G maxs maxr] phi'" and |
12516 | 379 |
w: "wt_step (JVMType.le G maxs maxr) Err (exec G maxs rT et bs) phi'" |
10592 | 380 |
by blast |
13066 | 381 |
hence wt_err_step: |
382 |
"wt_err_step (sup_state_opt G) (exec G maxs rT et bs) phi'" |
|
383 |
by (simp add: wt_err_step_def exec_def JVM_le_Err_conv) |
|
10592 | 384 |
|
12516 | 385 |
from s have le: "JVMType.le G maxs maxr (?start ! 0) (phi'!0)" |
10592 | 386 |
by (drule_tac p=0 in le_listD) (simp add: lesub_def)+ |
387 |
||
12516 | 388 |
from l have l: "size phi' = size bs" by simp |
389 |
with instrs w have "phi' ! 0 \<noteq> Err" by (unfold wt_step_def) simp |
|
390 |
with instrs l have phi0: "OK (map ok_val phi' ! 0) = phi' ! 0" |
|
10812
ead84e90bfeb
merged semilattice orders with <=' from Convert.thy (now defined in JVMType.thy)
kleing
parents:
10657
diff
changeset
|
391 |
by (clarsimp simp add: not_Err_eq) |
10592 | 392 |
|
12516 | 393 |
from l bounded |
394 |
have bounded': "bounded (\<lambda>pc. eff (bs!pc) G pc et) (length phi')" |
|
13066 | 395 |
by (simp add: exec_def check_bounded_is_bounded) |
396 |
with wt_err_step |
|
397 |
have "wt_app_eff (sup_state_opt G) (\<lambda>pc. app (bs!pc) G maxs rT pc et) |
|
398 |
(\<lambda>pc. eff (bs!pc) G pc et) (map ok_val phi')" |
|
399 |
by (auto intro: wt_err_imp_wt_app_eff simp add: l exec_def non_empty) |
|
12516 | 400 |
with instrs l le bounded' |
401 |
have "wt_method G C pTs rT maxs mxl bs et (map ok_val phi')" |
|
13066 | 402 |
apply (unfold wt_method_def wt_app_eff_def) |
10592 | 403 |
apply simp |
404 |
apply (rule conjI) |
|
405 |
apply (unfold wt_start_def) |
|
406 |
apply (rule JVM_le_convert [THEN iffD1]) |
|
407 |
apply (simp (no_asm) add: phi0) |
|
408 |
apply clarify |
|
409 |
apply (erule allE, erule impE, assumption) |
|
410 |
apply (elim conjE) |
|
411 |
apply (clarsimp simp add: lesub_def wt_instr_def) |
|
412 |
apply (unfold bounded_def) |
|
413 |
apply blast |
|
414 |
done |
|
415 |
||
416 |
thus ?thesis by blast |
|
417 |
qed |
|
418 |
||
10651 | 419 |
|
420 |
theorem wt_kil_complete: |
|
13006 | 421 |
"\<lbrakk> wt_method G C pTs rT maxs mxl bs et phi; wf_prog wf_mb G; |
13066 | 422 |
check_bounded bs et; length phi = length bs; is_class G C; |
423 |
\<forall>x \<in> set pTs. is_type G x; |
|
13006 | 424 |
map OK phi \<in> list (length bs) (states G maxs (1+size pTs+mxl)) \<rbrakk> |
425 |
\<Longrightarrow> wt_kil G C pTs rT maxs mxl et bs" |
|
10651 | 426 |
proof - |
12516 | 427 |
assume wf: "wf_prog wf_mb G" |
10651 | 428 |
assume isclass: "is_class G C" |
12516 | 429 |
assume istype: "\<forall>x \<in> set pTs. is_type G x" |
430 |
assume length: "length phi = length bs" |
|
431 |
assume istype_phi: "map OK phi \<in> list (length bs) (states G maxs (1+size pTs+mxl))" |
|
13066 | 432 |
assume bounded: "check_bounded bs et" |
10651 | 433 |
|
12516 | 434 |
assume "wt_method G C pTs rT maxs mxl bs et phi" |
10651 | 435 |
then obtain |
436 |
instrs: "0 < length bs" and |
|
437 |
wt_start: "wt_start G C pTs mxl phi" and |
|
438 |
wt_ins: "\<forall>pc. pc < length bs \<longrightarrow> |
|
12516 | 439 |
wt_instr (bs ! pc) G rT phi maxs (length bs) et pc" |
10651 | 440 |
by (unfold wt_method_def) simp |
441 |
||
12516 | 442 |
let ?eff = "\<lambda>pc. eff (bs!pc) G pc et" |
443 |
let ?app = "\<lambda>pc. app (bs!pc) G maxs rT pc et" |
|
10651 | 444 |
|
13066 | 445 |
from bounded |
446 |
have bounded_exec: "bounded (exec G maxs rT et bs) (size bs)" |
|
447 |
by (unfold exec_def) (intro bounded_lift check_bounded_is_bounded) |
|
12516 | 448 |
|
10651 | 449 |
from wt_ins |
13066 | 450 |
have "wt_app_eff (sup_state_opt G) ?app ?eff phi" |
451 |
apply (unfold wt_app_eff_def wt_instr_def lesub_def) |
|
10651 | 452 |
apply (simp (no_asm) only: length) |
453 |
apply blast |
|
454 |
done |
|
13066 | 455 |
with bounded_exec |
456 |
have "wt_err_step (sup_state_opt G) (err_step (size phi) ?app ?eff) (map OK phi)" |
|
457 |
by - (erule wt_app_eff_imp_wt_err,simp add: exec_def length) |
|
458 |
hence wt_err: |
|
459 |
"wt_err_step (sup_state_opt G) (exec G maxs rT et bs) (map OK phi)" |
|
460 |
by (unfold exec_def) (simp add: length) |
|
10651 | 461 |
|
462 |
let ?maxr = "1+size pTs+mxl" |
|
12516 | 463 |
from wf bounded_exec |
10651 | 464 |
have is_bcv: |
12516 | 465 |
"is_bcv (JVMType.le G maxs ?maxr) Err (exec G maxs rT et bs) |
466 |
(size bs) (states G maxs ?maxr) (kiljvm G maxs ?maxr rT et bs)" |
|
10651 | 467 |
by (rule is_bcv_kiljvm) |
468 |
||
469 |
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:
11299
diff
changeset
|
470 |
#(replicate (size bs - 1) (OK None))" |
10651 | 471 |
|
12516 | 472 |
{ fix l x have "set (replicate l x) \<subseteq> {x}" by (cases "0 < l") simp+ |
10651 | 473 |
} note subset_replicate = this |
474 |
||
12516 | 475 |
from istype have "set pTs \<subseteq> types G" by auto |
476 |
hence "OK ` set pTs \<subseteq> err (types G)" by auto |
|
477 |
with instrs isclass have start: |
|
10651 | 478 |
"?start \<in> list (length bs) (states G maxs ?maxr)" |
479 |
apply (unfold list_def JVM_states_unfold) |
|
480 |
apply simp |
|
481 |
apply (rule conjI) |
|
482 |
apply (simp add: Un_subset_iff) |
|
483 |
apply (rule_tac B = "{Err}" in subset_trans) |
|
484 |
apply (simp add: subset_replicate) |
|
485 |
apply simp |
|
486 |
apply (rule_tac B = "{OK None}" in subset_trans) |
|
487 |
apply (simp add: subset_replicate) |
|
488 |
apply simp |
|
489 |
done |
|
490 |
||
12516 | 491 |
let ?phi = "map OK phi" |
492 |
have less_phi: "?start <=[JVMType.le G maxs ?maxr] ?phi" |
|
10657 | 493 |
proof - |
12516 | 494 |
from length instrs |
495 |
have "length ?start = length (map OK phi)" by simp |
|
496 |
moreover |
|
10657 | 497 |
{ fix n |
498 |
from wt_start |
|
499 |
have "G \<turnstile> ok_val (?start!0) <=' phi!0" |
|
500 |
by (simp add: wt_start_def) |
|
501 |
moreover |
|
502 |
from instrs length |
|
503 |
have "0 < length phi" by simp |
|
504 |
ultimately |
|
12516 | 505 |
have "JVMType.le G maxs ?maxr (?start!0) (?phi!0)" |
10657 | 506 |
by (simp add: JVM_le_Err_conv Err.le_def lesub_def) |
507 |
moreover |
|
508 |
{ fix n' |
|
12516 | 509 |
have "JVMType.le G maxs ?maxr (OK None) (?phi!n)" |
10657 | 510 |
by (auto simp add: JVM_le_Err_conv Err.le_def lesub_def |
511 |
split: err.splits) |
|
13006 | 512 |
hence "\<lbrakk> n = Suc n'; n < length ?start \<rbrakk> |
513 |
\<Longrightarrow> JVMType.le G maxs ?maxr (?start!n) (?phi!n)" |
|
10657 | 514 |
by simp |
515 |
} |
|
516 |
ultimately |
|
13006 | 517 |
have "n < length ?start \<Longrightarrow> (?start!n) <=_(JVMType.le G maxs ?maxr) (?phi!n)" |
12516 | 518 |
by (unfold lesub_def) (cases n, blast+) |
519 |
} |
|
520 |
ultimately show ?thesis by (rule le_listI) |
|
10657 | 521 |
qed |
10651 | 522 |
|
13066 | 523 |
from wt_err |
12516 | 524 |
have "wt_step (JVMType.le G maxs ?maxr) Err (exec G maxs rT et bs) ?phi" |
13066 | 525 |
by (simp add: wt_err_step_def JVM_le_Err_conv) |
12516 | 526 |
with start istype_phi less_phi is_bcv |
527 |
have "\<forall>p. p < length bs \<longrightarrow> kiljvm G maxs ?maxr rT et bs ?start ! p \<noteq> Err" |
|
528 |
by (unfold is_bcv_def) auto |
|
13066 | 529 |
with bounded instrs |
12516 | 530 |
show "wt_kil G C pTs rT maxs mxl et bs" by (unfold wt_kil_def) simp |
531 |
qed |
|
532 |
text {* |
|
533 |
The above theorem @{text wt_kil_complete} is all nice'n shiny except |
|
534 |
for one assumption: @{term "map OK phi \<in> list (length bs) (states G maxs (1+size pTs+mxl))"} |
|
535 |
It does not hold for all @{text phi} that satisfy @{text wt_method}. |
|
10651 | 536 |
|
12516 | 537 |
The assumption states mainly that all entries in @{text phi} are legal |
538 |
types in the program context, that the stack size is bounded by @{text maxs}, |
|
539 |
and that the register sizes are exactly @{term "1+size pTs+mxl"}. |
|
540 |
The BV specification, i.e.~@{text wt_method}, only gives us this |
|
541 |
property for \emph{reachable} code. For unreachable code, |
|
542 |
e.g.~unused registers may contain arbitrary garbage. Even the stack |
|
543 |
and register sizes can be different from the rest of the program (as |
|
544 |
long as they are consistent inside each chunk of unreachable code). |
|
545 |
||
546 |
All is not lost, though: for each @{text phi} that satisfies |
|
547 |
@{text wt_method} there is a @{text phi'} that also satisfies |
|
548 |
@{text wt_method} and that additionally satisfies our assumption. |
|
549 |
The construction is quite easy: the entries for reachable code |
|
550 |
are the same in @{text phi} and @{text phi'}, the entries for |
|
551 |
unreachable code are all @{text None} in @{text phi'} (as it would |
|
552 |
be produced by Kildall's algorithm). |
|
10651 | 553 |
|
12516 | 554 |
Although this is proved easily by comment, it requires some more |
555 |
overhead (i.e.~talking about reachable instructions) if you try |
|
556 |
it the hard way. Thus it is missing here for the time being. |
|
557 |
||
558 |
The other direction (@{text wt_kil_correct}) can be lifted to |
|
559 |
programs without problems: |
|
560 |
*} |
|
10637 | 561 |
lemma is_type_pTs: |
13006 | 562 |
"\<lbrakk> wf_prog wf_mb G; (C,S,fs,mdecls) \<in> set G; (sig,rT,code) \<in> set mdecls; |
563 |
t \<in> set (snd sig) \<rbrakk> |
|
564 |
\<Longrightarrow> is_type G t" |
|
10637 | 565 |
proof - |
566 |
assume "wf_prog wf_mb G" |
|
567 |
"(C,S,fs,mdecls) \<in> set G" |
|
568 |
"(sig,rT,code) \<in> set mdecls" |
|
569 |
hence "wf_mdecl wf_mb G C (sig,rT,code)" |
|
570 |
by (unfold wf_prog_def wf_cdecl_def) auto |
|
571 |
hence "\<forall>t \<in> set (snd sig). is_type G t" |
|
572 |
by (unfold wf_mdecl_def wf_mhead_def) auto |
|
573 |
moreover |
|
574 |
assume "t \<in> set (snd sig)" |
|
575 |
ultimately |
|
576 |
show ?thesis by blast |
|
577 |
qed |
|
578 |
||
579 |
||
580 |
theorem jvm_kildall_correct: |
|
13006 | 581 |
"wt_jvm_prog_kildall G \<Longrightarrow> \<exists>Phi. wt_jvm_prog G Phi" |
10637 | 582 |
proof - |
583 |
assume wtk: "wt_jvm_prog_kildall G" |
|
584 |
||
585 |
then obtain wf_mb where |
|
586 |
wf: "wf_prog wf_mb G" |
|
587 |
by (auto simp add: wt_jvm_prog_kildall_def) |
|
588 |
||
12516 | 589 |
let ?Phi = "\<lambda>C sig. let (C,rT,(maxs,maxl,ins,et)) = the (method (G,C) sig) in |
590 |
SOME phi. wt_method G C (snd sig) rT maxs maxl ins et phi" |
|
10637 | 591 |
|
592 |
{ fix C S fs mdecls sig rT code |
|
593 |
assume "(C,S,fs,mdecls) \<in> set G" "(sig,rT,code) \<in> set mdecls" |
|
594 |
with wf |
|
595 |
have "method (G,C) sig = Some (C,rT,code) \<and> is_class G C \<and> (\<forall>t \<in> set (snd sig). is_type G t)" |
|
596 |
by (simp add: methd is_type_pTs) |
|
597 |
} note this [simp] |
|
598 |
||
599 |
from wtk |
|
600 |
have "wt_jvm_prog G ?Phi" |
|
601 |
apply (unfold wt_jvm_prog_def wt_jvm_prog_kildall_def wf_prog_def wf_cdecl_def) |
|
602 |
apply clarsimp |
|
603 |
apply (drule bspec, assumption) |
|
604 |
apply (unfold wf_mdecl_def) |
|
605 |
apply clarsimp |
|
606 |
apply (drule bspec, assumption) |
|
607 |
apply clarsimp |
|
608 |
apply (drule wt_kil_correct [OF _ wf]) |
|
609 |
apply (auto intro: someI) |
|
610 |
done |
|
611 |
||
612 |
thus ?thesis by blast |
|
613 |
qed |
|
614 |
||
13066 | 615 |
|
10592 | 616 |
end |