| author | paulson | 
| Fri, 16 Nov 2001 18:24:11 +0100 | |
| changeset 12224 | 02df7cbe7d25 | 
| parent 8 | c3d2c6dcf3f0 | 
| permissions | -rw-r--r-- | 
| 0 | 1 | (* Title: set/set | 
| 2 | ID: $Id$ | |
| 3 | ||
| 4 | For set.thy. | |
| 5 | ||
| 6 | Modified version of | |
| 7 | Title: HOL/set | |
| 8 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | |
| 9 | Copyright 1991 University of Cambridge | |
| 10 | ||
| 11 | For set.thy. Set theory for higher-order logic. A set is simply a predicate. | |
| 12 | *) | |
| 13 | ||
| 14 | open Set; | |
| 15 | ||
| 16 | val [prem] = goal Set.thy "[| P(a) |] ==> a : {x.P(x)}";
 | |
| 17 | by (rtac (mem_Collect_iff RS iffD2) 1); | |
| 18 | by (rtac prem 1); | |
| 19 | val CollectI = result(); | |
| 20 | ||
| 21 | val prems = goal Set.thy "[| a : {x.P(x)} |] ==> P(a)";
 | |
| 22 | by (resolve_tac (prems RL [mem_Collect_iff RS iffD1]) 1); | |
| 23 | val CollectD = result(); | |
| 24 | ||
| 8 
c3d2c6dcf3f0
Installation of new simplfier.  Previously appeared to set up the old
 lcp parents: 
0diff
changeset | 25 | val CollectE = make_elim CollectD; | 
| 
c3d2c6dcf3f0
Installation of new simplfier.  Previously appeared to set up the old
 lcp parents: 
