55 text {* |
55 text {* |
56 A ccpo has a least upper bound for any chain. In particular, the |
56 A ccpo has a least upper bound for any chain. In particular, the |
57 empty set is a chain, so every ccpo must have a bottom element. |
57 empty set is a chain, so every ccpo must have a bottom element. |
58 *} |
58 *} |
59 |
59 |
60 class ccpo = order + |
60 class ccpo = order + Sup + |
61 fixes lub :: "'a set \<Rightarrow> 'a" |
61 assumes ccpo_Sup_upper: "\<lbrakk>chain (op \<le>) A; x \<in> A\<rbrakk> \<Longrightarrow> x \<le> Sup A" |
62 assumes lub_upper: "chain (op \<le>) A \<Longrightarrow> x \<in> A \<Longrightarrow> x \<le> lub A" |
62 assumes ccpo_Sup_least: "\<lbrakk>chain (op \<le>) A; \<And>x. x \<in> A \<Longrightarrow> x \<le> z\<rbrakk> \<Longrightarrow> Sup A \<le> z" |
63 assumes lub_least: "chain (op \<le>) A \<Longrightarrow> (\<And>x. x \<in> A \<Longrightarrow> x \<le> z) \<Longrightarrow> lub A \<le> z" |
|
64 begin |
63 begin |
65 |
64 |
66 subsection {* Transfinite iteration of a function *} |
65 subsection {* Transfinite iteration of a function *} |
67 |
66 |
68 inductive_set iterates :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a set" |
67 inductive_set iterates :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a set" |
69 for f :: "'a \<Rightarrow> 'a" |
68 for f :: "'a \<Rightarrow> 'a" |
70 where |
69 where |
71 step: "x \<in> iterates f \<Longrightarrow> f x \<in> iterates f" |
70 step: "x \<in> iterates f \<Longrightarrow> f x \<in> iterates f" |
72 | lub: "chain (op \<le>) M \<Longrightarrow> \<forall>x\<in>M. x \<in> iterates f \<Longrightarrow> lub M \<in> iterates f" |
71 | Sup: "chain (op \<le>) M \<Longrightarrow> \<forall>x\<in>M. x \<in> iterates f \<Longrightarrow> Sup M \<in> iterates f" |
73 |
72 |
74 lemma iterates_le_f: |
73 lemma iterates_le_f: |
75 "x \<in> iterates f \<Longrightarrow> monotone (op \<le>) (op \<le>) f \<Longrightarrow> x \<le> f x" |
74 "x \<in> iterates f \<Longrightarrow> monotone (op \<le>) (op \<le>) f \<Longrightarrow> x \<le> f x" |
76 by (induct x rule: iterates.induct) |
75 by (induct x rule: iterates.induct) |
77 (force dest: monotoneD intro!: lub_upper lub_least)+ |
76 (force dest: monotoneD intro!: ccpo_Sup_upper ccpo_Sup_least)+ |
78 |
77 |
79 lemma chain_iterates: |
78 lemma chain_iterates: |
80 assumes f: "monotone (op \<le>) (op \<le>) f" |
79 assumes f: "monotone (op \<le>) (op \<le>) f" |
81 shows "chain (op \<le>) (iterates f)" (is "chain _ ?C") |
80 shows "chain (op \<le>) (iterates f)" (is "chain _ ?C") |
82 proof (rule chainI) |
81 proof (rule chainI) |
87 and IH: "\<And>z. z \<in> ?C \<Longrightarrow> x \<le> z \<or> z \<le> x" |
86 and IH: "\<And>z. z \<in> ?C \<Longrightarrow> x \<le> z \<or> z \<le> x" |
88 from y show "f x \<le> y \<or> y \<le> f x" |
87 from y show "f x \<le> y \<or> y \<le> f x" |
89 proof (induct y rule: iterates.induct) |
88 proof (induct y rule: iterates.induct) |
90 case (step y) with IH f show ?case by (auto dest: monotoneD) |
89 case (step y) with IH f show ?case by (auto dest: monotoneD) |
91 next |
90 next |
92 case (lub M) |
91 case (Sup M) |
93 then have chM: "chain (op \<le>) M" |
92 then have chM: "chain (op \<le>) M" |
94 and IH': "\<And>z. z \<in> M \<Longrightarrow> f x \<le> z \<or> z \<le> f x" by auto |
93 and IH': "\<And>z. z \<in> M \<Longrightarrow> f x \<le> z \<or> z \<le> f x" by auto |
95 show "f x \<le> lub M \<or> lub M \<le> f x" |
94 show "f x \<le> Sup M \<or> Sup M \<le> f x" |
96 proof (cases "\<exists>z\<in>M. f x \<le> z") |
95 proof (cases "\<exists>z\<in>M. f x \<le> z") |
97 case True then have "f x \<le> lub M" |
96 case True then have "f x \<le> Sup M" |
98 apply rule |
97 apply rule |
99 apply (erule order_trans) |
98 apply (erule order_trans) |
100 by (rule lub_upper[OF chM]) |
99 by (rule ccpo_Sup_upper[OF chM]) |
101 thus ?thesis .. |
100 thus ?thesis .. |
102 next |
101 next |
103 case False with IH' |
102 case False with IH' |
104 show ?thesis by (auto intro: lub_least[OF chM]) |
103 show ?thesis by (auto intro: ccpo_Sup_least[OF chM]) |
105 qed |
104 qed |
106 qed |
105 qed |
107 next |
106 next |
108 case (lub M y) |
107 case (Sup M y) |
109 show ?case |
108 show ?case |
110 proof (cases "\<exists>x\<in>M. y \<le> x") |
109 proof (cases "\<exists>x\<in>M. y \<le> x") |
111 case True then have "y \<le> lub M" |
110 case True then have "y \<le> Sup M" |
112 apply rule |
111 apply rule |
113 apply (erule order_trans) |
112 apply (erule order_trans) |
114 by (rule lub_upper[OF lub(1)]) |
113 by (rule ccpo_Sup_upper[OF Sup(1)]) |
115 thus ?thesis .. |
114 thus ?thesis .. |
116 next |
115 next |
117 case False with lub |
116 case False with Sup |
118 show ?thesis by (auto intro: lub_least) |
117 show ?thesis by (auto intro: ccpo_Sup_least) |
119 qed |
118 qed |
120 qed |
119 qed |
121 qed |
120 qed |
122 |
121 |
123 subsection {* Fixpoint combinator *} |
122 subsection {* Fixpoint combinator *} |
124 |
123 |
125 definition |
124 definition |
126 fixp :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a" |
125 fixp :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a" |
127 where |
126 where |
128 "fixp f = lub (iterates f)" |
127 "fixp f = Sup (iterates f)" |
129 |
128 |
130 lemma iterates_fixp: |
129 lemma iterates_fixp: |
131 assumes f: "monotone (op \<le>) (op \<le>) f" shows "fixp f \<in> iterates f" |
130 assumes f: "monotone (op \<le>) (op \<le>) f" shows "fixp f \<in> iterates f" |
132 unfolding fixp_def |
131 unfolding fixp_def |
133 by (simp add: iterates.lub chain_iterates f) |
132 by (simp add: iterates.Sup chain_iterates f) |
134 |
133 |
135 lemma fixp_unfold: |
134 lemma fixp_unfold: |
136 assumes f: "monotone (op \<le>) (op \<le>) f" |
135 assumes f: "monotone (op \<le>) (op \<le>) f" |
137 shows "fixp f = f (fixp f)" |
136 shows "fixp f = f (fixp f)" |
138 proof (rule antisym) |
137 proof (rule antisym) |
139 show "fixp f \<le> f (fixp f)" |
138 show "fixp f \<le> f (fixp f)" |
140 by (intro iterates_le_f iterates_fixp f) |
139 by (intro iterates_le_f iterates_fixp f) |
141 have "f (fixp f) \<le> lub (iterates f)" |
140 have "f (fixp f) \<le> Sup (iterates f)" |
142 by (intro lub_upper chain_iterates f iterates.step iterates_fixp) |
141 by (intro ccpo_Sup_upper chain_iterates f iterates.step iterates_fixp) |
143 thus "f (fixp f) \<le> fixp f" |
142 thus "f (fixp f) \<le> fixp f" |
144 unfolding fixp_def . |
143 unfolding fixp_def . |
145 qed |
144 qed |
146 |
145 |
147 lemma fixp_lowerbound: |
146 lemma fixp_lowerbound: |
148 assumes f: "monotone (op \<le>) (op \<le>) f" and z: "f z \<le> z" shows "fixp f \<le> z" |
147 assumes f: "monotone (op \<le>) (op \<le>) f" and z: "f z \<le> z" shows "fixp f \<le> z" |
149 unfolding fixp_def |
148 unfolding fixp_def |
150 proof (rule lub_least[OF chain_iterates[OF f]]) |
149 proof (rule ccpo_Sup_least[OF chain_iterates[OF f]]) |
151 fix x assume "x \<in> iterates f" |
150 fix x assume "x \<in> iterates f" |
152 thus "x \<le> z" |
151 thus "x \<le> z" |
153 proof (induct x rule: iterates.induct) |
152 proof (induct x rule: iterates.induct) |
154 fix x assume "x \<le> z" with f have "f x \<le> f z" by (rule monotoneD) |
153 fix x assume "x \<le> z" with f have "f x \<le> f z" by (rule monotoneD) |
155 also note z finally show "f x \<le> z" . |
154 also note z finally show "f x \<le> z" . |
156 qed (auto intro: lub_least) |
155 qed (auto intro: ccpo_Sup_least) |
157 qed |
156 qed |
158 |
157 |
159 |
158 |
160 subsection {* Fixpoint induction *} |
159 subsection {* Fixpoint induction *} |
161 |
160 |
162 definition |
161 definition |
163 admissible :: "('a \<Rightarrow> bool) \<Rightarrow> bool" |
162 admissible :: "('a \<Rightarrow> bool) \<Rightarrow> bool" |
164 where |
163 where |
165 "admissible P = (\<forall>A. chain (op \<le>) A \<longrightarrow> (\<forall>x\<in>A. P x) \<longrightarrow> P (lub A))" |
164 "admissible P = (\<forall>A. chain (op \<le>) A \<longrightarrow> (\<forall>x\<in>A. P x) \<longrightarrow> P (Sup A))" |
166 |
165 |
167 lemma admissibleI: |
166 lemma admissibleI: |
168 assumes "\<And>A. chain (op \<le>) A \<Longrightarrow> \<forall>x\<in>A. P x \<Longrightarrow> P (lub A)" |
167 assumes "\<And>A. chain (op \<le>) A \<Longrightarrow> \<forall>x\<in>A. P x \<Longrightarrow> P (Sup A)" |
169 shows "admissible P" |
168 shows "admissible P" |
170 using assms unfolding admissible_def by fast |
169 using assms unfolding admissible_def by fast |
171 |
170 |
172 lemma admissibleD: |
171 lemma admissibleD: |
173 assumes "admissible P" |
172 assumes "admissible P" |
174 assumes "chain (op \<le>) A" |
173 assumes "chain (op \<le>) A" |
175 assumes "\<And>x. x \<in> A \<Longrightarrow> P x" |
174 assumes "\<And>x. x \<in> A \<Longrightarrow> P x" |
176 shows "P (lub A)" |
175 shows "P (Sup A)" |
177 using assms by (auto simp: admissible_def) |
176 using assms by (auto simp: admissible_def) |
178 |
177 |
179 lemma fixp_induct: |
178 lemma fixp_induct: |
180 assumes adm: "admissible P" |
179 assumes adm: "admissible P" |
181 assumes mono: "monotone (op \<le>) (op \<le>) f" |
180 assumes mono: "monotone (op \<le>) (op \<le>) f" |
218 unfolding chain_def by fast |
217 unfolding chain_def by fast |
219 |
218 |
220 lemma admissible_disj_lemma: |
219 lemma admissible_disj_lemma: |
221 assumes A: "chain (op \<le>)A" |
220 assumes A: "chain (op \<le>)A" |
222 assumes P: "\<forall>x\<in>A. \<exists>y\<in>A. x \<le> y \<and> P y" |
221 assumes P: "\<forall>x\<in>A. \<exists>y\<in>A. x \<le> y \<and> P y" |
223 shows "lub A = lub {x \<in> A. P x}" |
222 shows "Sup A = Sup {x \<in> A. P x}" |
224 proof (rule antisym) |
223 proof (rule antisym) |
225 have *: "chain (op \<le>) {x \<in> A. P x}" |
224 have *: "chain (op \<le>) {x \<in> A. P x}" |
226 by (rule chain_compr [OF A]) |
225 by (rule chain_compr [OF A]) |
227 show "lub A \<le> lub {x \<in> A. P x}" |
226 show "Sup A \<le> Sup {x \<in> A. P x}" |
228 apply (rule lub_least [OF A]) |
227 apply (rule ccpo_Sup_least [OF A]) |
229 apply (drule P [rule_format], clarify) |
228 apply (drule P [rule_format], clarify) |
230 apply (erule order_trans) |
229 apply (erule order_trans) |
231 apply (simp add: lub_upper [OF *]) |
230 apply (simp add: ccpo_Sup_upper [OF *]) |
232 done |
231 done |
233 show "lub {x \<in> A. P x} \<le> lub A" |
232 show "Sup {x \<in> A. P x} \<le> Sup A" |
234 apply (rule lub_least [OF *]) |
233 apply (rule ccpo_Sup_least [OF *]) |
235 apply clarify |
234 apply clarify |
236 apply (simp add: lub_upper [OF A]) |
235 apply (simp add: ccpo_Sup_upper [OF A]) |
237 done |
236 done |
238 qed |
237 qed |
239 |
238 |
240 lemma admissible_disj: |
239 lemma admissible_disj: |
241 fixes P Q :: "'a \<Rightarrow> bool" |
240 fixes P Q :: "'a \<Rightarrow> bool" |
245 proof (rule admissibleI) |
244 proof (rule admissibleI) |
246 fix A :: "'a set" assume A: "chain (op \<le>) A" |
245 fix A :: "'a set" assume A: "chain (op \<le>) A" |
247 assume "\<forall>x\<in>A. P x \<or> Q x" |
246 assume "\<forall>x\<in>A. P x \<or> Q x" |
248 hence "(\<forall>x\<in>A. \<exists>y\<in>A. x \<le> y \<and> P y) \<or> (\<forall>x\<in>A. \<exists>y\<in>A. x \<le> y \<and> Q y)" |
247 hence "(\<forall>x\<in>A. \<exists>y\<in>A. x \<le> y \<and> P y) \<or> (\<forall>x\<in>A. \<exists>y\<in>A. x \<le> y \<and> Q y)" |
249 using chainD[OF A] by blast |
248 using chainD[OF A] by blast |
250 hence "lub A = lub {x \<in> A. P x} \<or> lub A = lub {x \<in> A. Q x}" |
249 hence "Sup A = Sup {x \<in> A. P x} \<or> Sup A = Sup {x \<in> A. Q x}" |
251 using admissible_disj_lemma [OF A] by fast |
250 using admissible_disj_lemma [OF A] by fast |
252 thus "P (lub A) \<or> Q (lub A)" |
251 thus "P (Sup A) \<or> Q (Sup A)" |
253 apply (rule disjE, simp_all) |
252 apply (rule disjE, simp_all) |
254 apply (rule disjI1, rule admissibleD [OF P chain_compr [OF A]], simp) |
253 apply (rule disjI1, rule admissibleD [OF P chain_compr [OF A]], simp) |
255 apply (rule disjI2, rule admissibleD [OF Q chain_compr [OF A]], simp) |
254 apply (rule disjI2, rule admissibleD [OF Q chain_compr [OF A]], simp) |
256 done |
255 done |
257 qed |
256 qed |
258 |
257 |
259 end |
258 end |
260 |
259 |
261 hide_const (open) lub iterates fixp admissible |
260 instance complete_lattice \<subseteq> ccpo |
|
261 by default (fast intro: Sup_upper Sup_least)+ |
|
262 |
|
263 lemma lfp_eq_fixp: |
|
264 assumes f: "mono f" shows "lfp f = fixp f" |
|
265 proof (rule antisym) |
|
266 from f have f': "monotone (op \<le>) (op \<le>) f" |
|
267 unfolding mono_def monotone_def . |
|
268 show "lfp f \<le> fixp f" |
|
269 by (rule lfp_lowerbound, subst fixp_unfold [OF f'], rule order_refl) |
|
270 show "fixp f \<le> lfp f" |
|
271 by (rule fixp_lowerbound [OF f'], subst lfp_unfold [OF f], rule order_refl) |
|
272 qed |
|
273 |
|
274 hide_const (open) iterates fixp admissible |
262 |
275 |
263 end |
276 end |