src/HOL/IMP/Abs_Int2.thy
changeset 45127 d2eb07a1e01b
parent 45111 054a9ac0d7ef
child 45623 f682f3f7b726
equal deleted inserted replaced
45126:fc3bb3a42369 45127:d2eb07a1e01b
     7 
     7 
     8 subsection "Widening and Narrowing"
     8 subsection "Widening and Narrowing"
     9 
     9 
    10 class WN = SL_top +
    10 class WN = SL_top +
    11 fixes widen :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infix "\<nabla>" 65)
    11 fixes widen :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infix "\<nabla>" 65)
    12 assumes widen: "y \<sqsubseteq> x \<nabla> y"
    12 assumes widen1: "x \<sqsubseteq> x \<nabla> y"
       
    13 assumes widen2: "y \<sqsubseteq> x \<nabla> y"
    13 fixes narrow :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infix "\<triangle>" 65)
    14 fixes narrow :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infix "\<triangle>" 65)
    14 assumes narrow1: "y \<sqsubseteq> x \<Longrightarrow> y \<sqsubseteq> x \<triangle> y"
    15 assumes narrow1: "y \<sqsubseteq> x \<Longrightarrow> y \<sqsubseteq> x \<triangle> y"
    15 assumes narrow2: "y \<sqsubseteq> x \<Longrightarrow> x \<triangle> y \<sqsubseteq> x"
    16 assumes narrow2: "y \<sqsubseteq> x \<Longrightarrow> x \<triangle> y \<sqsubseteq> x"
    16 
    17 
    17 
    18 
    47   FunDom (\<lambda>x. fun F1 x \<triangle> fun F2 x) (inter_list (dom F1) (dom F2))"
    48   FunDom (\<lambda>x. fun F1 x \<triangle> fun F2 x) (inter_list (dom F1) (dom F2))"
    48 
    49 
    49 instance
    50 instance
    50 proof
    51 proof
    51   case goal1 thus ?case
    52   case goal1 thus ?case
    52     by(simp add: widen_st_def le_st_def lookup_def widen)
    53     by(simp add: widen_st_def le_st_def lookup_def widen1)
    53 next
    54 next
    54   case goal2 thus ?case
    55   case goal2 thus ?case
       
    56     by(simp add: widen_st_def le_st_def lookup_def widen2)
       
    57 next
       
    58   case goal3 thus ?case
    55     by(auto simp: narrow_st_def le_st_def lookup_def narrow1)
    59     by(auto simp: narrow_st_def le_st_def lookup_def narrow1)
    56 next
    60 next
    57   case goal3 thus ?case
    61   case goal4 thus ?case
    58     by(auto simp: narrow_st_def le_st_def lookup_def narrow2)
    62     by(auto simp: narrow_st_def le_st_def lookup_def narrow2)
    59 qed
    63 qed
    60 
    64 
    61 end
    65 end
    62 
    66 
    74 "narrow_up (Up x) (Up y) = Up(x \<triangle> y)"
    78 "narrow_up (Up x) (Up y) = Up(x \<triangle> y)"
    75 
    79 
    76 instance
    80 instance
    77 proof
    81 proof
    78   case goal1 show ?case
    82   case goal1 show ?case
    79     by(induct x y rule: widen_up.induct) (simp_all add: widen)
    83     by(induct x y rule: widen_up.induct) (simp_all add: widen1)
    80 next
    84 next
    81   case goal2 thus ?case
    85   case goal2 show ?case
       
    86     by(induct x y rule: widen_up.induct) (simp_all add: widen2)
       
    87 next
       
    88   case goal3 thus ?case
    82     by(induct x y rule: narrow_up.induct) (simp_all add: narrow1)
    89     by(induct x y rule: narrow_up.induct) (simp_all add: narrow1)
    83 next
    90 next
    84   case goal3 thus ?case
    91   case goal4 thus ?case
    85     by(induct x y rule: narrow_up.induct) (simp_all add: narrow2)
    92     by(induct x y rule: narrow_up.induct) (simp_all add: narrow2)
    86 qed
    93 qed
    87 
    94 
    88 end
    95 end
    89 
    96 
   100 where "widen_acom == map2_acom (op \<nabla>)"
   107 where "widen_acom == map2_acom (op \<nabla>)"
   101 
   108 
   102 abbreviation narrow_acom :: "('a::WN)acom \<Rightarrow> 'a acom \<Rightarrow> 'a acom" (infix "\<triangle>\<^sub>c" 65)
   109 abbreviation narrow_acom :: "('a::WN)acom \<Rightarrow> 'a acom \<Rightarrow> 'a acom" (infix "\<triangle>\<^sub>c" 65)
   103 where "narrow_acom == map2_acom (op \<triangle>)"
   110 where "narrow_acom == map2_acom (op \<triangle>)"
   104 
   111 
       
   112 lemma widen1_acom: "strip c = strip c' \<Longrightarrow> c \<sqsubseteq> c \<nabla>\<^sub>c c'"
       
   113 by(induct c c' rule: le_acom.induct)(simp_all add: widen1)
       
   114 
       
   115 lemma widen2_acom: "strip c = strip c' \<Longrightarrow> c' \<sqsubseteq> c \<nabla>\<^sub>c c'"
       
   116 by(induct c c' rule: le_acom.induct)(simp_all add: widen2)
       
   117 
   105 lemma narrow1_acom: "y \<sqsubseteq> x \<Longrightarrow> y \<sqsubseteq> x \<triangle>\<^sub>c y"
   118 lemma narrow1_acom: "y \<sqsubseteq> x \<Longrightarrow> y \<sqsubseteq> x \<triangle>\<^sub>c y"
   106 by(induct y x rule: le_acom.induct) (simp_all add: narrow1)
   119 by(induct y x rule: le_acom.induct) (simp_all add: narrow1)
   107 
   120 
   108 lemma narrow2_acom: "y \<sqsubseteq> x \<Longrightarrow> x \<triangle>\<^sub>c y \<sqsubseteq> x"
   121 lemma narrow2_acom: "y \<sqsubseteq> x \<Longrightarrow> x \<triangle>\<^sub>c y \<sqsubseteq> x"
   109 by(induct y x rule: le_acom.induct) (simp_all add: narrow2)
   122 by(induct y x rule: le_acom.induct) (simp_all add: narrow2)
   110 
   123 
   111 fun iter_up :: "(('a::WN)acom \<Rightarrow> 'a acom) \<Rightarrow> nat \<Rightarrow> 'a acom \<Rightarrow> 'a acom" where
   124 
   112 "iter_up f 0 x = \<top>\<^sub>c (strip x)" |
   125 subsubsection "Post-fixed point computation"
   113 "iter_up f (Suc n) x =
       
   114   (let fx = f x in if fx \<sqsubseteq> x then x else iter_up f n (x \<nabla>\<^sub>c fx))"
       
   115 
       
   116 abbreviation
       
   117   iter_down :: "(('a::WN)acom \<Rightarrow> 'a acom) \<Rightarrow> nat \<Rightarrow> 'a acom \<Rightarrow> 'a acom" where
       
   118 "iter_down f n x == ((\<lambda>x. x \<triangle>\<^sub>c f x)^^n) x"
       
   119 
   126 
   120 definition
   127 definition
   121   iter' :: "nat \<Rightarrow> nat \<Rightarrow> (('a::WN)acom \<Rightarrow> 'a acom) \<Rightarrow> 'a acom \<Rightarrow> 'a acom" where
   128   prefp :: "(('a::preord) \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a option" where
   122 "iter' m n f x = iter_down f n (iter_up f m x)"
   129 "prefp f = while_option (\<lambda>x. \<not> x \<sqsubseteq> f x) f"
       
   130 
       
   131 definition
       
   132   pfp_WN :: "(('a::WN)up acom \<Rightarrow> 'a up acom) \<Rightarrow> com \<Rightarrow> 'a up acom option"
       
   133 where "pfp_WN f c = (case lpfp\<^isub>c (\<lambda>c. c \<nabla>\<^sub>c f c) c of None \<Rightarrow> None
       
   134                      | Some c' \<Rightarrow> prefp (\<lambda>c. c \<triangle>\<^sub>c f c) c')"
   123 
   135 
   124 lemma strip_map2_acom:
   136 lemma strip_map2_acom:
   125  "strip c1 = strip c2 \<Longrightarrow> strip(map2_acom f c1 c2) = strip c1"
   137  "strip c1 = strip c2 \<Longrightarrow> strip(map2_acom f c1 c2) = strip c1"
   126 by(induct f c1 c2 rule: map2_acom.induct) simp_all
   138 by(induct f c1 c2 rule: map2_acom.induct) simp_all
   127 
   139 
   128 lemma strip_iter_up: assumes "\<forall>c. strip(f c) = strip c"
   140 lemma lpfp_step_up_pfp:
   129 shows "strip(iter_up f n c) = strip c"
   141  "\<lbrakk> \<forall>c. strip(f c) = strip c;  lpfp\<^isub>c (\<lambda>c. c \<nabla>\<^sub>c f c) c = Some c' \<rbrakk> \<Longrightarrow> f c' \<sqsubseteq> c'"
   130 apply (induction n arbitrary: c)
   142 by (metis (no_types) assms lpfpc_pfp le_trans widen2_acom)
   131  apply (metis iter_up.simps(1) strip_Top_acom snd_conv)
       
   132 apply (simp add:Let_def)
       
   133 by (metis assms strip_map2_acom)
       
   134 
       
   135 lemma iter_up_pfp: assumes "\<forall>c. strip(f c) = strip c"
       
   136 shows "f(iter_up f n c) \<sqsubseteq> iter_up f n c"
       
   137 apply (induction n arbitrary: c)
       
   138  apply(simp add: assms)
       
   139 apply (simp add:Let_def)
       
   140 done
       
   141 
       
   142 lemma strip_iter_down: assumes "\<forall>c. strip(f c) = strip c"
       
   143 shows "strip(iter_down f n c) = strip c"
       
   144 apply (induction n arbitrary: c)
       
   145  apply(simp)
       
   146 apply (simp add: strip_map2_acom assms)
       
   147 done
       
   148 
   143 
   149 lemma iter_down_pfp: assumes "mono f" and "f x0 \<sqsubseteq> x0" 
   144 lemma iter_down_pfp: assumes "mono f" and "f x0 \<sqsubseteq> x0" 
   150 defines "x n == iter_down f n x0"
   145 and "prefp (\<lambda>c. c \<triangle>\<^sub>c f c) x0 = Some x"
   151 shows "f(x n) \<sqsubseteq> x n"
   146 shows "f x \<sqsubseteq> x \<and> x \<sqsubseteq> x0" (is "?P x")
   152 proof (induction n)
   147 proof-
   153   case 0 show ?case by (simp add: x_def assms(2))
   148   { fix x assume "?P x"
   154 next
   149     note 1 = conjunct1[OF this] and 2 = conjunct2[OF this]
   155   case (Suc n)
   150     let ?x' = "x \<triangle>\<^sub>c f x"
   156   have "f (x (Suc n)) = f(x n \<triangle>\<^sub>c f(x n))" by(simp add: x_def)
   151     have "?P ?x'"
   157   also have "\<dots> \<sqsubseteq> f(x n)" by(rule monoD[OF `mono f` narrow2_acom[OF Suc]])
   152     proof
   158   also have "\<dots> \<sqsubseteq> x n \<triangle>\<^sub>c f(x n)" by(rule narrow1_acom[OF Suc])
   153       have "f ?x' \<sqsubseteq> f x"  by(rule monoD[OF `mono f` narrow2_acom[OF 1]])
   159   also have "\<dots> = x(Suc n)" by(simp add: x_def)
   154       also have "\<dots> \<sqsubseteq> ?x'" by(rule narrow1_acom[OF 1])
   160   finally show ?case .
   155       finally show "f ?x' \<sqsubseteq> ?x'" .
       
   156       have "?x' \<sqsubseteq> x" by (rule narrow2_acom[OF 1])
       
   157       also have "x \<sqsubseteq> x0" by(rule 2)
       
   158       finally show "?x' \<sqsubseteq> x0" .
       
   159     qed
       
   160   }
       
   161   with while_option_rule[where P = ?P, OF _ assms(3)[simplified prefp_def]]
       
   162     assms(2) le_refl
       
   163   show ?thesis by blast
   161 qed
   164 qed
   162 
   165 
   163 lemma iter_down_down: assumes "mono f" and "f x0 \<sqsubseteq> x0" 
   166 
   164 defines "x n == iter_down f n x0"
   167 lemma pfp_WN_pfp:
   165 shows "x n \<sqsubseteq> x0"
   168   "\<lbrakk> \<forall>c. strip (f c) = strip c;  mono f;  pfp_WN f c = Some c' \<rbrakk> \<Longrightarrow> f c' \<sqsubseteq> c'"
   166 proof (induction n)
   169 unfolding pfp_WN_def
   167   case 0 show ?case by(simp add: x_def)
   170 by (auto dest: iter_down_pfp lpfp_step_up_pfp split: option.splits)
   168 next
   171 
   169   case (Suc n)
   172 lemma strip_while: fixes f :: "'a acom \<Rightarrow> 'a acom"
   170   have "x(Suc n) = x n \<triangle>\<^sub>c f(x n)" by(simp add: x_def)
   173 assumes "\<forall>c. strip (f c) = strip c" and "while_option P f c = Some c'"
   171   also have "\<dots> \<sqsubseteq> x n" unfolding x_def
   174 shows "strip c' = strip c"
   172     by(rule narrow2_acom[OF iter_down_pfp[OF assms(1), OF assms(2)]])
   175 using while_option_rule[where P = "\<lambda>c'. strip c' = strip c", OF _ assms(2)]
   173   also have "\<dots> \<sqsubseteq> x0" by(rule Suc)
   176 by (metis assms(1))
   174   finally show ?case .
   177 
   175 qed
   178 lemma strip_pfp_WN:
   176 
   179   "\<lbrakk> \<forall>c. strip(f c) = strip c; pfp_WN f c = Some c' \<rbrakk> \<Longrightarrow> strip c' = c"
   177 
   180 apply(auto simp add: pfp_WN_def prefp_def split: option.splits)
   178 lemma iter'_pfp: assumes "\<forall>c. strip (f c) = strip c" and "mono f"
   181 by (metis (no_types) strip_lpfpc strip_map2_acom strip_while)
   179 shows "f (iter' m n f c) \<sqsubseteq> iter' m n f c"
   182 
   180 using iter_up_pfp[of f] iter_down_pfp[of f]
   183 locale Abs_Int2 = Abs_Int1_mono rep for rep :: "'a::{WN,L_top_bot} \<Rightarrow> val set"
   181 by(auto simp add: iter'_def Let_def assms)
   184 begin
   182 
   185 
   183 lemma strip_iter': assumes "\<forall>c. strip(f c) = strip c"
   186 definition AI_WN :: "com \<Rightarrow> 'a st up acom option" where
   184 shows "strip(iter' m n f c) = strip c"
   187 "AI_WN = pfp_WN (step \<top>)"
   185 by(simp add: iter'_def strip_iter_down strip_iter_up assms)
   188 
   186 
   189 lemma AI_sound: "\<lbrakk> AI_WN c = Some c';  (c,s) \<Rightarrow> t \<rbrakk> \<Longrightarrow> t <:up post c'"
       
   190 unfolding AI_WN_def
       
   191 by(metis step_sound[of "\<top>" c' s t] strip_pfp_WN strip_step
       
   192   pfp_WN_pfp mono_def mono_step[OF le_refl] in_rep_Top_up)
       
   193 
       
   194 end
   187 
   195 
   188 interpretation
   196 interpretation
   189   Abs_Int1 rep_ivl num_ivl plus_ivl filter_plus_ivl filter_less_ivl "(iter' 20 5)"
   197   Abs_Int2 num_ivl plus_ivl filter_plus_ivl filter_less_ivl rep_ivl
   190 defines afilter_ivl' is afilter
   198 defines AI_ivl' is AI_WN
   191 and bfilter_ivl' is bfilter
   199 proof qed
   192 and step_ivl' is step
   200 
   193 and AI_ivl' is AI
   201 value [code] "show_acom_opt (AI_ivl test3_ivl)"
   194 and aval_ivl' is aval'
   202 value [code] "show_acom_opt (AI_ivl' test3_ivl)"
   195 proof qed (auto simp: iter'_pfp strip_iter')
   203 
   196 
   204 definition "step_up_ivl n = ((\<lambda>c. c \<nabla>\<^sub>c step_ivl \<top> c)^^n)"
   197 value [code] "show_acom (AI_ivl test3_ivl)"
   205 definition "step_down_ivl n = ((\<lambda>c. c \<triangle>\<^sub>c step_ivl \<top> c)^^n)"
   198 value [code] "show_acom (AI_ivl' test3_ivl)"
   206 
   199 
   207 value [code] "show_acom (step_up_ivl 1 (\<bottom>\<^sub>c test3_ivl))"
   200 definition "step_up n = ((\<lambda>c. c \<nabla>\<^sub>c step_ivl \<top> c)^^n)"
   208 value [code] "show_acom (step_up_ivl 2 (\<bottom>\<^sub>c test3_ivl))"
   201 definition "step_down n = ((\<lambda>c. c \<triangle>\<^sub>c step_ivl \<top> c)^^n)"
   209 value [code] "show_acom (step_up_ivl 3 (\<bottom>\<^sub>c test3_ivl))"
   202 
   210 value [code] "show_acom (step_up_ivl 4 (\<bottom>\<^sub>c test3_ivl))"
   203 value [code] "show_acom (step_up 1 (\<bottom>\<^sub>c test3_ivl))"
   211 value [code] "show_acom (step_up_ivl 5 (\<bottom>\<^sub>c test3_ivl))"
   204 value [code] "show_acom (step_up 2 (\<bottom>\<^sub>c test3_ivl))"
   212 value [code] "show_acom (step_down_ivl 1 (step_up_ivl 5 (\<bottom>\<^sub>c test3_ivl)))"
   205 value [code] "show_acom (step_up 3 (\<bottom>\<^sub>c test3_ivl))"
   213 value [code] "show_acom (step_down_ivl 2 (step_up_ivl 5 (\<bottom>\<^sub>c test3_ivl)))"
   206 value [code] "show_acom (step_up 4 (\<bottom>\<^sub>c test3_ivl))"
   214 value [code] "show_acom (step_down_ivl 3 (step_up_ivl 5 (\<bottom>\<^sub>c test3_ivl)))"
   207 value [code] "show_acom (step_up 5 (\<bottom>\<^sub>c test3_ivl))"
   215 
   208 value [code] "show_acom (step_down 1 (step_up 5 (\<bottom>\<^sub>c test3_ivl)))"
   216 value [code] "show_acom_opt (AI_ivl' test4_ivl)"
   209 value [code] "show_acom (step_down 2 (step_up 5 (\<bottom>\<^sub>c test3_ivl)))"
   217 value [code] "show_acom_opt (AI_ivl' test5_ivl)"
   210 value [code] "show_acom (step_down 3 (step_up 5 (\<bottom>\<^sub>c test3_ivl)))"
   218 value [code] "show_acom_opt (AI_ivl' test6_ivl)"
   211 
   219 
   212 value [code] "show_acom (AI_ivl' test4_ivl)"
   220 end
   213 value [code] "show_acom (AI_ivl' test5_ivl)"
       
   214 value [code] "show_acom (AI_ivl' test6_ivl)"
       
   215 
       
   216 end