23 (*** Well-founded relations ***) |
23 (*** Well-founded relations ***) |
24 |
24 |
25 (** Equivalences between wf and wf_on **) |
25 (** Equivalences between wf and wf_on **) |
26 |
26 |
27 goalw WF.thy [wf_def, wf_on_def] "!!A r. wf(r) ==> wf[A](r)"; |
27 goalw WF.thy [wf_def, wf_on_def] "!!A r. wf(r) ==> wf[A](r)"; |
28 by (Fast_tac 1); |
28 by (Blast_tac 1); |
29 qed "wf_imp_wf_on"; |
29 qed "wf_imp_wf_on"; |
30 |
30 |
31 goalw WF.thy [wf_def, wf_on_def] "!!r. wf[field(r)](r) ==> wf(r)"; |
31 goalw WF.thy [wf_def, wf_on_def] "!!r. wf[field(r)](r) ==> wf(r)"; |
32 by (Fast_tac 1); |
32 by (Fast_tac 1); |
33 qed "wf_on_field_imp_wf"; |
33 qed "wf_on_field_imp_wf"; |
34 |
34 |
35 goal WF.thy "wf(r) <-> wf[field(r)](r)"; |
35 goal WF.thy "wf(r) <-> wf[field(r)](r)"; |
36 by (fast_tac (!claset addSEs [wf_imp_wf_on, wf_on_field_imp_wf]) 1); |
36 by (blast_tac (!claset addIs [wf_imp_wf_on, wf_on_field_imp_wf]) 1); |
37 qed "wf_iff_wf_on_field"; |
37 qed "wf_iff_wf_on_field"; |
38 |
38 |
39 goalw WF.thy [wf_on_def, wf_def] "!!A B r. [| wf[A](r); B<=A |] ==> wf[B](r)"; |
39 goalw WF.thy [wf_on_def, wf_def] "!!A B r. [| wf[A](r); B<=A |] ==> wf[B](r)"; |
40 by (Fast_tac 1); |
40 by (Fast_tac 1); |
41 qed "wf_on_subset_A"; |
41 qed "wf_on_subset_A"; |
50 val [prem] = goalw WF.thy [wf_on_def, wf_def] |
50 val [prem] = goalw WF.thy [wf_on_def, wf_def] |
51 "[| !!Z u. [| Z<=A; u:Z; ALL x:Z. EX y:Z. <y,x>:r |] ==> False |] \ |
51 "[| !!Z u. [| Z<=A; u:Z; ALL x:Z. EX y:Z. <y,x>:r |] ==> False |] \ |
52 \ ==> wf[A](r)"; |
52 \ ==> wf[A](r)"; |
53 by (rtac (equals0I RS disjCI RS allI) 1); |
53 by (rtac (equals0I RS disjCI RS allI) 1); |
54 by (res_inst_tac [ ("Z", "Z") ] prem 1); |
54 by (res_inst_tac [ ("Z", "Z") ] prem 1); |
55 by (ALLGOALS (Fast_tac)); |
55 by (ALLGOALS Blast_tac); |
56 qed "wf_onI"; |
56 qed "wf_onI"; |
57 |
57 |
58 (*If r allows well-founded induction over A then wf[A](r) |
58 (*If r allows well-founded induction over A then wf[A](r) |
59 Premise is equivalent to |
59 Premise is equivalent to |
60 !!B. ALL x:A. (ALL y. <y,x>: r --> y:B) --> x:B ==> A<=B *) |
60 !!B. ALL x:A. (ALL y. <y,x>: r --> y:B) --> x:B ==> A<=B *) |
77 "[| wf(r); \ |
77 "[| wf(r); \ |
78 \ !!x.[| ALL y. <y,x>: r --> P(y) |] ==> P(x) \ |
78 \ !!x.[| ALL y. <y,x>: r --> P(y) |] ==> P(x) \ |
79 \ |] ==> P(a)"; |
79 \ |] ==> P(a)"; |
80 by (res_inst_tac [ ("x", "{z:domain(r) Un {a}. ~P(z)}") ] (major RS allE) 1); |
80 by (res_inst_tac [ ("x", "{z:domain(r) Un {a}. ~P(z)}") ] (major RS allE) 1); |
81 by (etac disjE 1); |
81 by (etac disjE 1); |
82 by (fast_tac (!claset addEs [equalityE]) 1); |
82 by (blast_tac (!claset addEs [equalityE]) 1); |
83 by (asm_full_simp_tac (!simpset addsimps [domainI]) 1); |
83 by (asm_full_simp_tac (!simpset addsimps [domainI]) 1); |
84 by (fast_tac (!claset addSDs [minor]) 1); |
84 by (blast_tac (!claset addSDs [minor]) 1); |
85 qed "wf_induct"; |
85 qed "wf_induct"; |
86 |
86 |
87 (*Perform induction on i, then prove the wf(r) subgoal using prems. *) |
87 (*Perform induction on i, then prove the wf(r) subgoal using prems. *) |
88 fun wf_ind_tac a prems i = |
88 fun wf_ind_tac a prems i = |
89 EVERY [res_inst_tac [("a",a)] wf_induct i, |
89 EVERY [res_inst_tac [("a",a)] wf_induct i, |
97 \ |] ==> P(a)"; |
97 \ |] ==> P(a)"; |
98 by (rtac (amem RS rev_mp) 1); |
98 by (rtac (amem RS rev_mp) 1); |
99 by (wf_ind_tac "a" [wfr] 1); |
99 by (wf_ind_tac "a" [wfr] 1); |
100 by (rtac impI 1); |
100 by (rtac impI 1); |
101 by (eresolve_tac prems 1); |
101 by (eresolve_tac prems 1); |
102 by (fast_tac (!claset addIs (prems RL [subsetD])) 1); |
102 by (blast_tac (!claset addIs (prems RL [subsetD])) 1); |
103 qed "wf_induct2"; |
103 qed "wf_induct2"; |
104 |
104 |
105 goal domrange.thy "!!r A. field(r Int A*A) <= A"; |
105 goal domrange.thy "!!r A. field(r Int A*A) <= A"; |
106 by (Fast_tac 1); |
106 by (Blast_tac 1); |
107 qed "field_Int_square"; |
107 qed "field_Int_square"; |
108 |
108 |
109 val wfr::amem::prems = goalw WF.thy [wf_on_def] |
109 val wfr::amem::prems = goalw WF.thy [wf_on_def] |
110 "[| wf[A](r); a:A; \ |
110 "[| wf[A](r); a:A; \ |
111 \ !!x.[| x: A; ALL y:A. <y,x>: r --> P(y) |] ==> P(x) \ |
111 \ !!x.[| x: A; ALL y:A. <y,x>: r --> P(y) |] ==> P(x) \ |
112 \ |] ==> P(a)"; |
112 \ |] ==> P(a)"; |
113 by (rtac ([wfr, amem, field_Int_square] MRS wf_induct2) 1); |
113 by (rtac ([wfr, amem, field_Int_square] MRS wf_induct2) 1); |
114 by (REPEAT (ares_tac prems 1)); |
114 by (REPEAT (ares_tac prems 1)); |
115 by (Fast_tac 1); |
115 by (Blast_tac 1); |
116 qed "wf_on_induct"; |
116 qed "wf_on_induct"; |
117 |
117 |
118 fun wf_on_ind_tac a prems i = |
118 fun wf_on_ind_tac a prems i = |
119 EVERY [res_inst_tac [("a",a)] wf_on_induct i, |
119 EVERY [res_inst_tac [("a",a)] wf_on_induct i, |
120 rename_last_tac a ["1"] (i+2), |
120 rename_last_tac a ["1"] (i+2), |
133 |
133 |
134 (*** Properties of well-founded relations ***) |
134 (*** Properties of well-founded relations ***) |
135 |
135 |
136 goal WF.thy "!!r. wf(r) ==> <a,a> ~: r"; |
136 goal WF.thy "!!r. wf(r) ==> <a,a> ~: r"; |
137 by (wf_ind_tac "a" [] 1); |
137 by (wf_ind_tac "a" [] 1); |
138 by (Fast_tac 1); |
138 by (Blast_tac 1); |
139 qed "wf_not_refl"; |
139 qed "wf_not_refl"; |
140 |
140 |
141 goal WF.thy "!!r. [| wf(r); <a,x>:r; <x,a>:r |] ==> P"; |
141 goal WF.thy "!!r. [| wf(r); <a,x>:r; <x,a>:r |] ==> P"; |
142 by (subgoal_tac "ALL x. <a,x>:r --> <x,a>:r --> P" 1); |
142 by (subgoal_tac "ALL x. <a,x>:r --> <x,a>:r --> P" 1); |
143 by (wf_ind_tac "a" [] 2); |
143 by (wf_ind_tac "a" [] 2); |
144 by (Fast_tac 2); |
144 by (Blast_tac 2); |
145 by (Fast_tac 1); |
145 by (Blast_tac 1); |
146 qed "wf_asym"; |
146 qed "wf_asym"; |
147 |
147 |
148 goal WF.thy "!!r. [| wf[A](r); a: A |] ==> <a,a> ~: r"; |
148 goal WF.thy "!!r. [| wf[A](r); a: A |] ==> <a,a> ~: r"; |
149 by (wf_on_ind_tac "a" [] 1); |
149 by (wf_on_ind_tac "a" [] 1); |
150 by (Fast_tac 1); |
150 by (Blast_tac 1); |
151 qed "wf_on_not_refl"; |
151 qed "wf_on_not_refl"; |
152 |
152 |
153 goal WF.thy "!!r. [| wf[A](r); <a,b>:r; <b,a>:r; a:A; b:A |] ==> P"; |
153 goal WF.thy "!!r. [| wf[A](r); <a,b>:r; <b,a>:r; a:A; b:A |] ==> P"; |
154 by (subgoal_tac "ALL y:A. <a,y>:r --> <y,a>:r --> P" 1); |
154 by (subgoal_tac "ALL y:A. <a,y>:r --> <y,a>:r --> P" 1); |
155 by (wf_on_ind_tac "a" [] 2); |
155 by (wf_on_ind_tac "a" [] 2); |
156 by (Fast_tac 2); |
156 by (Blast_tac 2); |
157 by (Fast_tac 1); |
157 by (Blast_tac 1); |
158 qed "wf_on_asym"; |
158 qed "wf_on_asym"; |
159 |
159 |
160 (*Needed to prove well_ordI. Could also reason that wf[A](r) means |
160 (*Needed to prove well_ordI. Could also reason that wf[A](r) means |
161 wf(r Int A*A); thus wf( (r Int A*A)^+ ) and use wf_not_refl *) |
161 wf(r Int A*A); thus wf( (r Int A*A)^+ ) and use wf_not_refl *) |
162 goal WF.thy |
162 goal WF.thy |
163 "!!r. [| wf[A](r); <a,b>:r; <b,c>:r; <c,a>:r; a:A; b:A; c:A |] ==> P"; |
163 "!!r. [| wf[A](r); <a,b>:r; <b,c>:r; <c,a>:r; a:A; b:A; c:A |] ==> P"; |
164 by (subgoal_tac |
164 by (subgoal_tac |
165 "ALL y:A. ALL z:A. <a,y>:r --> <y,z>:r --> <z,a>:r --> P" 1); |
165 "ALL y:A. ALL z:A. <a,y>:r --> <y,z>:r --> <z,a>:r --> P" 1); |
166 by (wf_on_ind_tac "a" [] 2); |
166 by (wf_on_ind_tac "a" [] 2); |
167 by (Fast_tac 2); |
167 by (Blast_tac 2); |
168 by (Fast_tac 1); |
168 by (Blast_tac 1); |
169 qed "wf_on_chain3"; |
169 qed "wf_on_chain3"; |
170 |
170 |
171 |
171 |
172 (*retains the universal formula for later use!*) |
172 (*retains the universal formula for later use!*) |
173 val bchain_tac = EVERY' [rtac (bspec RS mp), assume_tac, assume_tac ]; |
173 val bchain_tac = EVERY' [rtac (bspec RS mp), assume_tac, assume_tac ]; |
176 val [wfr,subs] = goal WF.thy |
176 val [wfr,subs] = goal WF.thy |
177 "[| wf[A](r); r-``A <= A |] ==> wf[A](r^+)"; |
177 "[| wf[A](r); r-``A <= A |] ==> wf[A](r^+)"; |
178 by (rtac wf_onI2 1); |
178 by (rtac wf_onI2 1); |
179 by (bchain_tac 1); |
179 by (bchain_tac 1); |
180 by (eres_inst_tac [("a","y")] (wfr RS wf_on_induct) 1); |
180 by (eres_inst_tac [("a","y")] (wfr RS wf_on_induct) 1); |
181 by (rtac (impI RS ballI) 1); |
|
182 by (etac tranclE 1); |
|
183 by (etac (bspec RS mp) 1 THEN assume_tac 1); |
|
184 by (Fast_tac 1); |
|
185 by (cut_facts_tac [subs] 1); |
181 by (cut_facts_tac [subs] 1); |
186 (*astar_tac is slightly faster*) |
182 by (blast_tac (!claset addEs [tranclE]) 1); |
187 by (Best_tac 1); |
|
188 qed "wf_on_trancl"; |
183 qed "wf_on_trancl"; |
189 |
184 |
190 goal WF.thy "!!r. wf(r) ==> wf(r^+)"; |
185 goal WF.thy "!!r. wf(r) ==> wf(r^+)"; |
191 by (asm_full_simp_tac (!simpset addsimps [wf_iff_wf_on_field]) 1); |
186 by (asm_full_simp_tac (!simpset addsimps [wf_iff_wf_on_field]) 1); |
192 by (rtac (trancl_type RS field_rel_subset RSN (2, wf_on_subset_A)) 1); |
187 by (rtac (trancl_type RS field_rel_subset RSN (2, wf_on_subset_A)) 1); |
193 by (etac wf_on_trancl 1); |
188 by (etac wf_on_trancl 1); |
194 by (Fast_tac 1); |
189 by (Blast_tac 1); |
195 qed "wf_trancl"; |
190 qed "wf_trancl"; |
196 |
191 |
197 |
192 |
198 |
193 |
199 (** r-``{a} is the set of everything under a in r **) |
194 (** r-``{a} is the set of everything under a in r **) |