184 |
184 |
185 lemma is_lub_bigger2 [iff]: |
185 lemma is_lub_bigger2 [iff]: |
186 "is_lub (r^* ) x y x = ((y,x):r^* )" |
186 "is_lub (r^* ) x y x = ((y,x):r^* )" |
187 apply (unfold is_lub_def is_ub_def) |
187 apply (unfold is_lub_def is_ub_def) |
188 apply blast |
188 apply blast |
189 done |
189 done |
190 |
190 |
191 lemma extend_lub: |
191 lemma extend_lub: |
192 "[| single_valued r; is_lub (r^* ) x y u; (x',x) : r |] |
192 "[| single_valued r; is_lub (r^* ) x y u; (x',x) : r |] |
193 ==> EX v. is_lub (r^* ) x' y v" |
193 ==> EX v. is_lub (r^* ) x' y v" |
194 apply (unfold is_lub_def is_ub_def) |
194 apply (unfold is_lub_def is_ub_def) |
199 apply (rule exI) |
199 apply (rule exI) |
200 apply (rule conjI) |
200 apply (rule conjI) |
201 apply (blast intro: rtrancl_into_rtrancl2 dest: single_valuedD) |
201 apply (blast intro: rtrancl_into_rtrancl2 dest: single_valuedD) |
202 apply (blast intro: rtrancl_into_rtrancl rtrancl_into_rtrancl2 |
202 apply (blast intro: rtrancl_into_rtrancl rtrancl_into_rtrancl2 |
203 elim: converse_rtranclE dest: single_valuedD) |
203 elim: converse_rtranclE dest: single_valuedD) |
204 done |
204 done |
205 |
205 |
206 lemma single_valued_has_lubs [rule_format]: |
206 lemma single_valued_has_lubs [rule_format]: |
207 "[| single_valued r; (x,u) : r^* |] ==> (!y. (y,u) : r^* --> |
207 "[| single_valued r; (x,u) : r^* |] ==> (!y. (y,u) : r^* --> |
208 (EX z. is_lub (r^* ) x y z))" |
208 (EX z. is_lub (r^* ) x y z))" |
209 apply (erule converse_rtrancl_induct) |
209 apply (erule converse_rtrancl_induct) |
218 "[| acyclic r; is_lub (r^* ) x y u |] ==> some_lub (r^* ) x y = u" |
218 "[| acyclic r; is_lub (r^* ) x y u |] ==> some_lub (r^* ) x y = u" |
219 apply (unfold some_lub_def is_lub_def) |
219 apply (unfold some_lub_def is_lub_def) |
220 apply (rule someI2) |
220 apply (rule someI2) |
221 apply assumption |
221 apply assumption |
222 apply (blast intro: antisymD dest!: acyclic_impl_antisym_rtrancl) |
222 apply (blast intro: antisymD dest!: acyclic_impl_antisym_rtrancl) |
223 done |
223 done |
224 |
224 |
225 lemma is_lub_some_lub: |
225 lemma is_lub_some_lub: |
226 "[| single_valued r; acyclic r; (x,u):r^*; (y,u):r^* |] |
226 "[| single_valued r; acyclic r; (x,u):r^*; (y,u):r^* |] |
227 ==> is_lub (r^* ) x y (some_lub (r^* ) x y)"; |
227 ==> is_lub (r^* ) x y (some_lub (r^* ) x y)"; |
228 by (fastsimp dest: single_valued_has_lubs simp add: some_lub_conv) |
228 by (fastsimp dest: single_valued_has_lubs simp add: some_lub_conv) |
229 |
229 |
|
230 subsection{*An executable lub-finder*} |
|
231 |
|
232 constdefs |
|
233 exec_lub :: "('a * 'a) set \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a binop" |
|
234 "exec_lub r f x y == while (\<lambda>z. (x,z) \<notin> r\<^sup>*) f y" |
|
235 |
|
236 |
|
237 lemma acyclic_single_valued_finite: |
|
238 "\<lbrakk>acyclic r; single_valued r; (x,y) \<in> r\<^sup>*\<rbrakk> |
|
239 \<Longrightarrow> finite (r \<inter> {a. (x, a) \<in> r\<^sup>*} \<times> {b. (b, y) \<in> r\<^sup>*})" |
|
240 apply(erule converse_rtrancl_induct) |
|
241 apply(rule_tac B = "{}" in finite_subset) |
|
242 apply(simp only:acyclic_def) |
|
243 apply(blast intro:rtrancl_into_trancl2 rtrancl_trancl_trancl) |
|
244 apply simp |
|
245 apply(rename_tac x x') |
|
246 apply(subgoal_tac "r \<inter> {a. (x,a) \<in> r\<^sup>*} \<times> {b. (b,y) \<in> r\<^sup>*} = |
|
247 insert (x,x') (r \<inter> {a. (x', a) \<in> r\<^sup>*} \<times> {b. (b, y) \<in> r\<^sup>*})") |
|
248 apply simp |
|
249 apply(blast intro:rtrancl_into_rtrancl2 |
|
250 elim:converse_rtranclE dest:single_valuedD) |
|
251 done |
|
252 |
|
253 |
|
254 lemma "\<lbrakk> acyclic r; !x y. (x,y) \<in> r \<longrightarrow> f x = y; is_lub (r\<^sup>*) x y u \<rbrakk> \<Longrightarrow> |
|
255 exec_lub r f x y = u"; |
|
256 apply(unfold exec_lub_def) |
|
257 apply(rule_tac P = "\<lambda>z. (y,z) \<in> r\<^sup>* \<and> (z,u) \<in> r\<^sup>*" and |
|
258 r = "(r \<inter> {(a,b). (y,a) \<in> r\<^sup>* \<and> (b,u) \<in> r\<^sup>*})^-1" in while_rule) |
|
259 apply(blast dest: is_lubD is_ubD) |
|
260 apply(erule conjE) |
|
261 apply(erule_tac z = u in converse_rtranclE) |
|
262 apply(blast dest: is_lubD is_ubD) |
|
263 apply(blast dest:rtrancl_into_rtrancl) |
|
264 apply(rename_tac s) |
|
265 apply(subgoal_tac "is_ub (r\<^sup>*) x y s") |
|
266 prefer 2; apply(simp add:is_ub_def) |
|
267 apply(subgoal_tac "(u, s) \<in> r\<^sup>*") |
|
268 prefer 2; apply(blast dest:is_lubD) |
|
269 apply(erule converse_rtranclE) |
|
270 apply blast |
|
271 apply(simp only:acyclic_def) |
|
272 apply(blast intro:rtrancl_into_trancl2 rtrancl_trancl_trancl) |
|
273 apply(rule finite_acyclic_wf) |
|
274 apply simp |
|
275 apply(erule acyclic_single_valued_finite) |
|
276 apply(blast intro:single_valuedI) |
|
277 apply(simp add:is_lub_def is_ub_def) |
|
278 apply simp |
|
279 apply(erule acyclic_subset) |
|
280 apply blast |
|
281 apply simp |
|
282 apply(erule conjE) |
|
283 apply(erule_tac z = u in converse_rtranclE) |
|
284 apply(blast dest: is_lubD is_ubD) |
|
285 apply(blast dest:rtrancl_into_rtrancl) |
|
286 done |
|
287 |
230 end |
288 end |