src/HOL/IMP/Abs_Int0_fun.thy
changeset 46039 698de142f6f9
parent 45903 02dd9319dcb7
child 46063 81ebd0cdb300
equal deleted inserted replaced
46035:313be214e40a 46039:698de142f6f9
   130 fun join_option where
   130 fun join_option where
   131 "Some x \<squnion> Some y = Some(x \<squnion> y)" |
   131 "Some x \<squnion> Some y = Some(x \<squnion> y)" |
   132 "None \<squnion> y = y" |
   132 "None \<squnion> y = y" |
   133 "x \<squnion> None = x"
   133 "x \<squnion> None = x"
   134 
   134 
   135 lemma [simp]: "x \<squnion> None = x"
   135 lemma join_None2[simp]: "x \<squnion> None = x"
   136 by (cases x) simp_all
   136 by (cases x) simp_all
   137 
   137 
   138 definition "\<top> = Some \<top>"
   138 definition "\<top> = Some \<top>"
   139 
   139 
   140 instance proof
   140 instance proof
   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)
   359     by(simp add: strip_lpfpc[OF _ 1])
   359     by(simp add: strip_lpfpc[OF _ 1])
   360   have "lfp c (step UNIV) \<le> \<gamma>\<^isub>c (step' \<top> c')"
   360   have "lfp c (step UNIV) \<le> \<gamma>\<^isub>c (step' \<top> c')"
   361   proof(rule lfp_lowerbound[simplified,OF 3])
   361   proof(rule lfp_lowerbound[simplified,OF 3])
   362     show "step UNIV (\<gamma>\<^isub>c (step' \<top> c')) \<le> \<gamma>\<^isub>c (step' \<top> c')"
   362     show "step UNIV (\<gamma>\<^isub>c (step' \<top> c')) \<le> \<gamma>\<^isub>c (step' \<top> c')"
   363     proof(rule step_preserves_le[OF _ _ 3])
   363     proof(rule step_preserves_le[OF _ _ 3])
   364       show "UNIV \<subseteq> \<gamma>\<^isub>u \<top>" by simp
   364       show "UNIV \<subseteq> \<gamma>\<^isub>o \<top>" by simp
   365       show "\<gamma>\<^isub>c (step' \<top> c') \<le> \<gamma>\<^isub>c c'" by(rule mono_rep_c[OF 2])
   365       show "\<gamma>\<^isub>c (step' \<top> c') \<le> \<gamma>\<^isub>c c'" by(rule mono_gamma_c[OF 2])
   366     qed
   366     qed
   367   qed
   367   qed
   368   from this 2 show "lfp c (step UNIV) \<le> \<gamma>\<^isub>c c'"
   368   from this 2 show "lfp c (step UNIV) \<le> \<gamma>\<^isub>c c'"
   369     by (blast intro: mono_rep_c order_trans)
   369     by (blast intro: mono_gamma_c order_trans)
   370 qed
   370 qed
   371 
   371 
   372 end
   372 end
   373 
   373 
   374 
   374