222 by blast |
222 by blast |
223 |
223 |
224 |
224 |
225 subsection "Abstract Interpretation" |
225 subsection "Abstract Interpretation" |
226 |
226 |
227 definition rep_fun :: "('a \<Rightarrow> 'b set) \<Rightarrow> ('c \<Rightarrow> 'a) \<Rightarrow> ('c \<Rightarrow> 'b)set" where |
227 definition \<gamma>_fun :: "('a \<Rightarrow> 'b set) \<Rightarrow> ('c \<Rightarrow> 'a) \<Rightarrow> ('c \<Rightarrow> 'b)set" where |
228 "rep_fun rep F = {f. \<forall>x. f x \<in> rep(F x)}" |
228 "\<gamma>_fun \<gamma> F = {f. \<forall>x. f x \<in> \<gamma>(F x)}" |
229 |
229 |
230 fun rep_option :: "('a \<Rightarrow> 'b set) \<Rightarrow> 'a option \<Rightarrow> 'b set" where |
230 fun \<gamma>_option :: "('a \<Rightarrow> 'b set) \<Rightarrow> 'a option \<Rightarrow> 'b set" where |
231 "rep_option rep None = {}" | |
231 "\<gamma>_option \<gamma> None = {}" | |
232 "rep_option rep (Some a) = rep a" |
232 "\<gamma>_option \<gamma> (Some a) = \<gamma> a" |
233 |
233 |
234 text{* The interface for abstract values: *} |
234 text{* The interface for abstract values: *} |
235 |
235 |
236 locale Val_abs = |
236 locale Val_abs = |
237 fixes rep :: "'a::SL_top \<Rightarrow> val set" ("\<gamma>") |
237 fixes \<gamma> :: "'a::SL_top \<Rightarrow> val set" |
238 assumes mono_rep: "a \<sqsubseteq> b \<Longrightarrow> \<gamma> a \<subseteq> \<gamma> b" |
238 assumes mono_gamma: "a \<sqsubseteq> b \<Longrightarrow> \<gamma> a \<subseteq> \<gamma> b" |
239 and rep_Top[simp]: "\<gamma> \<top> = UNIV" |
239 and gamma_Top[simp]: "\<gamma> \<top> = UNIV" |
240 fixes num' :: "val \<Rightarrow> 'a" |
240 fixes num' :: "val \<Rightarrow> 'a" |
241 and plus' :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" |
241 and plus' :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" |
242 assumes rep_num': "n : \<gamma>(num' n)" |
242 assumes gamma_num': "n : \<gamma>(num' n)" |
243 and rep_plus': |
243 and gamma_plus': |
244 "n1 : \<gamma> a1 \<Longrightarrow> n2 : \<gamma> a2 \<Longrightarrow> n1+n2 : \<gamma>(plus' a1 a2)" |
244 "n1 : \<gamma> a1 \<Longrightarrow> n2 : \<gamma> a2 \<Longrightarrow> n1+n2 : \<gamma>(plus' a1 a2)" |
245 |
245 |
246 type_synonym 'a st = "(vname \<Rightarrow> 'a)" |
246 type_synonym 'a st = "(vname \<Rightarrow> 'a)" |
247 |
247 |
248 locale Abs_Int_Fun = Val_abs |
248 locale Abs_Int_Fun = Val_abs |
249 begin |
249 begin |
250 |
250 |
251 fun aval' :: "aexp \<Rightarrow> 'a st \<Rightarrow> 'a" where |
251 fun aval' :: "aexp \<Rightarrow> 'a st \<Rightarrow> 'a" where |
252 "aval' (N n) _ = num' n" | |
252 "aval' (N n) S = num' n" | |
253 "aval' (V x) S = S x" | |
253 "aval' (V x) S = S x" | |
254 "aval' (Plus a1 a2) S = plus' (aval' a1 S) (aval' a2 S)" |
254 "aval' (Plus a1 a2) S = plus' (aval' a1 S) (aval' a2 S)" |
255 |
255 |
256 fun step' :: "'a st option \<Rightarrow> 'a st option acom \<Rightarrow> 'a st option acom" |
256 fun step' :: "'a st option \<Rightarrow> 'a st option acom \<Rightarrow> 'a st option acom" |
257 where |
257 where |
270 |
270 |
271 lemma strip_step'[simp]: "strip(step' S c) = strip c" |
271 lemma strip_step'[simp]: "strip(step' S c) = strip c" |
272 by(induct c arbitrary: S) (simp_all add: Let_def) |
272 by(induct c arbitrary: S) (simp_all add: Let_def) |
273 |
273 |
274 |
274 |
275 abbreviation rep_f :: "'a st \<Rightarrow> state set" ("\<gamma>\<^isub>f") |
275 abbreviation \<gamma>\<^isub>f :: "'a st \<Rightarrow> state set" |
276 where "\<gamma>\<^isub>f == rep_fun \<gamma>" |
276 where "\<gamma>\<^isub>f == \<gamma>_fun \<gamma>" |
277 |
277 |
278 abbreviation rep_u :: "'a st option \<Rightarrow> state set" ("\<gamma>\<^isub>u") |
278 abbreviation \<gamma>\<^isub>o :: "'a st option \<Rightarrow> state set" |
279 where "\<gamma>\<^isub>u == rep_option \<gamma>\<^isub>f" |
279 where "\<gamma>\<^isub>o == \<gamma>_option \<gamma>\<^isub>f" |
280 |
280 |
281 abbreviation rep_c :: "'a st option acom \<Rightarrow> state set acom" ("\<gamma>\<^isub>c") |
281 abbreviation \<gamma>\<^isub>c :: "'a st option acom \<Rightarrow> state set acom" |
282 where "\<gamma>\<^isub>c == map_acom \<gamma>\<^isub>u" |
282 where "\<gamma>\<^isub>c == map_acom \<gamma>\<^isub>o" |
283 |
283 |
284 lemma rep_f_Top[simp]: "\<gamma>\<^isub>f Top = UNIV" |
284 lemma gamma_f_Top[simp]: "\<gamma>\<^isub>f Top = UNIV" |
285 by(simp add: Top_fun_def rep_fun_def) |
285 by(simp add: Top_fun_def \<gamma>_fun_def) |
286 |
286 |
287 lemma rep_u_Top[simp]: "\<gamma>\<^isub>u Top = UNIV" |
287 lemma gamma_o_Top[simp]: "\<gamma>\<^isub>o Top = UNIV" |
288 by (simp add: Top_option_def) |
288 by (simp add: Top_option_def) |
289 |
289 |
290 (* FIXME (maybe also le \<rightarrow> sqle?) *) |
290 (* FIXME (maybe also le \<rightarrow> sqle?) *) |
291 |
291 |
292 lemma mono_rep_f: "f \<sqsubseteq> g \<Longrightarrow> \<gamma>\<^isub>f f \<subseteq> \<gamma>\<^isub>f g" |
292 lemma mono_gamma_f: "f \<sqsubseteq> g \<Longrightarrow> \<gamma>\<^isub>f f \<subseteq> \<gamma>\<^isub>f g" |
293 by(auto simp: le_fun_def rep_fun_def dest: mono_rep) |
293 by(auto simp: le_fun_def \<gamma>_fun_def dest: mono_gamma) |
294 |
294 |
295 lemma mono_rep_u: |
295 lemma mono_gamma_o: |
296 "sa \<sqsubseteq> sa' \<Longrightarrow> \<gamma>\<^isub>u sa \<subseteq> \<gamma>\<^isub>u sa'" |
296 "sa \<sqsubseteq> sa' \<Longrightarrow> \<gamma>\<^isub>o sa \<subseteq> \<gamma>\<^isub>o sa'" |
297 by(induction sa sa' rule: le_option.induct)(simp_all add: mono_rep_f) |
297 by(induction sa sa' rule: le_option.induct)(simp_all add: mono_gamma_f) |
298 |
298 |
299 lemma mono_rep_c: "ca \<sqsubseteq> ca' \<Longrightarrow> \<gamma>\<^isub>c ca \<le> \<gamma>\<^isub>c ca'" |
299 lemma mono_gamma_c: "ca \<sqsubseteq> ca' \<Longrightarrow> \<gamma>\<^isub>c ca \<le> \<gamma>\<^isub>c ca'" |
300 by (induction ca ca' rule: le_acom.induct) (simp_all add:mono_rep_u) |
300 by (induction ca ca' rule: le_acom.induct) (simp_all add:mono_gamma_o) |
301 |
301 |
302 text{* Soundness: *} |
302 text{* Soundness: *} |
303 |
303 |
304 lemma aval'_sound: "s : \<gamma>\<^isub>f S \<Longrightarrow> aval a s : \<gamma>(aval' a S)" |
304 lemma aval'_sound: "s : \<gamma>\<^isub>f S \<Longrightarrow> aval a s : \<gamma>(aval' a S)" |
305 by (induct a) (auto simp: rep_num' rep_plus' rep_fun_def) |
305 by (induct a) (auto simp: gamma_num' gamma_plus' \<gamma>_fun_def) |
306 |
306 |
307 lemma in_rep_update: |
307 lemma in_gamma_update: |
308 "\<lbrakk> s : \<gamma>\<^isub>f S; i : \<gamma> a \<rbrakk> \<Longrightarrow> s(x := i) : \<gamma>\<^isub>f(S(x := a))" |
308 "\<lbrakk> s : \<gamma>\<^isub>f S; i : \<gamma> a \<rbrakk> \<Longrightarrow> s(x := i) : \<gamma>\<^isub>f(S(x := a))" |
309 by(simp add: rep_fun_def) |
309 by(simp add: \<gamma>_fun_def) |
310 |
310 |
311 lemma step_preserves_le2: |
311 lemma step_preserves_le2: |
312 "\<lbrakk> S \<subseteq> \<gamma>\<^isub>u sa; cs \<le> \<gamma>\<^isub>c ca; strip cs = c; strip ca = c \<rbrakk> |
312 "\<lbrakk> S \<subseteq> \<gamma>\<^isub>o sa; cs \<le> \<gamma>\<^isub>c ca; strip cs = c; strip ca = c \<rbrakk> |
313 \<Longrightarrow> step S cs \<le> \<gamma>\<^isub>c (step' sa ca)" |
313 \<Longrightarrow> step S cs \<le> \<gamma>\<^isub>c (step' sa ca)" |
314 proof(induction c arbitrary: cs ca S sa) |
314 proof(induction c arbitrary: cs ca S sa) |
315 case SKIP thus ?case |
315 case SKIP thus ?case |
316 by(auto simp:strip_eq_SKIP) |
316 by(auto simp:strip_eq_SKIP) |
317 next |
317 next |
318 case Assign thus ?case |
318 case Assign thus ?case |
319 by (fastforce simp: strip_eq_Assign intro: aval'_sound in_rep_update |
319 by (fastforce simp: strip_eq_Assign intro: aval'_sound in_gamma_update |
320 split: option.splits del:subsetD) |
320 split: option.splits del:subsetD) |
321 next |
321 next |
322 case Semi thus ?case apply (auto simp: strip_eq_Semi) |
322 case Semi thus ?case apply (auto simp: strip_eq_Semi) |
323 by (metis le_post post_map_acom) |
323 by (metis le_post post_map_acom) |
324 next |
324 next |
325 case (If b c1 c2) |
325 case (If b c1 c2) |
326 then obtain cs1 cs2 ca1 ca2 P Pa where |
326 then obtain cs1 cs2 ca1 ca2 P Pa where |
327 "cs= IF b THEN cs1 ELSE cs2 {P}" "ca= IF b THEN ca1 ELSE ca2 {Pa}" |
327 "cs= IF b THEN cs1 ELSE cs2 {P}" "ca= IF b THEN ca1 ELSE ca2 {Pa}" |
328 "P \<subseteq> \<gamma>\<^isub>u Pa" "cs1 \<le> \<gamma>\<^isub>c ca1" "cs2 \<le> \<gamma>\<^isub>c ca2" |
328 "P \<subseteq> \<gamma>\<^isub>o Pa" "cs1 \<le> \<gamma>\<^isub>c ca1" "cs2 \<le> \<gamma>\<^isub>c ca2" |
329 "strip cs1 = c1" "strip ca1 = c1" "strip cs2 = c2" "strip ca2 = c2" |
329 "strip cs1 = c1" "strip ca1 = c1" "strip cs2 = c2" "strip ca2 = c2" |
330 by (fastforce simp: strip_eq_If) |
330 by (fastforce simp: strip_eq_If) |
331 moreover have "post cs1 \<subseteq> \<gamma>\<^isub>u(post ca1 \<squnion> post ca2)" |
331 moreover have "post cs1 \<subseteq> \<gamma>\<^isub>o(post ca1 \<squnion> post ca2)" |
332 by (metis (no_types) `cs1 \<le> \<gamma>\<^isub>c ca1` join_ge1 le_post mono_rep_u order_trans post_map_acom) |
332 by (metis (no_types) `cs1 \<le> \<gamma>\<^isub>c ca1` join_ge1 le_post mono_gamma_o order_trans post_map_acom) |
333 moreover have "post cs2 \<subseteq> \<gamma>\<^isub>u(post ca1 \<squnion> post ca2)" |
333 moreover have "post cs2 \<subseteq> \<gamma>\<^isub>o(post ca1 \<squnion> post ca2)" |
334 by (metis (no_types) `cs2 \<le> \<gamma>\<^isub>c ca2` join_ge2 le_post mono_rep_u order_trans post_map_acom) |
334 by (metis (no_types) `cs2 \<le> \<gamma>\<^isub>c ca2` join_ge2 le_post mono_gamma_o order_trans post_map_acom) |
335 ultimately show ?case using `S \<subseteq> \<gamma>\<^isub>u sa` by (simp add: If.IH subset_iff) |
335 ultimately show ?case using `S \<subseteq> \<gamma>\<^isub>o sa` by (simp add: If.IH subset_iff) |
336 next |
336 next |
337 case (While b c1) |
337 case (While b c1) |
338 then obtain cs1 ca1 I P Ia Pa where |
338 then obtain cs1 ca1 I P Ia Pa where |
339 "cs = {I} WHILE b DO cs1 {P}" "ca = {Ia} WHILE b DO ca1 {Pa}" |
339 "cs = {I} WHILE b DO cs1 {P}" "ca = {Ia} WHILE b DO ca1 {Pa}" |
340 "I \<subseteq> \<gamma>\<^isub>u Ia" "P \<subseteq> \<gamma>\<^isub>u Pa" "cs1 \<le> \<gamma>\<^isub>c ca1" |
340 "I \<subseteq> \<gamma>\<^isub>o Ia" "P \<subseteq> \<gamma>\<^isub>o Pa" "cs1 \<le> \<gamma>\<^isub>c ca1" |
341 "strip cs1 = c1" "strip ca1 = c1" |
341 "strip cs1 = c1" "strip ca1 = c1" |
342 by (fastforce simp: strip_eq_While) |
342 by (fastforce simp: strip_eq_While) |
343 moreover have "S \<union> post cs1 \<subseteq> \<gamma>\<^isub>u (sa \<squnion> post ca1)" |
343 moreover have "S \<union> post cs1 \<subseteq> \<gamma>\<^isub>o (sa \<squnion> post ca1)" |
344 using `S \<subseteq> \<gamma>\<^isub>u sa` le_post[OF `cs1 \<le> \<gamma>\<^isub>c ca1`, simplified] |
344 using `S \<subseteq> \<gamma>\<^isub>o sa` le_post[OF `cs1 \<le> \<gamma>\<^isub>c ca1`, simplified] |
345 by (metis (no_types) join_ge1 join_ge2 le_sup_iff mono_rep_u order_trans) |
345 by (metis (no_types) join_ge1 join_ge2 le_sup_iff mono_gamma_o order_trans) |
346 ultimately show ?case by (simp add: While.IH subset_iff) |
346 ultimately show ?case by (simp add: While.IH subset_iff) |
347 qed |
347 qed |
348 |
348 |
349 lemma step_preserves_le: |
349 lemma step_preserves_le: |
350 "\<lbrakk> S \<subseteq> \<gamma>\<^isub>u sa; cs \<le> \<gamma>\<^isub>c ca; strip cs = c \<rbrakk> |
350 "\<lbrakk> S \<subseteq> \<gamma>\<^isub>o sa; cs \<le> \<gamma>\<^isub>c ca; strip cs = c \<rbrakk> |
351 \<Longrightarrow> step S cs \<le> \<gamma>\<^isub>c(step' sa ca)" |
351 \<Longrightarrow> step S cs \<le> \<gamma>\<^isub>c(step' sa ca)" |
352 by (metis le_strip step_preserves_le2 strip_acom) |
352 by (metis le_strip step_preserves_le2 strip_acom) |
353 |
353 |
354 lemma AI_sound: "AI c = Some c' \<Longrightarrow> CS UNIV c \<le> \<gamma>\<^isub>c c'" |
354 lemma AI_sound: "AI c = Some c' \<Longrightarrow> CS UNIV c \<le> \<gamma>\<^isub>c c'" |
355 proof(simp add: CS_def AI_def) |
355 proof(simp add: CS_def AI_def) |