src/HOL/HOLCF/Library/Defl_Bifinite.thy
changeset 40774 0437dbc127b3
parent 40494 db8a09daba7b
child 41286 3d7685a4a5ff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/HOL/HOLCF/Library/Defl_Bifinite.thy	Sat Nov 27 16:08:10 2010 -0800
     1.3 @@ -0,0 +1,661 @@
     1.4 +(*  Title:      HOLCF/Library/Defl_Bifinite.thy
     1.5 +    Author:     Brian Huffman
     1.6 +*)
     1.7 +
     1.8 +header {* Algebraic deflations are a bifinite domain *}
     1.9 +
    1.10 +theory Defl_Bifinite
    1.11 +imports HOLCF Infinite_Set
    1.12 +begin
    1.13 +
    1.14 +subsection {* Lemmas about MOST *}
    1.15 +
    1.16 +default_sort type
    1.17 +
    1.18 +lemma MOST_INFM:
    1.19 +  assumes inf: "infinite (UNIV::'a set)"
    1.20 +  shows "MOST x::'a. P x \<Longrightarrow> INFM x::'a. P x"
    1.21 +  unfolding Alm_all_def Inf_many_def
    1.22 +  apply (auto simp add: Collect_neg_eq)
    1.23 +  apply (drule (1) finite_UnI)
    1.24 +  apply (simp add: Compl_partition2 inf)
    1.25 +  done
    1.26 +
    1.27 +lemma MOST_SucI: "MOST n. P n \<Longrightarrow> MOST n. P (Suc n)"
    1.28 +by (rule MOST_inj [OF _ inj_Suc])
    1.29 +
    1.30 +lemma MOST_SucD: "MOST n. P (Suc n) \<Longrightarrow> MOST n. P n"
    1.31 +unfolding MOST_nat
    1.32 +apply (clarify, rule_tac x="Suc m" in exI, clarify)
    1.33 +apply (erule Suc_lessE, simp)
    1.34 +done
    1.35 +
    1.36 +lemma MOST_Suc_iff: "(MOST n. P (Suc n)) \<longleftrightarrow> (MOST n. P n)"
    1.37 +by (rule iffI [OF MOST_SucD MOST_SucI])
    1.38 +
    1.39 +lemma INFM_finite_Bex_distrib:
    1.40 +  "finite A \<Longrightarrow> (INFM y. \<exists>x\<in>A. P x y) \<longleftrightarrow> (\<exists>x\<in>A. INFM y. P x y)"
    1.41 +by (induct set: finite, simp, simp add: INFM_disj_distrib)
    1.42 +
    1.43 +lemma MOST_finite_Ball_distrib:
    1.44 +  "finite A \<Longrightarrow> (MOST y. \<forall>x\<in>A. P x y) \<longleftrightarrow> (\<forall>x\<in>A. MOST y. P x y)"
    1.45 +by (induct set: finite, simp, simp add: MOST_conj_distrib)
    1.46 +
    1.47 +lemma MOST_ge_nat: "MOST n::nat. m \<le> n"
    1.48 +unfolding MOST_nat_le by fast
    1.49 +
    1.50 +subsection {* Eventually constant sequences *}
    1.51 +
    1.52 +definition
    1.53 +  eventually_constant :: "(nat \<Rightarrow> 'a) \<Rightarrow> bool"
    1.54 +where
    1.55 +  "eventually_constant S = (\<exists>x. MOST i. S i = x)"
    1.56 +
    1.57 +lemma eventually_constant_MOST_MOST:
    1.58 +  "eventually_constant S \<longleftrightarrow> (MOST m. MOST n. S n = S m)"
    1.59 +unfolding eventually_constant_def MOST_nat
    1.60 +apply safe
    1.61 +apply (rule_tac x=m in exI, clarify)
    1.62 +apply (rule_tac x=m in exI, clarify)
    1.63 +apply simp
    1.64 +apply fast
    1.65 +done
    1.66 +
    1.67 +lemma eventually_constantI: "MOST i. S i = x \<Longrightarrow> eventually_constant S"
    1.68 +unfolding eventually_constant_def by fast
    1.69 +
    1.70 +lemma eventually_constant_comp:
    1.71 +  "eventually_constant (\<lambda>i. S i) \<Longrightarrow> eventually_constant (\<lambda>i. f (S i))"
    1.72 +unfolding eventually_constant_def
    1.73 +apply (erule exE, rule_tac x="f x" in exI)
    1.74 +apply (erule MOST_mono, simp)
    1.75 +done
    1.76 +
    1.77 +lemma eventually_constant_Suc_iff:
    1.78 +  "eventually_constant (\<lambda>i. S (Suc i)) \<longleftrightarrow> eventually_constant (\<lambda>i. S i)"
    1.79 +unfolding eventually_constant_def
    1.80 +by (subst MOST_Suc_iff, rule refl)
    1.81 +
    1.82 +lemma eventually_constant_SucD:
    1.83 +  "eventually_constant (\<lambda>i. S (Suc i)) \<Longrightarrow> eventually_constant (\<lambda>i. S i)"
    1.84 +by (rule eventually_constant_Suc_iff [THEN iffD1])
    1.85 +
    1.86 +subsection {* Limits of eventually constant sequences *}
    1.87 +
    1.88 +definition
    1.89 +  eventual :: "(nat \<Rightarrow> 'a) \<Rightarrow> 'a" where
    1.90 +  "eventual S = (THE x. MOST i. S i = x)"
    1.91 +
    1.92 +lemma eventual_eqI: "MOST i. S i = x \<Longrightarrow> eventual S = x"
    1.93 +unfolding eventual_def
    1.94 +apply (rule the_equality, assumption)
    1.95 +apply (rename_tac y)
    1.96 +apply (subgoal_tac "MOST i::nat. y = x", simp)
    1.97 +apply (erule MOST_rev_mp)
    1.98 +apply (erule MOST_rev_mp)
    1.99 +apply simp
   1.100 +done
   1.101 +
   1.102 +lemma MOST_eq_eventual:
   1.103 +  "eventually_constant S \<Longrightarrow> MOST i. S i = eventual S"
   1.104 +unfolding eventually_constant_def
   1.105 +by (erule exE, simp add: eventual_eqI)
   1.106 +
   1.107 +lemma eventual_mem_range:
   1.108 +  "eventually_constant S \<Longrightarrow> eventual S \<in> range S"
   1.109 +apply (drule MOST_eq_eventual)
   1.110 +apply (simp only: MOST_nat_le, clarify)
   1.111 +apply (drule spec, drule mp, rule order_refl)
   1.112 +apply (erule range_eqI [OF sym])
   1.113 +done
   1.114 +
   1.115 +lemma eventually_constant_MOST_iff:
   1.116 +  assumes S: "eventually_constant S"
   1.117 +  shows "(MOST n. P (S n)) \<longleftrightarrow> P (eventual S)"
   1.118 +apply (subgoal_tac "(MOST n. P (S n)) \<longleftrightarrow> (MOST n::nat. P (eventual S))")
   1.119 +apply simp
   1.120 +apply (rule iffI)
   1.121 +apply (rule MOST_rev_mp [OF MOST_eq_eventual [OF S]])
   1.122 +apply (erule MOST_mono, force)
   1.123 +apply (rule MOST_rev_mp [OF MOST_eq_eventual [OF S]])
   1.124 +apply (erule MOST_mono, simp)
   1.125 +done
   1.126 +
   1.127 +lemma MOST_eventual:
   1.128 +  "\<lbrakk>eventually_constant S; MOST n. P (S n)\<rbrakk> \<Longrightarrow> P (eventual S)"
   1.129 +proof -
   1.130 +  assume "eventually_constant S"
   1.131 +  hence "MOST n. S n = eventual S"
   1.132 +    by (rule MOST_eq_eventual)
   1.133 +  moreover assume "MOST n. P (S n)"
   1.134 +  ultimately have "MOST n. S n = eventual S \<and> P (S n)"
   1.135 +    by (rule MOST_conj_distrib [THEN iffD2, OF conjI])
   1.136 +  hence "MOST n::nat. P (eventual S)"
   1.137 +    by (rule MOST_mono) auto
   1.138 +  thus ?thesis by simp
   1.139 +qed
   1.140 +
   1.141 +lemma eventually_constant_MOST_Suc_eq:
   1.142 +  "eventually_constant S \<Longrightarrow> MOST n. S (Suc n) = S n"
   1.143 +apply (drule MOST_eq_eventual)
   1.144 +apply (frule MOST_Suc_iff [THEN iffD2])
   1.145 +apply (erule MOST_rev_mp)
   1.146 +apply (erule MOST_rev_mp)
   1.147 +apply simp
   1.148 +done
   1.149 +
   1.150 +lemma eventual_comp:
   1.151 +  "eventually_constant S \<Longrightarrow> eventual (\<lambda>i. f (S i)) = f (eventual (\<lambda>i. S i))"
   1.152 +apply (rule eventual_eqI)
   1.153 +apply (rule MOST_mono)
   1.154 +apply (erule MOST_eq_eventual)
   1.155 +apply simp
   1.156 +done
   1.157 +
   1.158 +subsection {* Constructing finite deflations by iteration *}
   1.159 +
   1.160 +default_sort cpo
   1.161 +
   1.162 +lemma le_Suc_induct:
   1.163 +  assumes le: "i \<le> j"
   1.164 +  assumes step: "\<And>i. P i (Suc i)"
   1.165 +  assumes refl: "\<And>i. P i i"
   1.166 +  assumes trans: "\<And>i j k. \<lbrakk>P i j; P j k\<rbrakk> \<Longrightarrow> P i k"
   1.167 +  shows "P i j"
   1.168 +proof (cases "i = j")
   1.169 +  assume "i = j"
   1.170 +  thus "P i j" by (simp add: refl)
   1.171 +next
   1.172 +  assume "i \<noteq> j"
   1.173 +  with le have "i < j" by simp
   1.174 +  thus "P i j" using step trans by (rule less_Suc_induct)
   1.175 +qed
   1.176 +
   1.177 +definition
   1.178 +  eventual_iterate :: "('a \<rightarrow> 'a::cpo) \<Rightarrow> ('a \<rightarrow> 'a)"
   1.179 +where
   1.180 +  "eventual_iterate f = eventual (\<lambda>n. iterate n\<cdot>f)"
   1.181 +
   1.182 +text {* A pre-deflation is like a deflation, but not idempotent. *}
   1.183 +
   1.184 +locale pre_deflation =
   1.185 +  fixes f :: "'a \<rightarrow> 'a::cpo"
   1.186 +  assumes below: "\<And>x. f\<cdot>x \<sqsubseteq> x"
   1.187 +  assumes finite_range: "finite (range (\<lambda>x. f\<cdot>x))"
   1.188 +begin
   1.189 +
   1.190 +lemma iterate_below: "iterate i\<cdot>f\<cdot>x \<sqsubseteq> x"
   1.191 +by (induct i, simp_all add: below_trans [OF below])
   1.192 +
   1.193 +lemma iterate_fixed: "f\<cdot>x = x \<Longrightarrow> iterate i\<cdot>f\<cdot>x = x"
   1.194 +by (induct i, simp_all)
   1.195 +
   1.196 +lemma antichain_iterate_app: "i \<le> j \<Longrightarrow> iterate j\<cdot>f\<cdot>x \<sqsubseteq> iterate i\<cdot>f\<cdot>x"
   1.197 +apply (erule le_Suc_induct)
   1.198 +apply (simp add: below)
   1.199 +apply (rule below_refl)
   1.200 +apply (erule (1) below_trans)
   1.201 +done
   1.202 +
   1.203 +lemma finite_range_iterate_app: "finite (range (\<lambda>i. iterate i\<cdot>f\<cdot>x))"
   1.204 +proof (rule finite_subset)
   1.205 +  show "range (\<lambda>i. iterate i\<cdot>f\<cdot>x) \<subseteq> insert x (range (\<lambda>x. f\<cdot>x))"
   1.206 +    by (clarify, case_tac i, simp_all)
   1.207 +  show "finite (insert x (range (\<lambda>x. f\<cdot>x)))"
   1.208 +    by (simp add: finite_range)
   1.209 +qed
   1.210 +
   1.211 +lemma eventually_constant_iterate_app:
   1.212 +  "eventually_constant (\<lambda>i. iterate i\<cdot>f\<cdot>x)"
   1.213 +unfolding eventually_constant_def MOST_nat_le
   1.214 +proof -
   1.215 +  let ?Y = "\<lambda>i. iterate i\<cdot>f\<cdot>x"
   1.216 +  have "\<exists>j. \<forall>k. ?Y j \<sqsubseteq> ?Y k"
   1.217 +    apply (rule finite_range_has_max)
   1.218 +    apply (erule antichain_iterate_app)
   1.219 +    apply (rule finite_range_iterate_app)
   1.220 +    done
   1.221 +  then obtain j where j: "\<And>k. ?Y j \<sqsubseteq> ?Y k" by fast
   1.222 +  show "\<exists>z m. \<forall>n\<ge>m. ?Y n = z"
   1.223 +  proof (intro exI allI impI)
   1.224 +    fix k
   1.225 +    assume "j \<le> k"
   1.226 +    hence "?Y k \<sqsubseteq> ?Y j" by (rule antichain_iterate_app)
   1.227 +    also have "?Y j \<sqsubseteq> ?Y k" by (rule j)
   1.228 +    finally show "?Y k = ?Y j" .
   1.229 +  qed
   1.230 +qed
   1.231 +
   1.232 +lemma eventually_constant_iterate:
   1.233 +  "eventually_constant (\<lambda>n. iterate n\<cdot>f)"
   1.234 +proof -
   1.235 +  have "\<forall>y\<in>range (\<lambda>x. f\<cdot>x). eventually_constant (\<lambda>i. iterate i\<cdot>f\<cdot>y)"
   1.236 +    by (simp add: eventually_constant_iterate_app)
   1.237 +  hence "\<forall>y\<in>range (\<lambda>x. f\<cdot>x). MOST i. MOST j. iterate j\<cdot>f\<cdot>y = iterate i\<cdot>f\<cdot>y"
   1.238 +    unfolding eventually_constant_MOST_MOST .
   1.239 +  hence "MOST i. MOST j. \<forall>y\<in>range (\<lambda>x. f\<cdot>x). iterate j\<cdot>f\<cdot>y = iterate i\<cdot>f\<cdot>y"
   1.240 +    by (simp only: MOST_finite_Ball_distrib [OF finite_range])
   1.241 +  hence "MOST i. MOST j. \<forall>x. iterate j\<cdot>f\<cdot>(f\<cdot>x) = iterate i\<cdot>f\<cdot>(f\<cdot>x)"
   1.242 +    by simp
   1.243 +  hence "MOST i. MOST j. \<forall>x. iterate (Suc j)\<cdot>f\<cdot>x = iterate (Suc i)\<cdot>f\<cdot>x"
   1.244 +    by (simp only: iterate_Suc2)
   1.245 +  hence "MOST i. MOST j. iterate (Suc j)\<cdot>f = iterate (Suc i)\<cdot>f"
   1.246 +    by (simp only: cfun_eq_iff)
   1.247 +  hence "eventually_constant (\<lambda>i. iterate (Suc i)\<cdot>f)"
   1.248 +    unfolding eventually_constant_MOST_MOST .
   1.249 +  thus "eventually_constant (\<lambda>i. iterate i\<cdot>f)"
   1.250 +    by (rule eventually_constant_SucD)
   1.251 +qed
   1.252 +
   1.253 +abbreviation
   1.254 +  d :: "'a \<rightarrow> 'a"
   1.255 +where
   1.256 +  "d \<equiv> eventual_iterate f"
   1.257 +
   1.258 +lemma MOST_d: "MOST n. P (iterate n\<cdot>f) \<Longrightarrow> P d"
   1.259 +unfolding eventual_iterate_def
   1.260 +using eventually_constant_iterate by (rule MOST_eventual)
   1.261 +
   1.262 +lemma f_d: "f\<cdot>(d\<cdot>x) = d\<cdot>x"
   1.263 +apply (rule MOST_d)
   1.264 +apply (subst iterate_Suc [symmetric])
   1.265 +apply (rule eventually_constant_MOST_Suc_eq)
   1.266 +apply (rule eventually_constant_iterate_app)
   1.267 +done
   1.268 +
   1.269 +lemma d_fixed_iff: "d\<cdot>x = x \<longleftrightarrow> f\<cdot>x = x"
   1.270 +proof
   1.271 +  assume "d\<cdot>x = x"
   1.272 +  with f_d [where x=x]
   1.273 +  show "f\<cdot>x = x" by simp
   1.274 +next
   1.275 +  assume f: "f\<cdot>x = x"
   1.276 +  have "\<forall>n. iterate n\<cdot>f\<cdot>x = x"
   1.277 +    by (rule allI, rule nat.induct, simp, simp add: f)
   1.278 +  hence "MOST n. iterate n\<cdot>f\<cdot>x = x"
   1.279 +    by (rule ALL_MOST)
   1.280 +  thus "d\<cdot>x = x"
   1.281 +    by (rule MOST_d)
   1.282 +qed
   1.283 +
   1.284 +lemma finite_deflation_d: "finite_deflation d"
   1.285 +proof
   1.286 +  fix x :: 'a
   1.287 +  have "d \<in> range (\<lambda>n. iterate n\<cdot>f)"
   1.288 +    unfolding eventual_iterate_def
   1.289 +    using eventually_constant_iterate
   1.290 +    by (rule eventual_mem_range)
   1.291 +  then obtain n where n: "d = iterate n\<cdot>f" ..
   1.292 +  have "iterate n\<cdot>f\<cdot>(d\<cdot>x) = d\<cdot>x"
   1.293 +    using f_d by (rule iterate_fixed)
   1.294 +  thus "d\<cdot>(d\<cdot>x) = d\<cdot>x"
   1.295 +    by (simp add: n)
   1.296 +next
   1.297 +  fix x :: 'a
   1.298 +  show "d\<cdot>x \<sqsubseteq> x"
   1.299 +    by (rule MOST_d, simp add: iterate_below)
   1.300 +next
   1.301 +  from finite_range
   1.302 +  have "finite {x. f\<cdot>x = x}"
   1.303 +    by (rule finite_range_imp_finite_fixes)
   1.304 +  thus "finite {x. d\<cdot>x = x}"
   1.305 +    by (simp add: d_fixed_iff)
   1.306 +qed
   1.307 +
   1.308 +lemma deflation_d: "deflation d"
   1.309 +using finite_deflation_d
   1.310 +by (rule finite_deflation_imp_deflation)
   1.311 +
   1.312 +end
   1.313 +
   1.314 +lemma finite_deflation_eventual_iterate:
   1.315 +  "pre_deflation d \<Longrightarrow> finite_deflation (eventual_iterate d)"
   1.316 +by (rule pre_deflation.finite_deflation_d)
   1.317 +
   1.318 +lemma pre_deflation_oo:
   1.319 +  assumes "finite_deflation d"
   1.320 +  assumes f: "\<And>x. f\<cdot>x \<sqsubseteq> x"
   1.321 +  shows "pre_deflation (d oo f)"
   1.322 +proof
   1.323 +  interpret d: finite_deflation d by fact
   1.324 +  fix x
   1.325 +  show "\<And>x. (d oo f)\<cdot>x \<sqsubseteq> x"
   1.326 +    by (simp, rule below_trans [OF d.below f])
   1.327 +  show "finite (range (\<lambda>x. (d oo f)\<cdot>x))"
   1.328 +    by (rule finite_subset [OF _ d.finite_range], auto)
   1.329 +qed
   1.330 +
   1.331 +lemma eventual_iterate_oo_fixed_iff:
   1.332 +  assumes "finite_deflation d"
   1.333 +  assumes f: "\<And>x. f\<cdot>x \<sqsubseteq> x"
   1.334 +  shows "eventual_iterate (d oo f)\<cdot>x = x \<longleftrightarrow> d\<cdot>x = x \<and> f\<cdot>x = x"
   1.335 +proof -
   1.336 +  interpret d: finite_deflation d by fact
   1.337 +  let ?e = "d oo f"
   1.338 +  interpret e: pre_deflation "d oo f"
   1.339 +    using `finite_deflation d` f
   1.340 +    by (rule pre_deflation_oo)
   1.341 +  let ?g = "eventual (\<lambda>n. iterate n\<cdot>?e)"
   1.342 +  show ?thesis
   1.343 +    apply (subst e.d_fixed_iff)
   1.344 +    apply simp
   1.345 +    apply safe
   1.346 +    apply (erule subst)
   1.347 +    apply (rule d.idem)
   1.348 +    apply (rule below_antisym)
   1.349 +    apply (rule f)
   1.350 +    apply (erule subst, rule d.below)
   1.351 +    apply simp
   1.352 +    done
   1.353 +qed
   1.354 +
   1.355 +lemma eventual_mono:
   1.356 +  assumes A: "eventually_constant A"
   1.357 +  assumes B: "eventually_constant B"
   1.358 +  assumes below: "\<And>n. A n \<sqsubseteq> B n"
   1.359 +  shows "eventual A \<sqsubseteq> eventual B"
   1.360 +proof -
   1.361 +  from A have "MOST n. A n = eventual A"
   1.362 +    by (rule MOST_eq_eventual)
   1.363 +  then have "MOST n. eventual A \<sqsubseteq> B n"
   1.364 +    by (rule MOST_mono) (erule subst, rule below)
   1.365 +  with B show "eventual A \<sqsubseteq> eventual B"
   1.366 +    by (rule MOST_eventual)
   1.367 +qed
   1.368 +
   1.369 +lemma eventual_iterate_mono:
   1.370 +  assumes f: "pre_deflation f" and g: "pre_deflation g" and "f \<sqsubseteq> g"
   1.371 +  shows "eventual_iterate f \<sqsubseteq> eventual_iterate g"
   1.372 +unfolding eventual_iterate_def
   1.373 +apply (rule eventual_mono)
   1.374 +apply (rule pre_deflation.eventually_constant_iterate [OF f])
   1.375 +apply (rule pre_deflation.eventually_constant_iterate [OF g])
   1.376 +apply (rule monofun_cfun_arg [OF `f \<sqsubseteq> g`])
   1.377 +done
   1.378 +
   1.379 +lemma cont2cont_eventual_iterate_oo:
   1.380 +  assumes d: "finite_deflation d"
   1.381 +  assumes cont: "cont f" and below: "\<And>x y. f x\<cdot>y \<sqsubseteq> y"
   1.382 +  shows "cont (\<lambda>x. eventual_iterate (d oo f x))"
   1.383 +    (is "cont ?e")
   1.384 +proof (rule contI2)
   1.385 +  show "monofun ?e"
   1.386 +    apply (rule monofunI)
   1.387 +    apply (rule eventual_iterate_mono)
   1.388 +    apply (rule pre_deflation_oo [OF d below])
   1.389 +    apply (rule pre_deflation_oo [OF d below])
   1.390 +    apply (rule monofun_cfun_arg)
   1.391 +    apply (erule cont2monofunE [OF cont])
   1.392 +    done
   1.393 +next
   1.394 +  fix Y :: "nat \<Rightarrow> 'b"
   1.395 +  assume Y: "chain Y"
   1.396 +  with cont have fY: "chain (\<lambda>i. f (Y i))"
   1.397 +    by (rule ch2ch_cont)
   1.398 +  assume eY: "chain (\<lambda>i. ?e (Y i))"
   1.399 +  have lub_below: "\<And>x. f (\<Squnion>i. Y i)\<cdot>x \<sqsubseteq> x"
   1.400 +    by (rule admD [OF _ Y], simp add: cont, rule below)
   1.401 +  have "deflation (?e (\<Squnion>i. Y i))"
   1.402 +    apply (rule pre_deflation.deflation_d)
   1.403 +    apply (rule pre_deflation_oo [OF d lub_below])
   1.404 +    done
   1.405 +  then show "?e (\<Squnion>i. Y i) \<sqsubseteq> (\<Squnion>i. ?e (Y i))"
   1.406 +  proof (rule deflation.belowI)
   1.407 +    fix x :: 'a
   1.408 +    assume "?e (\<Squnion>i. Y i)\<cdot>x = x"
   1.409 +    hence "d\<cdot>x = x" and "f (\<Squnion>i. Y i)\<cdot>x = x"
   1.410 +      by (simp_all add: eventual_iterate_oo_fixed_iff [OF d lub_below])
   1.411 +    hence "(\<Squnion>i. f (Y i)\<cdot>x) = x"
   1.412 +      apply (simp only: cont2contlubE [OF cont Y])
   1.413 +      apply (simp only: contlub_cfun_fun [OF fY])
   1.414 +      done
   1.415 +    have "compact (d\<cdot>x)"
   1.416 +      using d by (rule finite_deflation.compact)
   1.417 +    then have "compact x"
   1.418 +      using `d\<cdot>x = x` by simp
   1.419 +    then have "compact (\<Squnion>i. f (Y i)\<cdot>x)"
   1.420 +      using `(\<Squnion>i. f (Y i)\<cdot>x) = x` by simp
   1.421 +    then have "\<exists>n. max_in_chain n (\<lambda>i. f (Y i)\<cdot>x)"
   1.422 +      by - (rule compact_imp_max_in_chain, simp add: fY, assumption)
   1.423 +    then obtain n where n: "max_in_chain n (\<lambda>i. f (Y i)\<cdot>x)" ..
   1.424 +    then have "f (Y n)\<cdot>x = x"
   1.425 +      using `(\<Squnion>i. f (Y i)\<cdot>x) = x` fY by (simp add: maxinch_is_thelub)
   1.426 +    with `d\<cdot>x = x` have "?e (Y n)\<cdot>x = x"
   1.427 +      by (simp add: eventual_iterate_oo_fixed_iff [OF d below])
   1.428 +    moreover have "?e (Y n)\<cdot>x \<sqsubseteq> (\<Squnion>i. ?e (Y i)\<cdot>x)"
   1.429 +      by (rule is_ub_thelub, simp add: eY)
   1.430 +    ultimately have "x \<sqsubseteq> (\<Squnion>i. ?e (Y i))\<cdot>x"
   1.431 +      by (simp add: contlub_cfun_fun eY)
   1.432 +    also have "(\<Squnion>i. ?e (Y i))\<cdot>x \<sqsubseteq> x"
   1.433 +      apply (rule deflation.below)
   1.434 +      apply (rule admD [OF adm_deflation eY])
   1.435 +      apply (rule pre_deflation.deflation_d)
   1.436 +      apply (rule pre_deflation_oo [OF d below])
   1.437 +      done
   1.438 +    finally show "(\<Squnion>i. ?e (Y i))\<cdot>x = x" ..
   1.439 +  qed
   1.440 +qed
   1.441 +
   1.442 +subsection {* Take function for finite deflations *}
   1.443 +
   1.444 +definition
   1.445 +  defl_take :: "nat \<Rightarrow> (udom \<rightarrow> udom) \<Rightarrow> (udom \<rightarrow> udom)"
   1.446 +where
   1.447 +  "defl_take i d = eventual_iterate (udom_approx i oo d)"
   1.448 +
   1.449 +lemma finite_deflation_defl_take:
   1.450 +  "deflation d \<Longrightarrow> finite_deflation (defl_take i d)"
   1.451 +unfolding defl_take_def
   1.452 +apply (rule pre_deflation.finite_deflation_d)
   1.453 +apply (rule pre_deflation_oo)
   1.454 +apply (rule finite_deflation_udom_approx)
   1.455 +apply (erule deflation.below)
   1.456 +done
   1.457 +
   1.458 +lemma deflation_defl_take:
   1.459 +  "deflation d \<Longrightarrow> deflation (defl_take i d)"
   1.460 +apply (rule finite_deflation_imp_deflation)
   1.461 +apply (erule finite_deflation_defl_take)
   1.462 +done
   1.463 +
   1.464 +lemma defl_take_fixed_iff:
   1.465 +  "deflation d \<Longrightarrow> defl_take i d\<cdot>x = x \<longleftrightarrow> udom_approx i\<cdot>x = x \<and> d\<cdot>x = x"
   1.466 +unfolding defl_take_def
   1.467 +apply (rule eventual_iterate_oo_fixed_iff)
   1.468 +apply (rule finite_deflation_udom_approx)
   1.469 +apply (erule deflation.below)
   1.470 +done
   1.471 +
   1.472 +lemma defl_take_below:
   1.473 +  "\<lbrakk>a \<sqsubseteq> b; deflation a; deflation b\<rbrakk> \<Longrightarrow> defl_take i a \<sqsubseteq> defl_take i b"
   1.474 +apply (rule deflation.belowI)
   1.475 +apply (erule deflation_defl_take)
   1.476 +apply (simp add: defl_take_fixed_iff)
   1.477 +apply (erule (1) deflation.belowD)
   1.478 +apply (erule conjunct2)
   1.479 +done
   1.480 +
   1.481 +lemma cont2cont_defl_take:
   1.482 +  assumes cont: "cont f" and below: "\<And>x y. f x\<cdot>y \<sqsubseteq> y"
   1.483 +  shows "cont (\<lambda>x. defl_take i (f x))"
   1.484 +unfolding defl_take_def
   1.485 +using finite_deflation_udom_approx assms
   1.486 +by (rule cont2cont_eventual_iterate_oo)
   1.487 +
   1.488 +definition
   1.489 +  fd_take :: "nat \<Rightarrow> fin_defl \<Rightarrow> fin_defl"
   1.490 +where
   1.491 +  "fd_take i d = Abs_fin_defl (defl_take i (Rep_fin_defl d))"
   1.492 +
   1.493 +lemma Rep_fin_defl_fd_take:
   1.494 +  "Rep_fin_defl (fd_take i d) = defl_take i (Rep_fin_defl d)"
   1.495 +unfolding fd_take_def
   1.496 +apply (rule Abs_fin_defl_inverse [unfolded mem_Collect_eq])
   1.497 +apply (rule finite_deflation_defl_take)
   1.498 +apply (rule deflation_Rep_fin_defl)
   1.499 +done
   1.500 +
   1.501 +lemma fd_take_fixed_iff:
   1.502 +  "Rep_fin_defl (fd_take i d)\<cdot>x = x \<longleftrightarrow>
   1.503 +    udom_approx i\<cdot>x = x \<and> Rep_fin_defl d\<cdot>x = x"
   1.504 +unfolding Rep_fin_defl_fd_take
   1.505 +apply (rule defl_take_fixed_iff)
   1.506 +apply (rule deflation_Rep_fin_defl)
   1.507 +done
   1.508 +
   1.509 +lemma fd_take_below: "fd_take n d \<sqsubseteq> d"
   1.510 +apply (rule fin_defl_belowI)
   1.511 +apply (simp add: fd_take_fixed_iff)
   1.512 +done
   1.513 +
   1.514 +lemma fd_take_idem: "fd_take n (fd_take n d) = fd_take n d"
   1.515 +apply (rule fin_defl_eqI)
   1.516 +apply (simp add: fd_take_fixed_iff)
   1.517 +done
   1.518 +
   1.519 +lemma fd_take_mono: "a \<sqsubseteq> b \<Longrightarrow> fd_take n a \<sqsubseteq> fd_take n b"
   1.520 +apply (rule fin_defl_belowI)
   1.521 +apply (simp add: fd_take_fixed_iff)
   1.522 +apply (simp add: fin_defl_belowD)
   1.523 +done
   1.524 +
   1.525 +lemma approx_fixed_le_lemma: "\<lbrakk>i \<le> j; udom_approx i\<cdot>x = x\<rbrakk> \<Longrightarrow> udom_approx j\<cdot>x = x"
   1.526 +apply (rule deflation.belowD)
   1.527 +apply (rule finite_deflation_imp_deflation)
   1.528 +apply (rule finite_deflation_udom_approx)
   1.529 +apply (erule chain_mono [OF chain_udom_approx])
   1.530 +apply assumption
   1.531 +done
   1.532 +
   1.533 +lemma fd_take_chain: "m \<le> n \<Longrightarrow> fd_take m a \<sqsubseteq> fd_take n a"
   1.534 +apply (rule fin_defl_belowI)
   1.535 +apply (simp add: fd_take_fixed_iff)
   1.536 +apply (simp add: approx_fixed_le_lemma)
   1.537 +done
   1.538 +
   1.539 +lemma finite_range_fd_take: "finite (range (fd_take n))"
   1.540 +apply (rule finite_imageD [where f="\<lambda>a. {x. Rep_fin_defl a\<cdot>x = x}"])
   1.541 +apply (rule finite_subset [where B="Pow {x. udom_approx n\<cdot>x = x}"])
   1.542 +apply (clarify, simp add: fd_take_fixed_iff)
   1.543 +apply (simp add: finite_deflation.finite_fixes [OF finite_deflation_udom_approx])
   1.544 +apply (rule inj_onI, clarify)
   1.545 +apply (simp add: set_eq_iff fin_defl_eqI)
   1.546 +done
   1.547 +
   1.548 +lemma fd_take_covers: "\<exists>n. fd_take n a = a"
   1.549 +apply (rule_tac x=
   1.550 +  "Max ((\<lambda>x. LEAST n. udom_approx n\<cdot>x = x) ` {x. Rep_fin_defl a\<cdot>x = x})" in exI)
   1.551 +apply (rule below_antisym)
   1.552 +apply (rule fd_take_below)
   1.553 +apply (rule fin_defl_belowI)
   1.554 +apply (simp add: fd_take_fixed_iff)
   1.555 +apply (rule approx_fixed_le_lemma)
   1.556 +apply (rule Max_ge)
   1.557 +apply (rule finite_imageI)
   1.558 +apply (rule Rep_fin_defl.finite_fixes)
   1.559 +apply (rule imageI)
   1.560 +apply (erule CollectI)
   1.561 +apply (rule LeastI_ex)
   1.562 +apply (rule approx_chain.compact_eq_approx [OF udom_approx])
   1.563 +apply (erule subst)
   1.564 +apply (rule Rep_fin_defl.compact)
   1.565 +done
   1.566 +
   1.567 +subsection {* Chain of approx functions on algebraic deflations *}
   1.568 +
   1.569 +definition
   1.570 +  defl_approx :: "nat \<Rightarrow> defl \<rightarrow> defl"
   1.571 +where
   1.572 +  "defl_approx = (\<lambda>i. defl.basis_fun (\<lambda>d. defl_principal (fd_take i d)))"
   1.573 +
   1.574 +lemma defl_approx_principal:
   1.575 +  "defl_approx i\<cdot>(defl_principal d) = defl_principal (fd_take i d)"
   1.576 +unfolding defl_approx_def
   1.577 +by (simp add: defl.basis_fun_principal fd_take_mono)
   1.578 +
   1.579 +lemma defl_approx: "approx_chain defl_approx"
   1.580 +proof
   1.581 +  show chain: "chain defl_approx"
   1.582 +    unfolding defl_approx_def
   1.583 +    by (simp add: chainI defl.basis_fun_mono fd_take_mono fd_take_chain)
   1.584 +  show idem: "\<And>i x. defl_approx i\<cdot>(defl_approx i\<cdot>x) = defl_approx i\<cdot>x"
   1.585 +    apply (induct_tac x rule: defl.principal_induct, simp)
   1.586 +    apply (simp add: defl_approx_principal fd_take_idem)
   1.587 +    done
   1.588 +  show below: "\<And>i x. defl_approx i\<cdot>x \<sqsubseteq> x"
   1.589 +    apply (induct_tac x rule: defl.principal_induct, simp)
   1.590 +    apply (simp add: defl_approx_principal fd_take_below)
   1.591 +    done
   1.592 +  show lub: "(\<Squnion>i. defl_approx i) = ID"
   1.593 +    apply (rule cfun_eqI, rule below_antisym)
   1.594 +    apply (simp add: contlub_cfun_fun chain lub_below_iff chain below)
   1.595 +    apply (induct_tac x rule: defl.principal_induct, simp)
   1.596 +    apply (simp add: contlub_cfun_fun chain)
   1.597 +    apply (simp add: compact_below_lub_iff defl.compact_principal chain)
   1.598 +    apply (simp add: defl_approx_principal)
   1.599 +    apply (subgoal_tac "\<exists>i. fd_take i a = a", metis below_refl)
   1.600 +    apply (rule fd_take_covers)
   1.601 +    done
   1.602 +  show "\<And>i. finite {x. defl_approx i\<cdot>x = x}"
   1.603 +    apply (rule finite_range_imp_finite_fixes)
   1.604 +    apply (rule_tac B="defl_principal ` range (fd_take i)" in rev_finite_subset)
   1.605 +    apply (simp add: finite_range_fd_take)
   1.606 +    apply (clarsimp, rename_tac x)
   1.607 +    apply (induct_tac x rule: defl.principal_induct)
   1.608 +    apply (simp add: adm_mem_finite finite_range_fd_take)
   1.609 +    apply (simp add: defl_approx_principal)
   1.610 +    done
   1.611 +qed
   1.612 +
   1.613 +subsection {* Algebraic deflations are a bifinite domain *}
   1.614 +
   1.615 +instantiation defl :: liftdomain
   1.616 +begin
   1.617 +
   1.618 +definition
   1.619 +  "emb = udom_emb defl_approx"
   1.620 +
   1.621 +definition
   1.622 +  "prj = udom_prj defl_approx"
   1.623 +
   1.624 +definition
   1.625 +  "defl (t::defl itself) =
   1.626 +    (\<Squnion>i. defl_principal (Abs_fin_defl (emb oo defl_approx i oo prj)))"
   1.627 +
   1.628 +definition
   1.629 +  "(liftemb :: defl u \<rightarrow> udom) = udom_emb u_approx oo u_map\<cdot>emb"
   1.630 +
   1.631 +definition
   1.632 +  "(liftprj :: udom \<rightarrow> defl u) = u_map\<cdot>prj oo udom_prj u_approx"
   1.633 +
   1.634 +definition
   1.635 +  "liftdefl (t::defl itself) = u_defl\<cdot>DEFL(defl)"
   1.636 +
   1.637 +instance
   1.638 +using liftemb_defl_def liftprj_defl_def liftdefl_defl_def
   1.639 +proof (rule liftdomain_class_intro)
   1.640 +  show ep: "ep_pair emb (prj :: udom \<rightarrow> defl)"
   1.641 +    unfolding emb_defl_def prj_defl_def
   1.642 +    by (rule ep_pair_udom [OF defl_approx])
   1.643 +  show "cast\<cdot>DEFL(defl) = emb oo (prj :: udom \<rightarrow> defl)"
   1.644 +    unfolding defl_defl_def
   1.645 +    apply (subst contlub_cfun_arg)
   1.646 +    apply (rule chainI)
   1.647 +    apply (rule defl.principal_mono)
   1.648 +    apply (simp add: below_fin_defl_def)
   1.649 +    apply (simp add: Abs_fin_defl_inverse approx_chain.finite_deflation_approx [OF defl_approx]
   1.650 +                     ep_pair.finite_deflation_e_d_p [OF ep])
   1.651 +    apply (intro monofun_cfun below_refl)
   1.652 +    apply (rule chainE)
   1.653 +    apply (rule approx_chain.chain_approx [OF defl_approx])
   1.654 +    apply (subst cast_defl_principal)
   1.655 +    apply (simp add: Abs_fin_defl_inverse approx_chain.finite_deflation_approx [OF defl_approx]
   1.656 +                     ep_pair.finite_deflation_e_d_p [OF ep])
   1.657 +    apply (simp add: lub_distribs approx_chain.chain_approx [OF defl_approx]
   1.658 +                     approx_chain.lub_approx [OF defl_approx])
   1.659 +    done
   1.660 +qed
   1.661 +
   1.662 +end
   1.663 +
   1.664 +end