4 Author: Konrad Slind |
4 Author: Konrad Slind |
5 Author: Alexander Krauss |
5 Author: Alexander Krauss |
6 Author: Andrei Popescu, TU Muenchen |
6 Author: Andrei Popescu, TU Muenchen |
7 *) |
7 *) |
8 |
8 |
9 section {*Well-founded Recursion*} |
9 section \<open>Well-founded Recursion\<close> |
10 |
10 |
11 theory Wellfounded |
11 theory Wellfounded |
12 imports Transitive_Closure |
12 imports Transitive_Closure |
13 begin |
13 begin |
14 |
14 |
15 subsection {* Basic Definitions *} |
15 subsection \<open>Basic Definitions\<close> |
16 |
16 |
17 definition wf :: "('a * 'a) set => bool" where |
17 definition wf :: "('a * 'a) set => bool" where |
18 "wf r \<longleftrightarrow> (!P. (!x. (!y. (y,x):r --> P(y)) --> P(x)) --> (!x. P(x)))" |
18 "wf r \<longleftrightarrow> (!P. (!x. (!y. (y,x):r --> P(y)) --> P(x)) --> (!x. P(x)))" |
19 |
19 |
20 definition wfP :: "('a => 'a => bool) => bool" where |
20 definition wfP :: "('a => 'a => bool) => bool" where |
27 "(!!P x. (ALL x. (ALL y. (y,x) : r --> P(y)) --> P(x)) ==> P(x)) ==> wf(r)" |
27 "(!!P x. (ALL x. (ALL y. (y,x) : r --> P(y)) --> P(x)) ==> P(x)) ==> wf(r)" |
28 unfolding wf_def by blast |
28 unfolding wf_def by blast |
29 |
29 |
30 lemmas wfPUNIVI = wfUNIVI [to_pred] |
30 lemmas wfPUNIVI = wfUNIVI [to_pred] |
31 |
31 |
32 text{*Restriction to domain @{term A} and range @{term B}. If @{term r} is |
32 text\<open>Restriction to domain @{term A} and range @{term B}. If @{term r} is |
33 well-founded over their intersection, then @{term "wf r"}*} |
33 well-founded over their intersection, then @{term "wf r"}\<close> |
34 lemma wfI: |
34 lemma wfI: |
35 "[| r \<subseteq> A <*> B; |
35 "[| r \<subseteq> A <*> B; |
36 !!x P. [|\<forall>x. (\<forall>y. (y,x) : r --> P y) --> P x; x : A; x : B |] ==> P x |] |
36 !!x P. [|\<forall>x. (\<forall>y. (y,x) : r --> P y) --> P x; x : A; x : B |] ==> P x |] |
37 ==> wf r" |
37 ==> wf r" |
38 unfolding wf_def by blast |
38 unfolding wf_def by blast |
103 assume "\<forall>x. (\<forall>y. (y, x) \<in> R \<longrightarrow> P y) \<longrightarrow> P x" |
103 assume "\<forall>x. (\<forall>y. (y, x) \<in> R \<longrightarrow> P y) \<longrightarrow> P x" |
104 then have "?A \<subseteq> R `` ?A" by blast |
104 then have "?A \<subseteq> R `` ?A" by blast |
105 with a show "P x" by blast |
105 with a show "P x" by blast |
106 qed |
106 qed |
107 |
107 |
108 text{*Minimal-element characterization of well-foundedness*} |
108 text\<open>Minimal-element characterization of well-foundedness\<close> |
109 |
109 |
110 lemma wfE_min: |
110 lemma wfE_min: |
111 assumes wf: "wf R" and Q: "x \<in> Q" |
111 assumes wf: "wf R" and Q: "x \<in> Q" |
112 obtains z where "z \<in> Q" "\<And>y. (y, z) \<in> R \<Longrightarrow> y \<notin> Q" |
112 obtains z where "z \<in> Q" "\<And>y. (y, z) \<in> R \<Longrightarrow> y \<notin> Q" |
113 using Q wfE_pf[OF wf, of Q] by blast |
113 using Q wfE_pf[OF wf, of Q] by blast |
141 fix P and x |
141 fix P and x |
142 assume induct_step: "!!x. (!!y. (y, x) : r^+ ==> P y) ==> P x" |
142 assume induct_step: "!!x. (!!y. (y, x) : r^+ ==> P y) ==> P x" |
143 have "P x" |
143 have "P x" |
144 proof (rule induct_step) |
144 proof (rule induct_step) |
145 fix y assume "(y, x) : r^+" |
145 fix y assume "(y, x) : r^+" |
146 with `wf r` show "P y" |
146 with \<open>wf r\<close> show "P y" |
147 proof (induct x arbitrary: y) |
147 proof (induct x arbitrary: y) |
148 case (less x) |
148 case (less x) |
149 note hyp = `\<And>x' y'. (x', x) : r ==> (y', x') : r^+ ==> P y'` |
149 note hyp = \<open>\<And>x' y'. (x', x) : r ==> (y', x') : r^+ ==> P y'\<close> |
150 from `(y, x) : r^+` show "P y" |
150 from \<open>(y, x) : r^+\<close> show "P y" |
151 proof cases |
151 proof cases |
152 case base |
152 case base |
153 show "P y" |
153 show "P y" |
154 proof (rule induct_step) |
154 proof (rule induct_step) |
155 fix y' assume "(y', y) : r^+" |
155 fix y' assume "(y', y) : r^+" |
156 with `(y, x) : r` show "P y'" by (rule hyp [of y y']) |
156 with \<open>(y, x) : r\<close> show "P y'" by (rule hyp [of y y']) |
157 qed |
157 qed |
158 next |
158 next |
159 case step |
159 case step |
160 then obtain x' where "(x', x) : r" and "(y, x') : r^+" by simp |
160 then obtain x' where "(x', x) : r" and "(y, x') : r^+" by simp |
161 then show "P y" by (rule hyp [of x' y]) |
161 then show "P y" by (rule hyp [of x' y]) |
170 lemma wf_converse_trancl: "wf (r^-1) ==> wf ((r^+)^-1)" |
170 lemma wf_converse_trancl: "wf (r^-1) ==> wf ((r^+)^-1)" |
171 apply (subst trancl_converse [symmetric]) |
171 apply (subst trancl_converse [symmetric]) |
172 apply (erule wf_trancl) |
172 apply (erule wf_trancl) |
173 done |
173 done |
174 |
174 |
175 text {* Well-foundedness of subsets *} |
175 text \<open>Well-foundedness of subsets\<close> |
176 |
176 |
177 lemma wf_subset: "[| wf(r); p<=r |] ==> wf(p)" |
177 lemma wf_subset: "[| wf(r); p<=r |] ==> wf(p)" |
178 apply (simp (no_asm_use) add: wf_eq_minimal) |
178 apply (simp (no_asm_use) add: wf_eq_minimal) |
179 apply fast |
179 apply fast |
180 done |
180 done |
181 |
181 |
182 lemmas wfP_subset = wf_subset [to_pred] |
182 lemmas wfP_subset = wf_subset [to_pred] |
183 |
183 |
184 text {* Well-foundedness of the empty relation *} |
184 text \<open>Well-foundedness of the empty relation\<close> |
185 |
185 |
186 lemma wf_empty [iff]: "wf {}" |
186 lemma wf_empty [iff]: "wf {}" |
187 by (simp add: wf_def) |
187 by (simp add: wf_def) |
188 |
188 |
189 lemma wfP_empty [iff]: |
189 lemma wfP_empty [iff]: |
201 lemma wf_Int2: "wf r ==> wf (r' Int r)" |
201 lemma wf_Int2: "wf r ==> wf (r' Int r)" |
202 apply (erule wf_subset) |
202 apply (erule wf_subset) |
203 apply (rule Int_lower2) |
203 apply (rule Int_lower2) |
204 done |
204 done |
205 |
205 |
206 text {* Exponentiation *} |
206 text \<open>Exponentiation\<close> |
207 |
207 |
208 lemma wf_exp: |
208 lemma wf_exp: |
209 assumes "wf (R ^^ n)" |
209 assumes "wf (R ^^ n)" |
210 shows "wf R" |
210 shows "wf R" |
211 proof (rule wfI_pf) |
211 proof (rule wfI_pf) |
212 fix A assume "A \<subseteq> R `` A" |
212 fix A assume "A \<subseteq> R `` A" |
213 then have "A \<subseteq> (R ^^ n) `` A" by (induct n) force+ |
213 then have "A \<subseteq> (R ^^ n) `` A" by (induct n) force+ |
214 with `wf (R ^^ n)` |
214 with \<open>wf (R ^^ n)\<close> |
215 show "A = {}" by (rule wfE_pf) |
215 show "A = {}" by (rule wfE_pf) |
216 qed |
216 qed |
217 |
217 |
218 text {* Well-foundedness of insert *} |
218 text \<open>Well-foundedness of insert\<close> |
219 |
219 |
220 lemma wf_insert [iff]: "wf(insert (y,x) r) = (wf(r) & (x,y) ~: r^*)" |
220 lemma wf_insert [iff]: "wf(insert (y,x) r) = (wf(r) & (x,y) ~: r^*)" |
221 apply (rule iffI) |
221 apply (rule iffI) |
222 apply (blast elim: wf_trancl [THEN wf_irrefl] |
222 apply (blast elim: wf_trancl [THEN wf_irrefl] |
223 intro: rtrancl_into_trancl1 wf_subset |
223 intro: rtrancl_into_trancl1 wf_subset |
231 apply (case_tac "y:Q") |
231 apply (case_tac "y:Q") |
232 prefer 2 apply blast |
232 prefer 2 apply blast |
233 apply (rule_tac x = "{z. z:Q & (z,y) : r^*}" in allE) |
233 apply (rule_tac x = "{z. z:Q & (z,y) : r^*}" in allE) |
234 apply assumption |
234 apply assumption |
235 apply (erule_tac V = "ALL Q. (EX x. x : Q) --> P Q" for P in thin_rl) |
235 apply (erule_tac V = "ALL Q. (EX x. x : Q) --> P Q" for P in thin_rl) |
236 --{*essential for speed*} |
236 --\<open>essential for speed\<close> |
237 txt{*Blast with new substOccur fails*} |
237 txt\<open>Blast with new substOccur fails\<close> |
238 apply (fast intro: converse_rtrancl_into_rtrancl) |
238 apply (fast intro: converse_rtrancl_into_rtrancl) |
239 done |
239 done |
240 |
240 |
241 text{*Well-foundedness of image*} |
241 text\<open>Well-foundedness of image\<close> |
242 |
242 |
243 lemma wf_map_prod_image: "[| wf r; inj f |] ==> wf (map_prod f f ` r)" |
243 lemma wf_map_prod_image: "[| wf r; inj f |] ==> wf (map_prod f f ` r)" |
244 apply (simp only: wf_eq_minimal, clarify) |
244 apply (simp only: wf_eq_minimal, clarify) |
245 apply (case_tac "EX p. f p : Q") |
245 apply (case_tac "EX p. f p : Q") |
246 apply (erule_tac x = "{p. f p : Q}" in allE) |
246 apply (erule_tac x = "{p. f p : Q}" in allE) |
247 apply (fast dest: inj_onD, blast) |
247 apply (fast dest: inj_onD, blast) |
248 done |
248 done |
249 |
249 |
250 |
250 |
251 subsection {* Well-Foundedness Results for Unions *} |
251 subsection \<open>Well-Foundedness Results for Unions\<close> |
252 |
252 |
253 lemma wf_union_compatible: |
253 lemma wf_union_compatible: |
254 assumes "wf R" "wf S" |
254 assumes "wf R" "wf S" |
255 assumes "R O S \<subseteq> R" |
255 assumes "R O S \<subseteq> R" |
256 shows "wf (R \<union> S)" |
256 shows "wf (R \<union> S)" |
257 proof (rule wfI_min) |
257 proof (rule wfI_min) |
258 fix x :: 'a and Q |
258 fix x :: 'a and Q |
259 let ?Q' = "{x \<in> Q. \<forall>y. (y, x) \<in> R \<longrightarrow> y \<notin> Q}" |
259 let ?Q' = "{x \<in> Q. \<forall>y. (y, x) \<in> R \<longrightarrow> y \<notin> Q}" |
260 assume "x \<in> Q" |
260 assume "x \<in> Q" |
261 obtain a where "a \<in> ?Q'" |
261 obtain a where "a \<in> ?Q'" |
262 by (rule wfE_min [OF `wf R` `x \<in> Q`]) blast |
262 by (rule wfE_min [OF \<open>wf R\<close> \<open>x \<in> Q\<close>]) blast |
263 with `wf S` |
263 with \<open>wf S\<close> |
264 obtain z where "z \<in> ?Q'" and zmin: "\<And>y. (y, z) \<in> S \<Longrightarrow> y \<notin> ?Q'" by (erule wfE_min) |
264 obtain z where "z \<in> ?Q'" and zmin: "\<And>y. (y, z) \<in> S \<Longrightarrow> y \<notin> ?Q'" by (erule wfE_min) |
265 { |
265 { |
266 fix y assume "(y, z) \<in> S" |
266 fix y assume "(y, z) \<in> S" |
267 then have "y \<notin> ?Q'" by (rule zmin) |
267 then have "y \<notin> ?Q'" by (rule zmin) |
268 |
268 |
269 have "y \<notin> Q" |
269 have "y \<notin> Q" |
270 proof |
270 proof |
271 assume "y \<in> Q" |
271 assume "y \<in> Q" |
272 with `y \<notin> ?Q'` |
272 with \<open>y \<notin> ?Q'\<close> |
273 obtain w where "(w, y) \<in> R" and "w \<in> Q" by auto |
273 obtain w where "(w, y) \<in> R" and "w \<in> Q" by auto |
274 from `(w, y) \<in> R` `(y, z) \<in> S` have "(w, z) \<in> R O S" by (rule relcompI) |
274 from \<open>(w, y) \<in> R\<close> \<open>(y, z) \<in> S\<close> have "(w, z) \<in> R O S" by (rule relcompI) |
275 with `R O S \<subseteq> R` have "(w, z) \<in> R" .. |
275 with \<open>R O S \<subseteq> R\<close> have "(w, z) \<in> R" .. |
276 with `z \<in> ?Q'` have "w \<notin> Q" by blast |
276 with \<open>z \<in> ?Q'\<close> have "w \<notin> Q" by blast |
277 with `w \<in> Q` show False by contradiction |
277 with \<open>w \<in> Q\<close> show False by contradiction |
278 qed |
278 qed |
279 } |
279 } |
280 with `z \<in> ?Q'` show "\<exists>z\<in>Q. \<forall>y. (y, z) \<in> R \<union> S \<longrightarrow> y \<notin> Q" by blast |
280 with \<open>z \<in> ?Q'\<close> show "\<exists>z\<in>Q. \<forall>y. (y, z) \<in> R \<union> S \<longrightarrow> y \<notin> Q" by blast |
281 qed |
281 qed |
282 |
282 |
283 |
283 |
284 text {* Well-foundedness of indexed union with disjoint domains and ranges *} |
284 text \<open>Well-foundedness of indexed union with disjoint domains and ranges\<close> |
285 |
285 |
286 lemma wf_UN: "[| ALL i:I. wf(r i); |
286 lemma wf_UN: "[| ALL i:I. wf(r i); |
287 ALL i:I. ALL j:I. r i ~= r j --> Domain(r i) Int Range(r j) = {} |
287 ALL i:I. ALL j:I. r i ~= r j --> Domain(r i) Int Range(r j) = {} |
288 |] ==> wf(UN i:I. r i)" |
288 |] ==> wf(UN i:I. r i)" |
289 apply (simp only: wf_eq_minimal, clarify) |
289 apply (simp only: wf_eq_minimal, clarify) |
338 show "wf ?A" |
338 show "wf ?A" |
339 proof (rule wfI_min) |
339 proof (rule wfI_min) |
340 fix Q :: "'a set" and x |
340 fix Q :: "'a set" and x |
341 assume "x \<in> Q" |
341 assume "x \<in> Q" |
342 |
342 |
343 with `wf ?B` |
343 with \<open>wf ?B\<close> |
344 obtain z where "z \<in> Q" and "\<And>y. (y, z) \<in> ?B \<Longrightarrow> y \<notin> Q" |
344 obtain z where "z \<in> Q" and "\<And>y. (y, z) \<in> ?B \<Longrightarrow> y \<notin> Q" |
345 by (erule wfE_min) |
345 by (erule wfE_min) |
346 then have A1: "\<And>y. (y, z) \<in> R O R \<Longrightarrow> y \<notin> Q" |
346 then have A1: "\<And>y. (y, z) \<in> R O R \<Longrightarrow> y \<notin> Q" |
347 and A2: "\<And>y. (y, z) \<in> S O R \<Longrightarrow> y \<notin> Q" |
347 and A2: "\<And>y. (y, z) \<in> S O R \<Longrightarrow> y \<notin> Q" |
348 and A3: "\<And>y. (y, z) \<in> S \<Longrightarrow> y \<notin> Q" |
348 and A3: "\<And>y. (y, z) \<in> S \<Longrightarrow> y \<notin> Q" |
349 by auto |
349 by auto |
350 |
350 |
351 show "\<exists>z\<in>Q. \<forall>y. (y, z) \<in> ?A \<longrightarrow> y \<notin> Q" |
351 show "\<exists>z\<in>Q. \<forall>y. (y, z) \<in> ?A \<longrightarrow> y \<notin> Q" |
352 proof (cases "\<forall>y. (y, z) \<in> R \<longrightarrow> y \<notin> Q") |
352 proof (cases "\<forall>y. (y, z) \<in> R \<longrightarrow> y \<notin> Q") |
353 case True |
353 case True |
354 with `z \<in> Q` A3 show ?thesis by blast |
354 with \<open>z \<in> Q\<close> A3 show ?thesis by blast |
355 next |
355 next |
356 case False |
356 case False |
357 then obtain z' where "z'\<in>Q" "(z', z) \<in> R" by blast |
357 then obtain z' where "z'\<in>Q" "(z', z) \<in> R" by blast |
358 |
358 |
359 have "\<forall>y. (y, z') \<in> ?A \<longrightarrow> y \<notin> Q" |
359 have "\<forall>y. (y, z') \<in> ?A \<longrightarrow> y \<notin> Q" |
360 proof (intro allI impI) |
360 proof (intro allI impI) |
361 fix y assume "(y, z') \<in> ?A" |
361 fix y assume "(y, z') \<in> ?A" |
362 then show "y \<notin> Q" |
362 then show "y \<notin> Q" |
363 proof |
363 proof |
364 assume "(y, z') \<in> R" |
364 assume "(y, z') \<in> R" |
365 then have "(y, z) \<in> R O R" using `(z', z) \<in> R` .. |
365 then have "(y, z) \<in> R O R" using \<open>(z', z) \<in> R\<close> .. |
366 with A1 show "y \<notin> Q" . |
366 with A1 show "y \<notin> Q" . |
367 next |
367 next |
368 assume "(y, z') \<in> S" |
368 assume "(y, z') \<in> S" |
369 then have "(y, z) \<in> S O R" using `(z', z) \<in> R` .. |
369 then have "(y, z) \<in> S O R" using \<open>(z', z) \<in> R\<close> .. |
370 with A2 show "y \<notin> Q" . |
370 with A2 show "y \<notin> Q" . |
371 qed |
371 qed |
372 qed |
372 qed |
373 with `z' \<in> Q` show ?thesis .. |
373 with \<open>z' \<in> Q\<close> show ?thesis .. |
374 qed |
374 qed |
375 qed |
375 qed |
376 qed |
376 qed |
377 |
377 |
378 lemma wf_comp_self: "wf R = wf (R O R)" -- {* special case *} |
378 lemma wf_comp_self: "wf R = wf (R O R)" -- \<open>special case\<close> |
379 by (rule wf_union_merge [where S = "{}", simplified]) |
379 by (rule wf_union_merge [where S = "{}", simplified]) |
380 |
380 |
381 |
381 |
382 subsection {* Well-Foundedness of Composition *} |
382 subsection \<open>Well-Foundedness of Composition\<close> |
383 |
383 |
384 text \<open>Bachmair and Dershowitz 1986, Lemma 2. [Provided by Tjark Weber]\<close> |
384 text \<open>Bachmair and Dershowitz 1986, Lemma 2. [Provided by Tjark Weber]\<close> |
385 |
385 |
386 lemma qc_wf_relto_iff: |
386 lemma qc_wf_relto_iff: |
387 assumes "R O S \<subseteq> (R \<union> S)\<^sup>* O R" -- \<open>R quasi-commutes over S\<close> |
387 assumes "R O S \<subseteq> (R \<union> S)\<^sup>* O R" -- \<open>R quasi-commutes over S\<close> |
435 then show ?thesis |
435 then show ?thesis |
436 by (rule Wellfounded.wf_subset) blast |
436 by (rule Wellfounded.wf_subset) blast |
437 qed |
437 qed |
438 |
438 |
439 |
439 |
440 subsection {* Acyclic relations *} |
440 subsection \<open>Acyclic relations\<close> |
441 |
441 |
442 lemma wf_acyclic: "wf r ==> acyclic r" |
442 lemma wf_acyclic: "wf r ==> acyclic r" |
443 apply (simp add: acyclic_def) |
443 apply (simp add: acyclic_def) |
444 apply (blast elim: wf_trancl [THEN wf_irrefl]) |
444 apply (blast elim: wf_trancl [THEN wf_irrefl]) |
445 done |
445 done |
446 |
446 |
447 lemmas wfP_acyclicP = wf_acyclic [to_pred] |
447 lemmas wfP_acyclicP = wf_acyclic [to_pred] |
448 |
448 |
449 text{* Wellfoundedness of finite acyclic relations*} |
449 text\<open>Wellfoundedness of finite acyclic relations\<close> |
450 |
450 |
451 lemma finite_acyclic_wf [rule_format]: "finite r ==> acyclic r --> wf r" |
451 lemma finite_acyclic_wf [rule_format]: "finite r ==> acyclic r --> wf r" |
452 apply (erule finite_induct, blast) |
452 apply (erule finite_induct, blast) |
453 apply (simp (no_asm_simp) only: split_tupled_all) |
453 apply (simp (no_asm_simp) only: split_tupled_all) |
454 apply simp |
454 apply simp |
628 by (blast intro: accp.accI) |
628 by (blast intro: accp.accI) |
629 qed |
629 qed |
630 qed |
630 qed |
631 |
631 |
632 |
632 |
633 text {* This is a generalized induction theorem that works on |
633 text \<open>This is a generalized induction theorem that works on |
634 subsets of the accessible part. *} |
634 subsets of the accessible part.\<close> |
635 |
635 |
636 lemma accp_subset_induct: |
636 lemma accp_subset_induct: |
637 assumes subset: "D \<le> accp R" |
637 assumes subset: "D \<le> accp R" |
638 and dcl: "\<And>x z. \<lbrakk>D x; R z x\<rbrakk> \<Longrightarrow> D z" |
638 and dcl: "\<And>x z. \<lbrakk>D x; R z x\<rbrakk> \<Longrightarrow> D z" |
639 and "D x" |
639 and "D x" |
640 and istep: "\<And>x. \<lbrakk>D x; (\<And>z. R z x \<Longrightarrow> P z)\<rbrakk> \<Longrightarrow> P x" |
640 and istep: "\<And>x. \<lbrakk>D x; (\<And>z. R z x \<Longrightarrow> P z)\<rbrakk> \<Longrightarrow> P x" |
641 shows "P x" |
641 shows "P x" |
642 proof - |
642 proof - |
643 from subset and `D x` |
643 from subset and \<open>D x\<close> |
644 have "accp R x" .. |
644 have "accp R x" .. |
645 then show "P x" using `D x` |
645 then show "P x" using \<open>D x\<close> |
646 proof (induct x) |
646 proof (induct x) |
647 fix x |
647 fix x |
648 assume "D x" |
648 assume "D x" |
649 and "\<And>y. R y x \<Longrightarrow> D y \<Longrightarrow> P y" |
649 and "\<And>y. R y x \<Longrightarrow> D y \<Longrightarrow> P y" |
650 with dcl and istep show "P x" by blast |
650 with dcl and istep show "P x" by blast |
651 qed |
651 qed |
652 qed |
652 qed |
653 |
653 |
654 |
654 |
655 text {* Set versions of the above theorems *} |
655 text \<open>Set versions of the above theorems\<close> |
656 |
656 |
657 lemmas acc_induct = accp_induct [to_set] |
657 lemmas acc_induct = accp_induct [to_set] |
658 |
658 |
659 lemmas acc_induct_rule = acc_induct [rule_format, induct set: acc] |
659 lemmas acc_induct_rule = acc_induct [rule_format, induct set: acc] |
660 |
660 |
729 |
729 |
730 lemma in_lex_prod[simp]: |
730 lemma in_lex_prod[simp]: |
731 "(((a,b),(a',b')): r <*lex*> s) = ((a,a'): r \<or> (a = a' \<and> (b, b') : s))" |
731 "(((a,b),(a',b')): r <*lex*> s) = ((a,a'): r \<or> (a = a' \<and> (b, b') : s))" |
732 by (auto simp:lex_prod_def) |
732 by (auto simp:lex_prod_def) |
733 |
733 |
734 text{* @{term "op <*lex*>"} preserves transitivity *} |
734 text\<open>@{term "op <*lex*>"} preserves transitivity\<close> |
735 |
735 |
736 lemma trans_lex_prod [intro!]: |
736 lemma trans_lex_prod [intro!]: |
737 "[| trans R1; trans R2 |] ==> trans (R1 <*lex*> R2)" |
737 "[| trans R1; trans R2 |] ==> trans (R1 <*lex*> R2)" |
738 by (unfold trans_def lex_prod_def, blast) |
738 by (unfold trans_def lex_prod_def, blast) |
739 |
739 |
740 text {* lexicographic combinations with measure functions *} |
740 text \<open>lexicographic combinations with measure functions\<close> |
741 |
741 |
742 definition |
742 definition |
743 mlex_prod :: "('a \<Rightarrow> nat) \<Rightarrow> ('a \<times> 'a) set \<Rightarrow> ('a \<times> 'a) set" (infixr "<*mlex*>" 80) |
743 mlex_prod :: "('a \<Rightarrow> nat) \<Rightarrow> ('a \<times> 'a) set \<Rightarrow> ('a \<times> 'a) set" (infixr "<*mlex*>" 80) |
744 where |
744 where |
745 "f <*mlex*> R = inv_image (less_than <*lex*> R) (%x. (f x, x))" |
745 "f <*mlex*> R = inv_image (less_than <*lex*> R) (%x. (f x, x))" |
752 unfolding mlex_prod_def by simp |
752 unfolding mlex_prod_def by simp |
753 |
753 |
754 lemma mlex_leq: "f x \<le> f y \<Longrightarrow> (x, y) \<in> R \<Longrightarrow> (x, y) \<in> f <*mlex*> R" |
754 lemma mlex_leq: "f x \<le> f y \<Longrightarrow> (x, y) \<in> R \<Longrightarrow> (x, y) \<in> f <*mlex*> R" |
755 unfolding mlex_prod_def by auto |
755 unfolding mlex_prod_def by auto |
756 |
756 |
757 text {* proper subset relation on finite sets *} |
757 text \<open>proper subset relation on finite sets\<close> |
758 |
758 |
759 definition finite_psubset :: "('a set * 'a set) set" |
759 definition finite_psubset :: "('a set * 'a set) set" |
760 where "finite_psubset = {(A,B). A < B & finite B}" |
760 where "finite_psubset = {(A,B). A < B & finite B}" |
761 |
761 |
762 lemma wf_finite_psubset[simp]: "wf(finite_psubset)" |
762 lemma wf_finite_psubset[simp]: "wf(finite_psubset)" |
770 by (simp add: finite_psubset_def less_le trans_def, blast) |
770 by (simp add: finite_psubset_def less_le trans_def, blast) |
771 |
771 |
772 lemma in_finite_psubset[simp]: "(A, B) \<in> finite_psubset = (A < B & finite B)" |
772 lemma in_finite_psubset[simp]: "(A, B) \<in> finite_psubset = (A < B & finite B)" |
773 unfolding finite_psubset_def by auto |
773 unfolding finite_psubset_def by auto |
774 |
774 |
775 text {* max- and min-extension of order to finite sets *} |
775 text \<open>max- and min-extension of order to finite sets\<close> |
776 |
776 |
777 inductive_set max_ext :: "('a \<times> 'a) set \<Rightarrow> ('a set \<times> 'a set) set" |
777 inductive_set max_ext :: "('a \<times> 'a) set \<Rightarrow> ('a set \<times> 'a set) set" |
778 for R :: "('a \<times> 'a) set" |
778 for R :: "('a \<times> 'a) set" |
779 where |
779 where |
780 max_extI[intro]: "finite X \<Longrightarrow> finite Y \<Longrightarrow> Y \<noteq> {} \<Longrightarrow> (\<And>x. x \<in> X \<Longrightarrow> \<exists>y\<in>Y. (x, y) \<in> R) \<Longrightarrow> (X, Y) \<in> max_ext R" |
780 max_extI[intro]: "finite X \<Longrightarrow> finite Y \<Longrightarrow> Y \<noteq> {} \<Longrightarrow> (\<And>x. x \<in> X \<Longrightarrow> \<exists>y\<in>Y. (x, y) \<in> R) \<Longrightarrow> (X, Y) \<in> max_ext R" |
826 from asm1 have "?N2 = {}" by auto |
826 from asm1 have "?N2 = {}" by auto |
827 with Mw show "?N2 \<in> ?W" by (simp only:) |
827 with Mw show "?N2 \<in> ?W" by (simp only:) |
828 next |
828 next |
829 assume "M \<noteq> {}" |
829 assume "M \<noteq> {}" |
830 from asm1 finites have N2: "(?N2, M) \<in> max_ext r" |
830 from asm1 finites have N2: "(?N2, M) \<in> max_ext r" |
831 by (rule_tac max_extI[OF _ _ `M \<noteq> {}`]) auto |
831 by (rule_tac max_extI[OF _ _ \<open>M \<noteq> {}\<close>]) auto |
832 |
832 |
833 with `M \<in> ?W` show "?N2 \<in> ?W" by (rule acc_downward) |
833 with \<open>M \<in> ?W\<close> show "?N2 \<in> ?W" by (rule acc_downward) |
834 qed |
834 qed |
835 with finites have "?N1 \<union> ?N2 \<in> ?W" |
835 with finites have "?N1 \<union> ?N2 \<in> ?W" |
836 by (rule add_less) simp |
836 by (rule add_less) simp |
837 then show "N \<in> ?W" by (simp only: N) |
837 then show "N \<in> ?W" by (simp only: N) |
838 qed |
838 qed |
867 next |
867 next |
868 assume "Q \<noteq> {{}}" |
868 assume "Q \<noteq> {{}}" |
869 with nonempty |
869 with nonempty |
870 obtain e x where "x \<in> Q" "e \<in> x" by force |
870 obtain e x where "x \<in> Q" "e \<in> x" by force |
871 then have eU: "e \<in> \<Union>Q" by auto |
871 then have eU: "e \<in> \<Union>Q" by auto |
872 with `wf r` |
872 with \<open>wf r\<close> |
873 obtain z where z: "z \<in> \<Union>Q" "\<And>y. (y, z) \<in> r \<Longrightarrow> y \<notin> \<Union>Q" |
873 obtain z where z: "z \<in> \<Union>Q" "\<And>y. (y, z) \<in> r \<Longrightarrow> y \<notin> \<Union>Q" |
874 by (erule wfE_min) |
874 by (erule wfE_min) |
875 from z obtain m where "m \<in> Q" "z \<in> m" by auto |
875 from z obtain m where "m \<in> Q" "z \<in> m" by auto |
876 from `m \<in> Q` |
876 from \<open>m \<in> Q\<close> |
877 show ?thesis |
877 show ?thesis |
878 proof (rule, intro bexI allI impI) |
878 proof (rule, intro bexI allI impI) |
879 fix n |
879 fix n |
880 assume smaller: "(n, m) \<in> min_ext r" |
880 assume smaller: "(n, m) \<in> min_ext r" |
881 with `z \<in> m` obtain y where y: "y \<in> n" "(y, z) \<in> r" by (auto simp: min_ext_def) |
881 with \<open>z \<in> m\<close> obtain y where y: "y \<in> n" "(y, z) \<in> r" by (auto simp: min_ext_def) |
882 then show "n \<notin> Q" using z(2) by auto |
882 then show "n \<notin> Q" using z(2) by auto |
883 qed |
883 qed |
884 qed |
884 qed |
885 qed |
885 qed |
886 |
886 |
887 text{* Bounded increase must terminate: *} |
887 text\<open>Bounded increase must terminate:\<close> |
888 |
888 |
889 lemma wf_bounded_measure: |
889 lemma wf_bounded_measure: |
890 fixes ub :: "'a \<Rightarrow> nat" and f :: "'a \<Rightarrow> nat" |
890 fixes ub :: "'a \<Rightarrow> nat" and f :: "'a \<Rightarrow> nat" |
891 assumes "!!a b. (b,a) : r \<Longrightarrow> ub b \<le> ub a & ub a \<ge> f b & f b > f a" |
891 assumes "!!a b. (b,a) : r \<Longrightarrow> ub b \<le> ub a & ub a \<ge> f b & f b > f a" |
892 shows "wf r" |
892 shows "wf r" |