src/ZF/EquivClass.ML
changeset 1461 6bcb44e4d6e5
parent 1076 68f088887f48
child 2469 b50b8c0eec01
equal deleted inserted replaced
1460:5a6f2aabd538 1461:6bcb44e4d6e5
     1 (*  Title: 	ZF/EquivClass.ML
     1 (*  Title:      ZF/EquivClass.ML
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author: 	Lawrence C Paulson, Cambridge University Computer Laboratory
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   1994  University of Cambridge
     4     Copyright   1994  University of Cambridge
     5 
     5 
     6 For EquivClass.thy.  Equivalence relations in Zermelo-Fraenkel Set Theory 
     6 For EquivClass.thy.  Equivalence relations in Zermelo-Fraenkel Set Theory 
     7 *)
     7 *)
     8 
     8 
    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? **)
   102 by (rtac RepFunI 1);
   102 by (rtac RepFunI 1);
   103 by (resolve_tac prems 1);
   103 by (resolve_tac prems 1);
   104 qed "quotientI";
   104 qed "quotientI";
   105 
   105 
   106 val major::prems = goalw EquivClass.thy [quotient_def]
   106 val major::prems = goalw EquivClass.thy [quotient_def]
   107     "[| X: A/r;  !!x. [| X = r``{x};  x:A |] ==> P |] 	\
   107     "[| X: A/r;  !!x. [| X = r``{x};  x:A |] ==> P |]   \
   108 \    ==> P";
   108 \    ==> P";
   109 by (rtac (major RS RepFunE) 1);
   109 by (rtac (major RS RepFunE) 1);
   110 by (eresolve_tac prems 1);
   110 by (eresolve_tac prems 1);
   111 by (assume_tac 1);
   111 by (assume_tac 1);
   112 qed "quotientE";
   112 qed "quotientE";
   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";