0diff
changeset | 26 | |
| 0 | 27 | val [prem] = goal Set.thy "[| !!x. x:A <-> x:B |] ==> A = B"; | 
| 28 | by (rtac (set_extension RS iffD2) 1); | |
| 29 | by (rtac (prem RS allI) 1); | |
| 30 | val set_ext = result(); | |
| 31 | ||
| 32 | (*** Bounded quantifiers ***) | |
| 33 | ||
| 34 | val prems = goalw Set.thy [Ball_def] | |
| 35 | "[| !!x. x:A ==> P(x) |] ==> ALL x:A. P(x)"; | |
| 36 | by (REPEAT (ares_tac (prems @ [allI,impI]) 1)); | |
| 37 | val ballI = result(); | |
| 38 | ||
| 39 | val [major,minor] = goalw Set.thy [Ball_def] | |
| 40 | "[| ALL x:A. P(x); x:A |] ==> P(x)"; | |
| 41 | by (rtac (minor RS (major RS spec RS mp)) 1); | |
| 42 | val bspec = result(); | |
| 43 | ||
| 44 | val major::prems = goalw Set.thy [Ball_def] | |
| 45 | "[| ALL x:A. P(x); P(x) ==> Q; ~ x:A ==> Q |] ==> Q"; | |
| 46 | by (rtac (major RS spec RS impCE) 1); | |
| 47 | by (REPEAT (eresolve_tac prems 1)); | |
| 48 | val ballE = result(); | |
| 49 | ||
| 50 | (*Takes assumptions ALL x:A.P(x) and a:A; creates assumption P(a)*) | |
| 51 | fun ball_tac i = etac ballE i THEN contr_tac (i+1); | |
| 52 | ||
| 53 | val prems = goalw Set.thy [Bex_def] | |
| 54 | "[| P(x); x:A |] ==> EX x:A. P(x)"; | |
| 55 | by (REPEAT (ares_tac (prems @ [exI,conjI]) 1)); | |
| 56 | val bexI = result(); | |
| 57 | ||
| 58 | val bexCI = prove_goal Set.thy | |
| 59 | "[| EX x:A. ~P(x) ==> P(a); a:A |] ==> EX x:A.P(x)" | |
| 60 | (fn prems=> | |
| 61 | [ (rtac classical 1), | |
| 62 | (REPEAT (ares_tac (prems@[bexI,ballI,notI,notE]) 1)) ]); | |
| 63 | ||
| 64 | val major::prems = goalw Set.thy [Bex_def] | |
| 65 | "[| EX x:A. P(x); !!x. [| x:A; P(x) |] ==> Q |] ==> Q"; | |
| 66 | by (rtac (major RS exE) 1); | |
| 67 | by (REPEAT (eresolve_tac (prems @ [asm_rl,conjE]) 1)); | |
| 68 | val bexE = result(); | |
| 69 | ||
| 70 | (*Trival rewrite rule; (! x:A.P)=P holds only if A is nonempty!*) | |
| 71 | val prems = goal Set.thy | |
| 72 | "(ALL x:A. True) <-> True"; | |
| 73 | by (REPEAT (ares_tac [TrueI,ballI,iffI] 1)); | |
| 74 | val ball_rew = result(); | |
| 75 | ||
| 76 | (** Congruence rules **) | |
| 77 | ||
| 78 | val prems = goal Set.thy | |
| 79 | "[| A=A'; !!x. x:A' ==> P(x) <-> P'(x) |] ==> \ | |
| 80 | \ (ALL x:A. P(x)) <-> (ALL x:A'. P'(x))"; | |
| 81 | by (resolve_tac (prems RL [ssubst,iffD2]) 1); | |
| 82 | by (REPEAT (ares_tac [ballI,iffI] 1 | |
| 83 | ORELSE eresolve_tac ([make_elim bspec, mp] @ (prems RL [iffE])) 1)); | |
| 84 | val ball_cong = result(); | |
| 85 | ||
| 86 | val prems = goal Set.thy | |
| 87 | "[| A=A'; !!x. x:A' ==> P(x) <-> P'(x) |] ==> \ | |
| 88 | \ (EX x:A. P(x)) <-> (EX x:A'. P'(x))"; | |
| 89 | by (resolve_tac (prems RL [ssubst,iffD2]) 1); | |
| 90 | by (REPEAT (etac bexE 1 | |
| 91 | ORELSE ares_tac ([bexI,iffI] @ (prems RL [iffD1,iffD2])) 1)); | |
| 92 | val bex_cong = result(); | |
| 93 | ||
| 94 | (*** Rules for subsets ***) | |
| 95 | ||
| 96 | val prems = goalw Set.thy [subset_def] "(!!x.x:A ==> x:B) ==> A <= B"; | |
| 97 | by (REPEAT (ares_tac (prems @ [ballI]) 1)); | |
| 98 | val subsetI = result(); | |
| 99 | ||
| 100 | (*Rule in Modus Ponens style*) | |
| 101 | val major::prems = goalw Set.thy [subset_def] "[| A <= B; c:A |] ==> c:B"; | |
| 102 | by (rtac (major RS bspec) 1); | |
| 103 | by (resolve_tac prems 1); | |
| 104 | val subsetD = result(); | |
| 105 | ||
| 106 | (*Classical elimination rule*) | |
| 107 | val major::prems = goalw Set.thy [subset_def] | |
| 108 | "[| A <= B; ~(c:A) ==> P; c:B ==> P |] ==> P"; | |
| 109 | by (rtac (major RS ballE) 1); | |
| 110 | by (REPEAT (eresolve_tac prems 1)); | |
| 111 | val subsetCE = result(); | |
| 112 | ||
| 113 | (*Takes assumptions A<=B; c:A and creates the assumption c:B *) | |
| 114 | fun set_mp_tac i = etac subsetCE i THEN mp_tac i; | |
| 115 | ||
| 116 | val subset_refl = prove_goal Set.thy "A <= A" | |
| 117 | (fn _=> [ (REPEAT (ares_tac [subsetI] 1)) ]); | |
| 118 | ||
| 119 | goal Set.thy "!!A B C. [| A<=B; B<=C |] ==> A<=C"; | |
| 120 | br subsetI 1; | |
| 121 | by (REPEAT (eresolve_tac [asm_rl, subsetD] 1)); | |
| 122 | val subset_trans = result(); | |
| 123 | ||
| 124 | ||
| 125 | (*** Rules for equality ***) | |
| 126 | ||
| 127 | (*Anti-symmetry of the subset relation*) | |
| 128 | val prems = goal Set.thy "[| A <= B; B <= A |] ==> A = B"; | |
| 129 | by (rtac (iffI RS set_ext) 1); | |
| 130 | by (REPEAT (ares_tac (prems RL [subsetD]) 1)); | |
| 131 | val subset_antisym = result(); | |
| 132 | val equalityI = subset_antisym; | |
| 133 | ||
| 134 | (* Equality rules from ZF set theory -- are they appropriate here? *) | |
| 135 | val prems = goal Set.thy "A = B ==> A<=B"; | |
| 136 | by (resolve_tac (prems RL [subst]) 1); | |
| 137 | by (rtac subset_refl 1); | |
| 138 | val equalityD1 = result(); | |
| 139 | ||
| 140 | val prems = goal Set.thy "A = B ==> B<=A"; | |
| 141 | by (resolve_tac (prems RL [subst]) 1); | |
| 142 | by (rtac subset_refl 1); | |
| 143 | val equalityD2 = result(); | |
| 144 | ||
| 145 | val prems = goal Set.thy | |
| 146 | "[| A = B; [| A<=B; B<=A |] ==> P |] ==> P"; | |
| 147 | by (resolve_tac prems 1); | |
| 148 | by (REPEAT (resolve_tac (prems RL [equalityD1,equalityD2]) 1)); | |
| 149 | val equalityE = result(); | |
| 150 | ||
| 151 | val major::prems = goal Set.thy | |
| 152 | "[| A = B; [| c:A; c:B |] ==> P; [| ~ c:A; ~ c:B |] ==> P |] ==> P"; | |
| 153 | by (rtac (major RS equalityE) 1); | |
| 154 | by (REPEAT (contr_tac 1 ORELSE eresolve_tac ([asm_rl,subsetCE]@prems) 1)); | |
| 155 | val equalityCE = result(); | |
| 156 | ||
| 157 | (*Lemma for creating induction formulae -- for "pattern matching" on p | |
| 158 | To make the induction hypotheses usable, apply "spec" or "bspec" to | |
| 159 | put universal quantifiers over the free variables in p. *) | |
| 160 | val prems = goal Set.thy | |
| 161 | "[| p:A; !!z. z:A ==> p=z --> R |] ==> R"; | |
| 162 | by (rtac mp 1); | |
| 163 | by (REPEAT (resolve_tac (refl::prems) 1)); | |
| 164 | val setup_induction = result(); | |
| 165 | ||
| 166 | goal Set.thy "{x.x:A} = A";
 | |
