1(* Title: HOL/HOLCF/Fix.thy 2 Author: Franz Regensburger 3 Author: Brian Huffman 4*) 5 6section \<open>Fixed point operator and admissibility\<close> 7 8theory Fix 9 imports Cfun 10begin 11 12default_sort pcpo 13 14 15subsection \<open>Iteration\<close> 16 17primrec iterate :: "nat \<Rightarrow> ('a::cpo \<rightarrow> 'a) \<rightarrow> ('a \<rightarrow> 'a)" 18 where 19 "iterate 0 = (\<Lambda> F x. x)" 20 | "iterate (Suc n) = (\<Lambda> F x. F\<cdot>(iterate n\<cdot>F\<cdot>x))" 21 22text \<open>Derive inductive properties of iterate from primitive recursion\<close> 23 24lemma iterate_0 [simp]: "iterate 0\<cdot>F\<cdot>x = x" 25 by simp 26 27lemma iterate_Suc [simp]: "iterate (Suc n)\<cdot>F\<cdot>x = F\<cdot>(iterate n\<cdot>F\<cdot>x)" 28 by simp 29 30declare iterate.simps [simp del] 31 32lemma iterate_Suc2: "iterate (Suc n)\<cdot>F\<cdot>x = iterate n\<cdot>F\<cdot>(F\<cdot>x)" 33 by (induct n) simp_all 34 35lemma iterate_iterate: "iterate m\<cdot>F\<cdot>(iterate n\<cdot>F\<cdot>x) = iterate (m + n)\<cdot>F\<cdot>x" 36 by (induct m) simp_all 37 38text \<open>The sequence of function iterations is a chain.\<close> 39 40lemma chain_iterate [simp]: "chain (\<lambda>i. iterate i\<cdot>F\<cdot>\<bottom>)" 41 by (rule chainI, unfold iterate_Suc2, rule monofun_cfun_arg, rule minimal) 42 43 44subsection \<open>Least fixed point operator\<close> 45 46definition "fix" :: "('a \<rightarrow> 'a) \<rightarrow> 'a" 47 where "fix = (\<Lambda> F. \<Squnion>i. iterate i\<cdot>F\<cdot>\<bottom>)" 48 49text \<open>Binder syntax for \<^term>\<open>fix\<close>\<close> 50 51abbreviation fix_syn :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a" (binder "\<mu> " 10) 52 where "fix_syn (\<lambda>x. f x) \<equiv> fix\<cdot>(\<Lambda> x. f x)" 53 54notation (ASCII) 55 fix_syn (binder "FIX " 10) 56 57text \<open>Properties of \<^term>\<open>fix\<close>\<close> 58 59text \<open>direct connection between \<^term>\<open>fix\<close> and iteration\<close> 60 61lemma fix_def2: "fix\<cdot>F = (\<Squnion>i. iterate i\<cdot>F\<cdot>\<bottom>)" 62 by (simp add: fix_def) 63 64lemma iterate_below_fix: "iterate n\<cdot>f\<cdot>\<bottom> \<sqsubseteq> fix\<cdot>f" 65 unfolding fix_def2 66 using chain_iterate by (rule is_ub_thelub) 67 68text \<open> 69 Kleene's fixed point theorems for continuous functions in pointed 70 omega cpo's 71\<close> 72 73lemma fix_eq: "fix\<cdot>F = F\<cdot>(fix\<cdot>F)" 74 apply (simp add: fix_def2) 75 apply (subst lub_range_shift [of _ 1, symmetric]) 76 apply (rule chain_iterate) 77 apply (subst contlub_cfun_arg) 78 apply (rule chain_iterate) 79 apply simp 80 done 81 82lemma fix_least_below: "F\<cdot>x \<sqsubseteq> x \<Longrightarrow> fix\<cdot>F \<sqsubseteq> x" 83 apply (simp add: fix_def2) 84 apply (rule lub_below) 85 apply (rule chain_iterate) 86 apply (induct_tac i) 87 apply simp 88 apply simp 89 apply (erule rev_below_trans) 90 apply (erule monofun_cfun_arg) 91 done 92 93lemma fix_least: "F\<cdot>x = x \<Longrightarrow> fix\<cdot>F \<sqsubseteq> x" 94 by (rule fix_least_below) simp 95 96lemma fix_eqI: 97 assumes fixed: "F\<cdot>x = x" 98 and least: "\<And>z. F\<cdot>z = z \<Longrightarrow> x \<sqsubseteq> z" 99 shows "fix\<cdot>F = x" 100 apply (rule below_antisym) 101 apply (rule fix_least [OF fixed]) 102 apply (rule least [OF fix_eq [symmetric]]) 103 done 104 105lemma fix_eq2: "f \<equiv> fix\<cdot>F \<Longrightarrow> f = F\<cdot>f" 106 by (simp add: fix_eq [symmetric]) 107 108lemma fix_eq3: "f \<equiv> fix\<cdot>F \<Longrightarrow> f\<cdot>x = F\<cdot>f\<cdot>x" 109 by (erule fix_eq2 [THEN cfun_fun_cong]) 110 111lemma fix_eq4: "f = fix\<cdot>F \<Longrightarrow> f = F\<cdot>f" 112 by (erule ssubst) (rule fix_eq) 113 114lemma fix_eq5: "f = fix\<cdot>F \<Longrightarrow> f\<cdot>x = F\<cdot>f\<cdot>x" 115 by (erule fix_eq4 [THEN cfun_fun_cong]) 116 117text \<open>strictness of \<^term>\<open>fix\<close>\<close> 118 119lemma fix_bottom_iff: "fix\<cdot>F = \<bottom> \<longleftrightarrow> F\<cdot>\<bottom> = \<bottom>" 120 apply (rule iffI) 121 apply (erule subst) 122 apply (rule fix_eq [symmetric]) 123 apply (erule fix_least [THEN bottomI]) 124 done 125 126lemma fix_strict: "F\<cdot>\<bottom> = \<bottom> \<Longrightarrow> fix\<cdot>F = \<bottom>" 127 by (simp add: fix_bottom_iff) 128 129lemma fix_defined: "F\<cdot>\<bottom> \<noteq> \<bottom> \<Longrightarrow> fix\<cdot>F \<noteq> \<bottom>" 130 by (simp add: fix_bottom_iff) 131 132text \<open>\<^term>\<open>fix\<close> applied to identity and constant functions\<close> 133 134lemma fix_id: "(\<mu> x. x) = \<bottom>" 135 by (simp add: fix_strict) 136 137lemma fix_const: "(\<mu> x. c) = c" 138 by (subst fix_eq) simp 139 140 141subsection \<open>Fixed point induction\<close> 142 143lemma fix_ind: "adm P \<Longrightarrow> P \<bottom> \<Longrightarrow> (\<And>x. P x \<Longrightarrow> P (F\<cdot>x)) \<Longrightarrow> P (fix\<cdot>F)" 144 unfolding fix_def2 145 apply (erule admD) 146 apply (rule chain_iterate) 147 apply (rule nat_induct, simp_all) 148 done 149 150lemma cont_fix_ind: "cont F \<Longrightarrow> adm P \<Longrightarrow> P \<bottom> \<Longrightarrow> (\<And>x. P x \<Longrightarrow> P (F x)) \<Longrightarrow> P (fix\<cdot>(Abs_cfun F))" 151 by (simp add: fix_ind) 152 153lemma def_fix_ind: "\<lbrakk>f \<equiv> fix\<cdot>F; adm P; P \<bottom>; \<And>x. P x \<Longrightarrow> P (F\<cdot>x)\<rbrakk> \<Longrightarrow> P f" 154 by (simp add: fix_ind) 155 156lemma fix_ind2: 157 assumes adm: "adm P" 158 assumes 0: "P \<bottom>" and 1: "P (F\<cdot>\<bottom>)" 159 assumes step: "\<And>x. \<lbrakk>P x; P (F\<cdot>x)\<rbrakk> \<Longrightarrow> P (F\<cdot>(F\<cdot>x))" 160 shows "P (fix\<cdot>F)" 161 unfolding fix_def2 162 apply (rule admD [OF adm chain_iterate]) 163 apply (rule nat_less_induct) 164 apply (case_tac n) 165 apply (simp add: 0) 166 apply (case_tac nat) 167 apply (simp add: 1) 168 apply (frule_tac x=nat in spec) 169 apply (simp add: step) 170 done 171 172lemma parallel_fix_ind: 173 assumes adm: "adm (\<lambda>x. P (fst x) (snd x))" 174 assumes base: "P \<bottom> \<bottom>" 175 assumes step: "\<And>x y. P x y \<Longrightarrow> P (F\<cdot>x) (G\<cdot>y)" 176 shows "P (fix\<cdot>F) (fix\<cdot>G)" 177proof - 178 from adm have adm': "adm (case_prod P)" 179 unfolding split_def . 180 have "P (iterate i\<cdot>F\<cdot>\<bottom>) (iterate i\<cdot>G\<cdot>\<bottom>)" for i 181 by (induct i) (simp add: base, simp add: step) 182 then have "\<And>i. case_prod P (iterate i\<cdot>F\<cdot>\<bottom>, iterate i\<cdot>G\<cdot>\<bottom>)" 183 by simp 184 then have "case_prod P (\<Squnion>i. (iterate i\<cdot>F\<cdot>\<bottom>, iterate i\<cdot>G\<cdot>\<bottom>))" 185 by - (rule admD [OF adm'], simp, assumption) 186 then have "case_prod P (\<Squnion>i. iterate i\<cdot>F\<cdot>\<bottom>, \<Squnion>i. iterate i\<cdot>G\<cdot>\<bottom>)" 187 by (simp add: lub_Pair) 188 then have "P (\<Squnion>i. iterate i\<cdot>F\<cdot>\<bottom>) (\<Squnion>i. iterate i\<cdot>G\<cdot>\<bottom>)" 189 by simp 190 then show "P (fix\<cdot>F) (fix\<cdot>G)" 191 by (simp add: fix_def2) 192qed 193 194lemma cont_parallel_fix_ind: 195 assumes "cont F" and "cont G" 196 assumes "adm (\<lambda>x. P (fst x) (snd x))" 197 assumes "P \<bottom> \<bottom>" 198 assumes "\<And>x y. P x y \<Longrightarrow> P (F x) (G y)" 199 shows "P (fix\<cdot>(Abs_cfun F)) (fix\<cdot>(Abs_cfun G))" 200 by (rule parallel_fix_ind) (simp_all add: assms) 201 202 203subsection \<open>Fixed-points on product types\<close> 204 205text \<open> 206 Bekic's Theorem: Simultaneous fixed points over pairs 207 can be written in terms of separate fixed points. 208\<close> 209 210lemma fix_cprod: 211 "fix\<cdot>(F::'a \<times> 'b \<rightarrow> 'a \<times> 'b) = 212 (\<mu> x. fst (F\<cdot>(x, \<mu> y. snd (F\<cdot>(x, y)))), 213 \<mu> y. snd (F\<cdot>(\<mu> x. fst (F\<cdot>(x, \<mu> y. snd (F\<cdot>(x, y)))), y)))" 214 (is "fix\<cdot>F = (?x, ?y)") 215proof (rule fix_eqI) 216 have *: "fst (F\<cdot>(?x, ?y)) = ?x" 217 by (rule trans [symmetric, OF fix_eq], simp) 218 have "snd (F\<cdot>(?x, ?y)) = ?y" 219 by (rule trans [symmetric, OF fix_eq], simp) 220 with * show "F\<cdot>(?x, ?y) = (?x, ?y)" 221 by (simp add: prod_eq_iff) 222next 223 fix z 224 assume F_z: "F\<cdot>z = z" 225 obtain x y where z: "z = (x, y)" by (rule prod.exhaust) 226 from F_z z have F_x: "fst (F\<cdot>(x, y)) = x" by simp 227 from F_z z have F_y: "snd (F\<cdot>(x, y)) = y" by simp 228 let ?y1 = "\<mu> y. snd (F\<cdot>(x, y))" 229 have "?y1 \<sqsubseteq> y" 230 by (rule fix_least) (simp add: F_y) 231 then have "fst (F\<cdot>(x, ?y1)) \<sqsubseteq> fst (F\<cdot>(x, y))" 232 by (simp add: fst_monofun monofun_cfun) 233 with F_x have "fst (F\<cdot>(x, ?y1)) \<sqsubseteq> x" 234 by simp 235 then have *: "?x \<sqsubseteq> x" 236 by (simp add: fix_least_below) 237 then have "snd (F\<cdot>(?x, y)) \<sqsubseteq> snd (F\<cdot>(x, y))" 238 by (simp add: snd_monofun monofun_cfun) 239 with F_y have "snd (F\<cdot>(?x, y)) \<sqsubseteq> y" 240 by simp 241 then have "?y \<sqsubseteq> y" 242 by (simp add: fix_least_below) 243 with z * show "(?x, ?y) \<sqsubseteq> z" 244 by simp 245qed 246 247end 248