25 qed "refl_comp_subset"; |
25 qed "refl_comp_subset"; |
26 |
26 |
27 goalw EquivClass.thy [equiv_def] |
27 goalw EquivClass.thy [equiv_def] |
28 "!!A r. equiv(A,r) ==> converse(r) O r = r"; |
28 "!!A r. equiv(A,r) ==> converse(r) O r = r"; |
29 by (fast_tac (subset_cs addSIs [equalityI, sym_trans_comp_subset, |
29 by (fast_tac (subset_cs addSIs [equalityI, sym_trans_comp_subset, |
30 refl_comp_subset]) 1); |
30 refl_comp_subset]) 1); |
31 qed "equiv_comp_eq"; |
31 qed "equiv_comp_eq"; |
32 |
32 |
33 (*second half*) |
33 (*second half*) |
34 goalw EquivClass.thy [equiv_def,refl_def,sym_def,trans_def] |
34 goalw EquivClass.thy [equiv_def,refl_def,sym_def,trans_def] |
35 "!!A r. [| converse(r) O r = r; domain(r) = A |] ==> equiv(A,r)"; |
35 "!!A r. [| converse(r) O r = r; domain(r) = A |] ==> equiv(A,r)"; |
36 by (etac equalityE 1); |
36 by (etac equalityE 1); |
37 by (subgoal_tac "ALL x y. <x,y> : r --> <y,x> : r" 1); |
37 by (subgoal_tac "ALL x y. <x,y> : r --> <y,x> : r" 1); |
38 by (safe_tac ZF_cs); |
38 by (safe_tac ZF_cs); |
39 by (fast_tac (ZF_cs addSIs [converseI] addIs [compI]) 3); |
39 by (fast_tac (ZF_cs addSIs [converseI] addIs [compI]) 3); |
40 by (ALLGOALS (fast_tac |
40 by (ALLGOALS (fast_tac |
41 (ZF_cs addSIs [converseI] addIs [compI] addSEs [compE]))); |
41 (ZF_cs addSIs [converseI] addIs [compI] addSEs [compE]))); |
42 qed "comp_equivI"; |
42 qed "comp_equivI"; |
43 |
43 |
44 (** Equivalence classes **) |
44 (** Equivalence classes **) |
45 |
45 |
46 (*Lemma for the next result*) |
46 (*Lemma for the next result*) |
50 qed "equiv_class_subset"; |
50 qed "equiv_class_subset"; |
51 |
51 |
52 goalw EquivClass.thy [equiv_def] |
52 goalw EquivClass.thy [equiv_def] |
53 "!!A r. [| equiv(A,r); <a,b>: r |] ==> r``{a} = r``{b}"; |
53 "!!A r. [| equiv(A,r); <a,b>: r |] ==> r``{a} = r``{b}"; |
54 by (safe_tac (subset_cs addSIs [equalityI, equiv_class_subset])); |
54 by (safe_tac (subset_cs addSIs [equalityI, equiv_class_subset])); |
55 by (rewrite_goals_tac [sym_def]); |
55 by (rewtac sym_def); |
56 by (fast_tac ZF_cs 1); |
56 by (fast_tac ZF_cs 1); |
57 qed "equiv_class_eq"; |
57 qed "equiv_class_eq"; |
58 |
58 |
59 goalw EquivClass.thy [equiv_def,refl_def] |
59 goalw EquivClass.thy [equiv_def,refl_def] |
60 "!!A r. [| equiv(A,r); a: A |] ==> a: r``{a}"; |
60 "!!A r. [| equiv(A,r); a: A |] ==> a: r``{a}"; |
83 qed "equiv_type"; |
83 qed "equiv_type"; |
84 |
84 |
85 goal EquivClass.thy |
85 goal EquivClass.thy |
86 "!!A r. equiv(A,r) ==> <x,y>: r <-> r``{x} = r``{y} & x:A & y:A"; |
86 "!!A r. equiv(A,r) ==> <x,y>: r <-> r``{x} = r``{y} & x:A & y:A"; |
87 by (fast_tac (ZF_cs addIs [eq_equiv_class, equiv_class_eq] |
87 by (fast_tac (ZF_cs addIs [eq_equiv_class, equiv_class_eq] |
88 addDs [equiv_type]) 1); |
88 addDs [equiv_type]) 1); |
89 qed "equiv_class_eq_iff"; |
89 qed "equiv_class_eq_iff"; |
90 |
90 |
91 goal EquivClass.thy |
91 goal EquivClass.thy |
92 "!!A r. [| equiv(A,r); x: A; y: A |] ==> r``{x} = r``{y} <-> <x,y>: r"; |
92 "!!A r. [| equiv(A,r); x: A; y: A |] ==> r``{x} = r``{y} <-> <x,y>: r"; |
93 by (fast_tac (ZF_cs addIs [eq_equiv_class, equiv_class_eq] |
93 by (fast_tac (ZF_cs addIs [eq_equiv_class, equiv_class_eq] |
94 addDs [equiv_type]) 1); |
94 addDs [equiv_type]) 1); |
95 qed "eq_equiv_class_iff"; |
95 qed "eq_equiv_class_iff"; |
96 |
96 |
97 (*** Quotients ***) |
97 (*** Quotients ***) |
98 |
98 |
99 (** Introduction/elimination rules -- needed? **) |
99 (** Introduction/elimination rules -- needed? **) |
141 by (fast_tac ZF_cs 1); |
141 by (fast_tac ZF_cs 1); |
142 qed "UN_equiv_class"; |
142 qed "UN_equiv_class"; |
143 |
143 |
144 (*type checking of UN x:r``{a}. b(x) *) |
144 (*type checking of UN x:r``{a}. b(x) *) |
145 val prems = goalw EquivClass.thy [quotient_def] |
145 val prems = goalw EquivClass.thy [quotient_def] |
146 "[| equiv(A,r); congruent(r,b); X: A/r; \ |
146 "[| equiv(A,r); congruent(r,b); X: A/r; \ |
147 \ !!x. x : A ==> b(x) : B |] \ |
147 \ !!x. x : A ==> b(x) : B |] \ |
148 \ ==> (UN x:X. b(x)) : B"; |
148 \ ==> (UN x:X. b(x)) : B"; |
149 by (cut_facts_tac prems 1); |
149 by (cut_facts_tac prems 1); |
150 by (safe_tac ZF_cs); |
150 by (safe_tac ZF_cs); |
151 by (asm_simp_tac (ZF_ss addsimps (UN_equiv_class::prems)) 1); |
151 by (asm_simp_tac (ZF_ss addsimps (UN_equiv_class::prems)) 1); |
152 qed "UN_equiv_class_type"; |
152 qed "UN_equiv_class_type"; |
155 major premise could be an inclusion; bcong could be !!y. y:A ==> b(y):B |
155 major premise could be an inclusion; bcong could be !!y. y:A ==> b(y):B |
156 *) |
156 *) |
157 val prems = goalw EquivClass.thy [quotient_def] |
157 val prems = goalw EquivClass.thy [quotient_def] |
158 "[| equiv(A,r); congruent(r,b); \ |
158 "[| equiv(A,r); congruent(r,b); \ |
159 \ (UN x:X. b(x))=(UN y:Y. b(y)); X: A/r; Y: A/r; \ |
159 \ (UN x:X. b(x))=(UN y:Y. b(y)); X: A/r; Y: A/r; \ |
160 \ !!x y. [| x:A; y:A; b(x)=b(y) |] ==> <x,y>:r |] \ |
160 \ !!x y. [| x:A; y:A; b(x)=b(y) |] ==> <x,y>:r |] \ |
161 \ ==> X=Y"; |
161 \ ==> X=Y"; |
162 by (cut_facts_tac prems 1); |
162 by (cut_facts_tac prems 1); |
163 by (safe_tac ZF_cs); |
163 by (safe_tac ZF_cs); |
164 by (rtac equiv_class_eq 1); |
164 by (rtac equiv_class_eq 1); |
165 by (REPEAT (ares_tac prems 1)); |
165 by (REPEAT (ares_tac prems 1)); |
182 by (cut_facts_tac (equivA::prems) 1); |
182 by (cut_facts_tac (equivA::prems) 1); |
183 by (safe_tac ZF_cs); |
183 by (safe_tac ZF_cs); |
184 by (rtac (equivA RS equiv_type RS subsetD RS SigmaE2) 1); |
184 by (rtac (equivA RS equiv_type RS subsetD RS SigmaE2) 1); |
185 by (assume_tac 1); |
185 by (assume_tac 1); |
186 by (asm_simp_tac (ZF_ss addsimps [equivA RS UN_equiv_class, |
186 by (asm_simp_tac (ZF_ss addsimps [equivA RS UN_equiv_class, |
187 congruent2_implies_congruent]) 1); |
187 congruent2_implies_congruent]) 1); |
188 by (rewrite_goals_tac [congruent2_def,equiv_def,refl_def]); |
188 by (rewrite_goals_tac [congruent2_def,equiv_def,refl_def]); |
189 by (fast_tac ZF_cs 1); |
189 by (fast_tac ZF_cs 1); |
190 qed "congruent2_implies_congruent_UN"; |
190 qed "congruent2_implies_congruent_UN"; |
191 |
191 |
192 val prems as equivA::_ = goal EquivClass.thy |
192 val prems as equivA::_ = goal EquivClass.thy |
193 "[| equiv(A,r); congruent2(r,b); a1: A; a2: A |] \ |
193 "[| equiv(A,r); congruent2(r,b); a1: A; a2: A |] \ |
194 \ ==> (UN x1:r``{a1}. UN x2:r``{a2}. b(x1,x2)) = b(a1,a2)"; |
194 \ ==> (UN x1:r``{a1}. UN x2:r``{a2}. b(x1,x2)) = b(a1,a2)"; |
195 by (cut_facts_tac prems 1); |
195 by (cut_facts_tac prems 1); |
196 by (asm_simp_tac (ZF_ss addsimps [equivA RS UN_equiv_class, |
196 by (asm_simp_tac (ZF_ss addsimps [equivA RS UN_equiv_class, |
197 congruent2_implies_congruent, |
197 congruent2_implies_congruent, |
198 congruent2_implies_congruent_UN]) 1); |
198 congruent2_implies_congruent_UN]) 1); |
199 qed "UN_equiv_class2"; |
199 qed "UN_equiv_class2"; |
200 |
200 |
201 (*type checking*) |
201 (*type checking*) |
202 val prems = goalw EquivClass.thy [quotient_def] |
202 val prems = goalw EquivClass.thy [quotient_def] |
203 "[| equiv(A,r); congruent2(r,b); \ |
203 "[| equiv(A,r); congruent2(r,b); \ |
204 \ X1: A/r; X2: A/r; \ |
204 \ X1: A/r; X2: A/r; \ |
205 \ !!x1 x2. [| x1: A; x2: A |] ==> b(x1,x2) : B \ |
205 \ !!x1 x2. [| x1: A; x2: A |] ==> b(x1,x2) : B \ |
206 \ |] ==> (UN x1:X1. UN x2:X2. b(x1,x2)) : B"; |
206 \ |] ==> (UN x1:X1. UN x2:X2. b(x1,x2)) : B"; |
207 by (cut_facts_tac prems 1); |
207 by (cut_facts_tac prems 1); |
208 by (safe_tac ZF_cs); |
208 by (safe_tac ZF_cs); |
209 by (REPEAT (ares_tac (prems@[UN_equiv_class_type, |
209 by (REPEAT (ares_tac (prems@[UN_equiv_class_type, |
210 congruent2_implies_congruent_UN, |
210 congruent2_implies_congruent_UN, |
211 congruent2_implies_congruent, quotientI]) 1)); |
211 congruent2_implies_congruent, quotientI]) 1)); |
212 qed "UN_equiv_class_type2"; |
212 qed "UN_equiv_class_type2"; |
213 |
213 |
214 |
214 |
215 (*Suggested by John Harrison -- the two subproofs may be MUCH simpler |
215 (*Suggested by John Harrison -- the two subproofs may be MUCH simpler |
216 than the direct proof*) |
216 than the direct proof*) |
217 val prems = goalw EquivClass.thy [congruent2_def,equiv_def,refl_def] |
217 val prems = goalw EquivClass.thy [congruent2_def,equiv_def,refl_def] |
218 "[| equiv(A,r); \ |
218 "[| equiv(A,r); \ |
219 \ !! y z w. [| w: A; <y,z> : r |] ==> b(y,w) = b(z,w); \ |
219 \ !! y z w. [| w: A; <y,z> : r |] ==> b(y,w) = b(z,w); \ |
220 \ !! y z w. [| w: A; <y,z> : r |] ==> b(w,y) = b(w,z) \ |
220 \ !! y z w. [| w: A; <y,z> : r |] ==> b(w,y) = b(w,z) \ |
221 \ |] ==> congruent2(r,b)"; |
221 \ |] ==> congruent2(r,b)"; |
222 by (cut_facts_tac prems 1); |
222 by (cut_facts_tac prems 1); |
223 by (safe_tac ZF_cs); |
223 by (safe_tac ZF_cs); |
225 by (REPEAT (ares_tac prems 1 |
225 by (REPEAT (ares_tac prems 1 |
226 ORELSE etac (subsetD RS SigmaE2) 1 THEN assume_tac 2 THEN assume_tac 1)); |
226 ORELSE etac (subsetD RS SigmaE2) 1 THEN assume_tac 2 THEN assume_tac 1)); |
227 qed "congruent2I"; |
227 qed "congruent2I"; |
228 |
228 |
229 val [equivA,commute,congt] = goal EquivClass.thy |
229 val [equivA,commute,congt] = goal EquivClass.thy |
230 "[| equiv(A,r); \ |
230 "[| equiv(A,r); \ |
231 \ !! y z. [| y: A; z: A |] ==> b(y,z) = b(z,y); \ |
231 \ !! y z. [| y: A; z: A |] ==> b(y,z) = b(z,y); \ |
232 \ !! y z w. [| w: A; <y,z>: r |] ==> b(w,y) = b(w,z) \ |
232 \ !! y z w. [| w: A; <y,z>: r |] ==> b(w,y) = b(w,z) \ |
233 \ |] ==> congruent2(r,b)"; |
233 \ |] ==> congruent2(r,b)"; |
234 by (resolve_tac [equivA RS congruent2I] 1); |
234 by (resolve_tac [equivA RS congruent2I] 1); |
235 by (rtac (commute RS trans) 1); |
235 by (rtac (commute RS trans) 1); |
236 by (rtac (commute RS trans RS sym) 3); |
236 by (rtac (commute RS trans RS sym) 3); |
237 by (rtac sym 5); |
237 by (rtac sym 5); |
240 qed "congruent2_commuteI"; |
240 qed "congruent2_commuteI"; |
241 |
241 |
242 (*Obsolete?*) |
242 (*Obsolete?*) |
243 val [equivA,ZinA,congt,commute] = goalw EquivClass.thy [quotient_def] |
243 val [equivA,ZinA,congt,commute] = goalw EquivClass.thy [quotient_def] |
244 "[| equiv(A,r); Z: A/r; \ |
244 "[| equiv(A,r); Z: A/r; \ |
245 \ !!w. [| w: A |] ==> congruent(r, %z.b(w,z)); \ |
245 \ !!w. [| w: A |] ==> congruent(r, %z.b(w,z)); \ |
246 \ !!x y. [| x: A; y: A |] ==> b(y,x) = b(x,y) \ |
246 \ !!x y. [| x: A; y: A |] ==> b(y,x) = b(x,y) \ |
247 \ |] ==> congruent(r, %w. UN z: Z. b(w,z))"; |
247 \ |] ==> congruent(r, %w. UN z: Z. b(w,z))"; |
248 val congt' = rewrite_rule [congruent_def] congt; |
248 val congt' = rewrite_rule [congruent_def] congt; |
249 by (cut_facts_tac [ZinA] 1); |
249 by (cut_facts_tac [ZinA] 1); |
250 by (rewtac congruent_def); |
250 by (rewtac congruent_def); |
251 by (safe_tac ZF_cs); |
251 by (safe_tac ZF_cs); |
252 by (rtac (equivA RS equiv_type RS subsetD RS SigmaE2) 1); |
252 by (rtac (equivA RS equiv_type RS subsetD RS SigmaE2) 1); |
253 by (assume_tac 1); |
253 by (assume_tac 1); |
254 by (asm_simp_tac (ZF_ss addsimps [commute, |
254 by (asm_simp_tac (ZF_ss addsimps [commute, |
255 [equivA, congt] MRS UN_equiv_class]) 1); |
255 [equivA, congt] MRS UN_equiv_class]) 1); |
256 by (REPEAT (ares_tac [congt' RS spec RS spec RS mp] 1)); |
256 by (REPEAT (ares_tac [congt' RS spec RS spec RS mp] 1)); |
257 qed "congruent_commuteI"; |
257 qed "congruent_commuteI"; |