| 167 | by (REPEAT (ares_tac [equalityI,subsetI,CollectI] 1 ORELSE eresolve_tac [CollectD] 1)); | |
| 168 | val trivial_set = result(); | |
| 169 | ||
| 170 | (*** Rules for binary union -- Un ***) | |
| 171 | ||
| 172 | val prems = goalw Set.thy [Un_def] "c:A ==> c : A Un B"; | |
| 173 | by (REPEAT (resolve_tac (prems @ [CollectI,disjI1]) 1)); | |
| 174 | val UnI1 = result(); | |
| 175 | ||
| 176 | val prems = goalw Set.thy [Un_def] "c:B ==> c : A Un B"; | |
| 177 | by (REPEAT (resolve_tac (prems @ [CollectI,disjI2]) 1)); | |
| 178 | val UnI2 = result(); | |
| 179 | ||
| 180 | (*Classical introduction rule: no commitment to A vs B*) | |
| 181 | val UnCI = prove_goal Set.thy "(~c:B ==> c:A) ==> c : A Un B" | |
| 182 | (fn prems=> | |
| 183 | [ (rtac classical 1), | |
| 184 | (REPEAT (ares_tac (prems@[UnI1,notI]) 1)), | |
| 185 | (REPEAT (ares_tac (prems@[UnI2,notE]) 1)) ]); | |
| 186 | ||
| 187 | val major::prems = goalw Set.thy [Un_def] | |
| 188 | "[| c : A Un B; c:A ==> P; c:B ==> P |] ==> P"; | |
| 189 | by (rtac (major RS CollectD RS disjE) 1); | |
| 190 | by (REPEAT (eresolve_tac prems 1)); | |
| 191 | val UnE = result(); | |
| 192 | ||
| 193 | ||
| 194 | (*** Rules for small intersection -- Int ***) | |
| 195 | ||
| 196 | val prems = goalw Set.thy [Int_def] | |
| 197 | "[| c:A; c:B |] ==> c : A Int B"; | |
| 198 | by (REPEAT (resolve_tac (prems @ [CollectI,conjI]) 1)); | |
| 199 | val IntI = result(); | |
| 200 | ||
| 201 | val [major] = goalw Set.thy [Int_def] "c : A Int B ==> c:A"; | |
| 202 | by (rtac (major RS CollectD RS conjunct1) 1); | |
| 203 | val IntD1 = result(); | |
| 204 | ||
| 205 | val [major] = goalw Set.thy [Int_def] "c : A Int B ==> c:B"; | |
| 206 | by (rtac (major RS CollectD RS conjunct2) 1); | |
| 207 | val IntD2 = result(); | |
| 208 | ||
| 209 | val [major,minor] = goal Set.thy | |
| 210 | "[| c : A Int B; [| c:A; c:B |] ==> P |] ==> P"; | |
| 211 | by (rtac minor 1); | |
| 212 | by (rtac (major RS IntD1) 1); | |
| 213 | by (rtac (major RS IntD2) 1); | |
| 214 | val IntE = result(); | |
| 215 | ||
| 216 | ||
| 217 | (*** Rules for set complement -- Compl ***) | |
| 218 | ||
| 219 | val prems = goalw Set.thy [Compl_def] | |
| 220 | "[| c:A ==> False |] ==> c : Compl(A)"; | |
| 221 | by (REPEAT (ares_tac (prems @ [CollectI,notI]) 1)); | |
| 222 | val ComplI = result(); | |
| 223 | ||
| 224 | (*This form, with negated conclusion, works well with the Classical prover. | |
| 225 | Negated assumptions behave like formulae on the right side of the notional | |
| 226 | turnstile...*) | |
| 227 | val major::prems = goalw Set.thy [Compl_def] | |
| 228 | "[| c : Compl(A) |] ==> ~c:A"; | |
| 229 | by (rtac (major RS CollectD) 1); | |
| 230 | val ComplD = result(); | |
| 231 | ||
| 232 | val ComplE = make_elim ComplD; | |
| 233 | ||
| 234 | ||
| 235 | (*** Empty sets ***) | |
| 236 | ||
| 237 | goalw Set.thy [empty_def] "{x.False} = {}";
 | |
| 238 | br refl 1; | |
| 239 | val empty_eq = result(); | |
| 240 | ||
| 241 | val [prem] = goalw Set.thy [empty_def] "a : {} ==> P";
 | |
| 242 | by (rtac (prem RS CollectD RS FalseE) 1); | |
| 243 | val emptyD = result(); | |
| 244 | ||
| 245 | val emptyE = make_elim emptyD; | |
| 246 | ||
| 247 | val [prem] = goal Set.thy "~ A={} ==> (EX x.x:A)";
 | |
| 248 | br (prem RS swap) 1; | |
| 249 | br equalityI 1; | |
| 250 | by (ALLGOALS (fast_tac (FOL_cs addSIs [subsetI] addSEs [emptyD]))); | |
| 251 | val not_emptyD = result(); | |
| 252 | ||
| 253 | (*** Singleton sets ***) | |
| 254 | ||
| 255 | goalw Set.thy [singleton_def] "a : {a}";
 | |
| 256 | by (rtac CollectI 1); | |
| 257 | by (rtac refl 1); | |
| 258 | val singletonI = result(); | |
| 259 | ||
| 260 | val [major] = goalw Set.thy [singleton_def] "b : {a} ==> b=a"; 
 | |
| 261 | by (rtac (major RS CollectD) 1); | |
| 262 | val singletonD = result(); | |
| 263 | ||
| 264 | val singletonE = make_elim singletonD; | |
| 265 | ||
| 266 | (*** Unions of families ***) | |
| 267 | ||
| 268 | (*The order of the premises presupposes that A is rigid; b may be flexible*) | |
| 269 | val prems = goalw Set.thy [UNION_def] | |
| 270 | "[| a:A; b: B(a) |] ==> b: (UN x:A. B(x))"; | |
| 271 | by (REPEAT (resolve_tac (prems @ [bexI,CollectI]) 1)); | |
| 272 | val UN_I = result(); | |
| 273 | ||
| 274 | val major::prems = goalw Set.thy [UNION_def] | |
| 275 | "[| b : (UN x:A. B(x)); !!x.[| x:A; b: B(x) |] ==> R |] ==> R"; | |
| 276 | by (rtac (major RS CollectD RS bexE) 1); | |
| 277 | by (REPEAT (ares_tac prems 1)); | |
| 278 | val UN_E = result(); | |
| 279 | ||
| 280 | val prems = goal Set.thy | |
| 281 | "[| A=B; !!x. x:B ==> C(x) = D(x) |] ==> \ | |
| 282 | \ (UN x:A. C(x)) = (UN x:B. D(x))"; | |
| 283 | by (REPEAT (etac UN_E 1 | |
| 284 | ORELSE ares_tac ([UN_I,equalityI,subsetI] @ | |
| 285 | (prems RL [equalityD1,equalityD2] RL [subsetD])) 1)); | |
| 286 | val UN_cong = result(); | |
| 287 | ||
| 288 | (*** Intersections of families -- INTER x:A. B(x) is Inter(B)``A ) *) | |
| 289 | ||
| 290 | val prems = goalw Set.thy [INTER_def] | |
| 291 | "(!!x. x:A ==> b: B(x)) ==> b : (INT x:A. B(x))"; | |
| 292 | by (REPEAT (ares_tac ([CollectI,ballI] @ prems) 1)); | |
| 293 | val INT_I = result(); | |
| 294 | ||
| 295 | val major::prems = goalw Set.thy [INTER_def] | |
| 296 | "[| b : (INT x:A. B(x)); a:A |] ==> b: B(a)"; | |
| 297 | by (rtac (major RS CollectD RS bspec) 1); | |
| 298 | by (resolve_tac prems 1); | |
| 299 | val INT_D = result(); | |
| 300 | ||
| 301 | (*"Classical" elimination rule -- does not require proving X:C *) | |
| 302 | val major::prems = goalw Set.thy [INTER_def] | |
| 303 | "[| b : (INT x:A. B(x)); b: B(a) ==> R; ~ a:A ==> R |] ==> R"; | |
| 304 | by (rtac (major RS CollectD RS ballE) 1); | |
| 305 | by (REPEAT (eresolve_tac prems 1)); | |
| 306 | val INT_E = result(); | |
| 307 | ||
| 308 | val prems = goal Set.thy | |
| 309 | "[| A=B; !!x. x:B ==> C(x) = D(x) |] ==> \ | |
| 310 | \ (INT x:A. C(x)) = (INT x:B. D(x))"; | |
| 311 | by (REPEAT_FIRST (resolve_tac [INT_I,equalityI,subsetI])); | |
| 312 | by (REPEAT (dtac INT_D 1 | |
| 313 | ORELSE ares_tac (prems RL [equalityD1,equalityD2] RL [subsetD]) 1)); | |
| 314 | val INT_cong = result(); | |
| 315 | ||
| 316 | (*** Rules for Unions ***) | |
| 317 | ||
| 318 | (*The order of the premises presupposes that C is rigid; A may be flexible*) | |
| 319 | val prems = goalw Set.thy [Union_def] | |
| 320 | "[| X:C; A:X |] ==> A : Union(C)"; | |
| 321 | by (REPEAT (resolve_tac (prems @ [UN_I]) 1)); | |
| 322 | val UnionI = result(); | |
| 323 | ||
| 324 | val major::prems = goalw Set.thy [Union_def] | |
| 325 | "[| A : Union(C); !!X.[| A:X; X:C |] ==> R |] ==> R"; | |
| 326 | by (rtac (major RS UN_E) 1); | |
| 327 | by (REPEAT (ares_tac prems 1)); | |
| 328 | val UnionE = result(); | |
| 329 | ||
| 330 | (*** Rules for Inter ***) | |
| 331 | ||
| 332 | val prems = goalw Set.thy [Inter_def] | |
| 333 | "[| !!X. X:C ==> A:X |] ==> A : Inter(C)"; | |
| 334 | by (REPEAT (ares_tac ([INT_I] @ prems) 1)); | |
| 335 | val InterI = result(); | |
| 336 | ||
| 337 | (*A "destruct" rule -- every X in C contains A as an element, but | |
| 338 | A:X can hold when X:C does not! This rule is analogous to "spec". *) | |
| 339 | val major::prems = goalw Set.thy [Inter_def] | |
| 340 | "[| A : Inter(C); X:C |] ==> A:X"; | |
| 341 | by (rtac (major RS INT_D) 1); | |
| 342 | by (resolve_tac prems 1); | |
| 343 | val InterD = result(); | |
| 344 | ||
| 345 | (*"Classical" elimination rule -- does not require proving X:C *) | |
| 346 | val major::prems = goalw Set.thy [Inter_def] | |
| 347 | "[| A : Inter(C); A:X ==> R; ~ X:C ==> R |] ==> R"; | |
| 348 | by (rtac (major RS INT_E) 1); | |
| 349 | by (REPEAT (eresolve_tac prems 1)); | |
| 350 | val InterE = result(); |