1(* ========================================================================= *) 2(* *) 3(* Elementary Topology in Euclidean Space (R^1) *) 4(* *) 5(* (c) Copyright, John Harrison 1998-2015 *) 6(* (c) Copyright, Valentina Bruno 2010 *) 7(* (c) Copyright, Marco Maggesi 2014-2015 *) 8(* (c) Copyright 2015, *) 9(* Muhammad Qasim, *) 10(* Osman Hasan, *) 11(* Hardware Verification Group, *) 12(* Concordia University *) 13(* Contact: <m_qasi@ece.concordia.ca> *) 14(* *) 15(* Note: This theory was ported from HOL Light *) 16(* *) 17(* ========================================================================= *) 18 19open HolKernel Parse boolLib bossLib; 20 21open numTheory numLib unwindLib tautLib Arith prim_recTheory RealArith 22 combinTheory quotientTheory arithmeticTheory realTheory 23 jrhUtils pairTheory boolTheory pred_setTheory optionTheory 24 sumTheory InductiveDefinition ind_typeTheory listTheory mesonLib 25 seqTheory limTheory transcTheory realLib topologyTheory metricTheory; 26 27open wellorderTheory cardinalTheory iterateTheory productTheory hurdUtils; 28 29val _ = new_theory "real_topology"; 30 31fun MESON ths tm = prove(tm,MESON_TAC ths); 32fun METIS ths tm = prove(tm,METIS_TAC ths); 33 34val DISC_RW_KILL = DISCH_TAC THEN ONCE_ASM_REWRITE_TAC [] THEN 35 POP_ASSUM K_TAC; 36 37fun ASSERT_TAC tm = SUBGOAL_THEN tm STRIP_ASSUME_TAC; 38 39val ASM_ARITH_TAC = REPEAT (POP_ASSUM MP_TAC) THEN ARITH_TAC; 40val ASM_REAL_ARITH_TAC = REAL_ASM_ARITH_TAC; 41 42(* Minimal hol-light compatibility layer *) 43val IMP_CONJ = CONJ_EQ_IMP; (* cardinalTheory *) 44val FINITE_SUBSET = SUBSET_FINITE_I; (* pred_setTheory *) 45val LE_0 = ZERO_LESS_EQ; (* arithmeticTheory *) 46 47(* ------------------------------------------------------------------------- *) 48(* Pairwise property over sets and lists. *) 49(* ------------------------------------------------------------------------- *) 50 51val pairwise = new_definition ("pairwise", 52 ``pairwise r s <=> !x y. x IN s /\ y IN s /\ ~(x = y) ==> r x y``); 53 54val PAIRWISE_EMPTY = store_thm ("PAIRWISE_EMPTY", 55 ``!r. pairwise r {} <=> T``, 56 REWRITE_TAC[pairwise, NOT_IN_EMPTY] THEN MESON_TAC[]); 57 58val PAIRWISE_SING = store_thm ("PAIRWISE_SING", 59 ``!r x. pairwise r {x} <=> T``, 60 REWRITE_TAC[pairwise, IN_SING] THEN MESON_TAC[]); 61 62val PAIRWISE_MONO = store_thm ("PAIRWISE_MONO", 63 ``!r s t. pairwise r s /\ t SUBSET s ==> pairwise r t``, 64 REWRITE_TAC[pairwise] THEN SET_TAC[]); 65 66val PAIRWISE_INSERT = store_thm ("PAIRWISE_INSERT", 67 ``!r x s. 68 pairwise r (x INSERT s) <=> 69 (!y. y IN s /\ ~(y = x) ==> r x y /\ r y x) /\ 70 pairwise r s``, 71 REWRITE_TAC[pairwise, IN_INSERT] THEN MESON_TAC[]); 72 73val PAIRWISE_IMAGE = store_thm ("PAIRWISE_IMAGE", 74 ``!r f. pairwise r (IMAGE f s) <=> 75 pairwise (\x y. ~(f x = f y) ==> r (f x) (f y)) s``, 76 REWRITE_TAC[pairwise, IN_IMAGE] THEN MESON_TAC[]); 77 78(* ------------------------------------------------------------------------- *) 79(* Permutes *) 80(* ------------------------------------------------------------------------- *) 81 82val _ = set_fixity "permutes" (Infix(NONASSOC, 450)); 83 84(* This is different with pred_setTheory.PERMUTES *) 85val permutes = new_definition ("permutes", 86 ``p permutes s <=> (!x. ~(x IN s) ==> (p(x) = x)) /\ (!y. ?!x. (p x = y))``); 87 88val PERMUTES_IMAGE = store_thm ("PERMUTES_IMAGE", 89 ``!p s. p permutes s ==> (IMAGE p s = s)``, 90 REWRITE_TAC[permutes, EXTENSION, IN_IMAGE] THEN MESON_TAC[]); 91 92val PERMUTES_INJECTIVE = store_thm ("PERMUTES_INJECTIVE", 93 ``!p s. p permutes s ==> !x y. (p(x) = p(y)) <=> (x = y)``, 94 REWRITE_TAC[permutes] THEN MESON_TAC[]); 95 96val EXISTS_IN_INSERT = store_thm ("EXISTS_IN_INSERT", 97 ``!P a s. (?x. x IN (a INSERT s) /\ P x) <=> P a \/ ?x. x IN s /\ P x``, 98 REWRITE_TAC[IN_INSERT] THEN MESON_TAC[]); 99 100val DEPENDENT_CHOICE_FIXED = store_thm ("DEPENDENT_CHOICE_FIXED", 101 ``!P R a:'a. P 0 a /\ (!n x. P n x ==> ?y. P (SUC n) y /\ R n x y) ==> 102 ?f. (f 0 = a) /\ (!n. P n (f n)) /\ (!n. R n (f n) (f(SUC n)))``, 103 REPEAT STRIP_TAC THEN KNOW_TAC ``(?f. (f 0 = (a:'a)) /\ 104 (!n. f(SUC n) = (@y. P (SUC n) y /\ R n (f n) y)))`` THENL 105 [RW_TAC std_ss [num_Axiom], ALL_TAC] THEN 106 STRIP_TAC THEN EXISTS_TAC ``f:num->'a`` THEN ASM_REWRITE_TAC [] THEN 107 ONCE_REWRITE_TAC[METIS [] ``(!n. P n (f n)) = (!n. (\n. P n (f n)) n)``] THEN 108 GEN_REWR_TAC LAND_CONV 109 [MESON[num_CASES] ``(!n. P n) <=> P 0 /\ !n. P(SUC n)``] THEN 110 ASM_SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN INDUCT_TAC THEN METIS_TAC[]); 111 112val DEPENDENT_CHOICE = store_thm ("DEPENDENT_CHOICE", 113 ``!P R:num->'a->'a->bool. (?a. P 0 a) /\ 114 (!n x. P n x ==> ?y. P (SUC n) y /\ R n x y) ==> 115 ?f. (!n. P n (f n)) /\ (!n. R n (f n) (f(SUC n)))``, 116 MESON_TAC[DEPENDENT_CHOICE_FIXED]); 117 118val BIGUNION_MONO_IMAGE = store_thm ("BIGUNION_MONO_IMAGE", 119 ``(!x. x IN s ==> f x SUBSET g x) ==> 120 BIGUNION(IMAGE f s) SUBSET BIGUNION(IMAGE g s)``, 121 SET_TAC[]); 122(** proof without SET_TAC 123 RW_TAC std_ss [SUBSET_DEF, IN_BIGUNION_IMAGE] 124 >> rename1 `y IN s` 125 >> Q.EXISTS_TAC `y` >> ASM_REWRITE_TAC [] 126 >> FIRST_X_ASSUM irule 127 >> ASM_REWRITE_TAC [] 128 *) 129 130val BIGUNION_MONO = store_thm ("BIGUNION_MONO", 131 ``(!x. x IN s ==> ?y. y IN t /\ x SUBSET y) ==> BIGUNION s SUBSET BIGUNION t``, 132 SET_TAC[]); 133(** proof without SET_TAC 134 rpt STRIP_TAC 135 >> RW_TAC std_ss [SUBSET_DEF, IN_BIGUNION] 136 >> rename1 `x IN y` 137 >> Q.PAT_X_ASSUM `!x. x IN s ==> P` (MP_TAC o (Q.SPEC `y`)) 138 >> RW_TAC std_ss [SUBSET_DEF] 139 >> rename1 `z IN t` 140 >> Q.EXISTS_TAC `z` >> ASM_REWRITE_TAC [] 141 >> POP_ASSUM MATCH_MP_TAC 142 >> ASM_REWRITE_TAC [] 143 *) 144 145(* unused lemma 146val th = 147 REWRITE_RULE[IN_UNIV] 148 (ISPECL [``f:'a->'b``, ``UNIV:'a->bool``] INJECTIVE_ON_LEFT_INVERSE); 149 *) 150 151(* ------------------------------------------------------------------------- *) 152(* Metric function for R^1. *) 153(* ------------------------------------------------------------------------- *) 154 155(* new definition based on metricTheory *) 156Definition dist_def : 157 Dist = dist mr1 158End 159 160(* old definition (now becomes a theorem) *) 161Theorem dist : 162 !x y. Dist(x:real,y:real) = abs(x - y) 163Proof 164 RW_TAC std_ss [dist_def, MR1_DEF] 165 >> REAL_ARITH_TAC 166QED 167 168val _ = overload_on ("dist",``Dist``); 169 170val DIST_REFL = store_thm ("DIST_REFL", 171 ``!x. dist(x,x) = &0``, 172 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 173 174val DIST_SYM = store_thm ("DIST_SYM", 175 ``!x y. dist(x,y) = dist(y,x)``, 176 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 177 178val DIST_TRIANGLE = store_thm ("DIST_TRIANGLE", 179 ``!x:real y z. dist(x,z) <= dist(x,y) + dist(y,z)``, 180 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 181 182val DIST_TRIANGLE_ALT = store_thm ("DIST_TRIANGLE_ALT", 183 ``!x y z. dist(y,z) <= dist(x,y) + dist(x,z)``, 184 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 185 186val DIST_EQ_0 = store_thm ("DIST_EQ_0", 187 ``!x y. (dist(x,y) = 0:real) <=> (x = y)``, 188 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 189 190val DIST_POS_LT = store_thm ("DIST_POS_LT", 191 ``!x y. ~(x = y) ==> &0 < dist(x,y)``, 192 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 193 194val DIST_NZ = store_thm ("DIST_NZ", 195 ``!x y. ~(x = y) <=> &0 < dist(x,y)``, 196 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 197 198val DIST_TRIANGLE_LE = store_thm ("DIST_TRIANGLE_LE", 199 ``!x y z e. dist(x,z) + dist(y,z) <= e ==> dist(x,y) <= e``, 200 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 201 202val DIST_TRIANGLE_LT = store_thm ("DIST_TRIANGLE_LT", 203 ``!x y z e. dist(x,z) + dist(y,z) < e ==> dist(x,y) < e``, 204 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 205 206val DIST_TRIANGLE_HALF_L = store_thm ("DIST_TRIANGLE_HALF_L", 207 ``!x1 x2 y. dist(x1,y) < e / &2 /\ dist(x2,y) < e / &2 ==> dist(x1,x2) < e``, 208 REPEAT STRIP_TAC THEN KNOW_TAC `` dist (x1,y) + dist (x2,y) < e`` THENL 209 [METIS_TAC [REAL_LT_ADD2, REAL_HALF_DOUBLE], 210 DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 211 EXISTS_TAC ``dist (x1,y) + dist (x2,y)`` THEN 212 METIS_TAC [DIST_TRIANGLE, DIST_SYM]]); 213 214val DIST_TRIANGLE_HALF_R = store_thm ("DIST_TRIANGLE_HALF_R", 215 ``!x1 x2 y. dist(y,x1) < e / &2 /\ dist(y,x2) < e / &2 ==> dist(x1,x2) < e``, 216 REPEAT STRIP_TAC THEN KNOW_TAC `` dist (y, x1) + dist (y, x2) < e`` THENL 217 [METIS_TAC [REAL_LT_ADD2, REAL_HALF_DOUBLE], 218 DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 219 EXISTS_TAC ``dist (y, x1) + dist (y, x2)`` THEN 220 METIS_TAC [DIST_TRIANGLE, DIST_SYM]]); 221 222val DIST_TRIANGLE_ADD = store_thm ("DIST_TRIANGLE_ADD", 223 ``!x x' y y'. dist(x + y,x' + y') <= dist(x,x') + dist(y,y')``, 224 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 225 226val DIST_MUL = store_thm ("DIST_MUL", 227 ``!x y c. dist(c * x,c * y) = abs(c) * dist(x,y)``, 228 REWRITE_TAC[dist, GSYM ABS_MUL] THEN REAL_ARITH_TAC); 229 230val DIST_TRIANGLE_ADD_HALF = store_thm ("DIST_TRIANGLE_ADD_HALF", 231 ``!x x' y y':real. 232 dist(x,x') < e / &2 /\ dist(y,y') < e / &2 ==> dist(x + y,x' + y') < e``, 233 REPEAT STRIP_TAC THEN KNOW_TAC `` dist (x, x') + dist (y, y') < e`` THENL 234 [METIS_TAC [REAL_LT_ADD2, REAL_HALF_DOUBLE], 235 DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 236 EXISTS_TAC ``dist (x, x') + dist (y, y')`` THEN 237 METIS_TAC [DIST_TRIANGLE_ADD, DIST_SYM]]); 238 239val DIST_LE_0 = store_thm ("DIST_LE_0", 240 ``!x y. dist(x,y) <= &0 <=> (x = y)``, 241 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 242 243val DIST_POS_LE = store_thm ("DIST_POS_LE", 244 ``!x y. &0 <= dist(x,y)``, 245 METIS_TAC [DIST_EQ_0, DIST_NZ, REAL_LE_LT]); 246 247val DIST_EQ = store_thm ("DIST_EQ", 248 ``!w x y z. (dist(w,x) = dist(y,z)) <=> (dist(w,x) pow 2 = dist(y,z) pow 2)``, 249 REPEAT GEN_TAC THEN EQ_TAC THENL [RW_TAC std_ss [], 250 DISCH_TAC THEN MATCH_MP_TAC POW_EQ THEN EXISTS_TAC ``1:num`` THEN 251 RW_TAC arith_ss [DIST_POS_LE]]); 252 253val DIST_0 = store_thm ("DIST_0", 254 ``!x. (dist(x,0) = abs(x)) /\ (dist(0,x) = abs(x))``, 255 RW_TAC arith_ss [dist, REAL_SUB_RZERO, REAL_SUB_LZERO, ABS_NEG]); 256 257val REAL_CHOOSE_DIST = store_thm ("REAL_CHOOSE_DIST", 258 ``!x e. &0 <= e ==> (?y. dist (x,y) = e)``, 259 REPEAT STRIP_TAC THEN EXISTS_TAC ``x - e:real`` THEN 260 ASM_REWRITE_TAC [dist, REAL_SUB_SUB2, ABS_REFL]); 261 262(* ------------------------------------------------------------------------- *) 263(* Linear functions. *) 264(* ------------------------------------------------------------------------- *) 265 266val linear = new_definition ("linear", 267 ``linear (f:real->real) <=> 268 (!x y. f(x + y) = f(x) + f(y)) /\ 269 (!c x. f(c * x) = c * f(x))``); 270 271val LINEAR_SCALING = store_thm ("LINEAR_SCALING", 272 ``!c. linear(\x:real. c * x)``, 273 SIMP_TAC std_ss [linear] THEN REAL_ARITH_TAC); 274 275val LINEAR_COMPOSE_CMUL = store_thm ("LINEAR_COMPOSE_CMUL", 276 ``!f c. linear f ==> linear (\x. c * f(x))``, 277 SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 278 279val LINEAR_COMPOSE_NEG = store_thm ("LINEAR_COMPOSE_NEG", 280 ``!f. linear f ==> linear (\x. -(f(x)))``, 281 SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 282 283val LINEAR_COMPOSE_ADD = store_thm ("LINEAR_COMPOSE_ADD", 284 ``!f g. linear f /\ linear g ==> linear (\x. f(x) + g(x))``, 285 SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 286 287val LINEAR_COMPOSE_SUB = store_thm ("LINEAR_COMPOSE_SUB", 288 ``!f g. linear f /\ linear g ==> linear (\x. f(x) - g(x))``, 289 SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 290 291val LINEAR_COMPOSE = store_thm ("LINEAR_COMPOSE", 292 ``!f g. linear f /\ linear g ==> linear (g o f)``, 293 SIMP_TAC std_ss [linear, o_THM]); 294 295val LINEAR_ID = store_thm ("LINEAR_ID", 296 ``linear (\x. x)``, 297 SIMP_TAC std_ss [linear]); 298 299val LINEAR_ZERO = store_thm ("LINEAR_ZERO", 300 ``linear (\x. 0)``, 301 SIMP_TAC std_ss [linear] THEN CONJ_TAC THEN REAL_ARITH_TAC); 302 303val LINEAR_NEGATION = store_thm ("LINEAR_NEGATION", 304 ``linear (\x. -x)``, 305 SIMP_TAC std_ss [linear] THEN REAL_ARITH_TAC); 306 307val LINEAR_COMPOSE_SUM = store_thm ("LINEAR_COMPOSE_SUM", 308 ``!f s. FINITE s /\ (!a. a IN s ==> linear(f a)) 309 ==> linear(\x. sum s (\a. f a x))``, 310 GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN GEN_TAC THEN 311 KNOW_TAC 312 ``((!a. a IN s ==> linear (f a)) ==> linear (\x. sum s (\a. f a x))) = 313 (\s. (!a. a IN s ==> linear (f a)) ==> linear (\x. sum s (\a. f a x))) s`` 314 THENL [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 315 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 316 SIMP_TAC std_ss [SUM_CLAUSES, LINEAR_ZERO] THEN REPEAT STRIP_TAC THEN 317 KNOW_TAC ``(linear (\x. f e x + sum s (\a. f a x))) = 318 linear (\x. (\x. f e x) x + (\x. sum s (\a. f a x)) x)`` THENL 319 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 320 MATCH_MP_TAC LINEAR_COMPOSE_ADD THEN METIS_TAC [IN_INSERT]); 321 322val LINEAR_MUL_COMPONENT = store_thm ("LINEAR_MUL_COMPONENT", 323 ``!f:real->real v. 324 linear f ==> linear (\x. f(x) * v)``, 325 SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 326 327val LINEAR_0 = store_thm ("LINEAR_0", 328 ``!f. linear f ==> (f(0) = 0)``, 329 METIS_TAC [REAL_MUL_LZERO, linear]); 330 331val LINEAR_CMUL = store_thm ("LINEAR_CMUL", 332 ``!f c x. linear f ==> (f(c * x) = c * f(x))``, 333 SIMP_TAC std_ss [linear]); 334 335val LINEAR_NEG = store_thm ("LINEAR_NEG", 336 ``!f x. linear f ==> (f(-x) = -(f x))``, 337 ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN SIMP_TAC std_ss [LINEAR_CMUL]); 338 339val LINEAR_ADD = store_thm ("LINEAR_ADD", 340 ``!f x y. linear f ==> (f(x + y) = f(x) + f(y))``, 341 SIMP_TAC std_ss [linear]); 342 343val LINEAR_SUB = store_thm ("LINEAR_SUB", 344 ``!f x y. linear f ==> (f(x - y) = f(x) - f(y))``, 345 SIMP_TAC std_ss [real_sub, LINEAR_ADD, LINEAR_NEG]); 346 347val LINEAR_SUM = store_thm ("LINEAR_SUM", 348 ``!f g s. linear f /\ FINITE s ==> (f(sum s g) = sum s (f o g))``, 349 GEN_TAC THEN GEN_TAC THEN SIMP_TAC std_ss [GSYM AND_IMP_INTRO, RIGHT_FORALL_IMP_THM] THEN 350 DISCH_TAC THEN GEN_TAC THEN 351 KNOW_TAC ``(f (sum s g) = sum s (f o g)) = 352 (\s. (f (sum s g) = sum s (f o g))) s`` THENL 353 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 354 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 355 SIMP_TAC std_ss [SUM_CLAUSES] THEN FIRST_ASSUM(fn th => 356 SIMP_TAC std_ss [MATCH_MP LINEAR_0 th, MATCH_MP LINEAR_ADD th, o_THM])); 357 358val LINEAR_SUM_MUL = store_thm ("LINEAR_SUM_MUL", 359 ``!f s c v. 360 linear f /\ FINITE s 361 ==> (f(sum s (\i. c i * v i)) = sum s (\i. c(i) * f(v i)))``, 362 SIMP_TAC std_ss [LINEAR_SUM, o_DEF, LINEAR_CMUL]); 363 364val lemma = prove ( 365 ``x = sum (1:num..1:num) (\i. x * &i)``, 366 REWRITE_TAC [SUM_SING_NUMSEG] THEN BETA_TAC THEN REAL_ARITH_TAC); 367 368val LINEAR_BOUNDED = store_thm ("LINEAR_BOUNDED", 369 ``!f:real->real. linear f ==> ?B. !x. abs(f x) <= B * abs(x)``, 370 REPEAT STRIP_TAC THEN EXISTS_TAC 371 ``sum(1:num..1:num) (\i. abs((f:real->real)(&i)))`` THEN 372 GEN_TAC THEN 373 GEN_REWR_TAC (LAND_CONV o funpow 2 RAND_CONV) [lemma] THEN 374 ASM_SIMP_TAC std_ss [LINEAR_SUM, FINITE_NUMSEG] THEN 375 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN 376 MATCH_MP_TAC SUM_ABS_LE THEN REWRITE_TAC [FINITE_NUMSEG, IN_NUMSEG] THEN 377 BETA_TAC THEN ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN 378 ASM_SIMP_TAC std_ss [o_DEF, ABS_MUL, LINEAR_CMUL] THEN 379 METIS_TAC [REAL_LE_RMUL, ABS_POS, REAL_LE_LT, REAL_MUL_COMM]); 380 381val LINEAR_BOUNDED_POS = store_thm ("LINEAR_BOUNDED_POS", 382 ``!f:real->real. linear f ==> ?B. &0 < B /\ !x. abs(f x) <= B * abs(x)``, 383 REPEAT STRIP_TAC THEN 384 FIRST_ASSUM(X_CHOOSE_TAC ``B:real`` o MATCH_MP LINEAR_BOUNDED) THEN 385 EXISTS_TAC ``abs(B) + &1:real`` THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN 386 GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x:real`) THEN 387 MATCH_MP_TAC(REAL_ARITH ``a <= b ==> x <= a ==> x <= b:real``) THEN 388 MATCH_MP_TAC REAL_LE_RMUL_IMP THEN REWRITE_TAC[ABS_POS] THEN 389 REAL_ARITH_TAC); 390 391val SYMMETRIC_LINEAR_IMAGE = store_thm ("SYMMETRIC_LINEAR_IMAGE", 392 ``!f s. (!x. x IN s ==> -x IN s) /\ linear f 393 ==> !x. x IN (IMAGE f s) ==> -x IN (IMAGE f s)``, 394 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 395 SIMP_TAC std_ss [GSYM LINEAR_NEG] THEN SET_TAC[]); 396 397(* ------------------------------------------------------------------------- *) 398(* Bilinear functions. *) 399(* ------------------------------------------------------------------------- *) 400 401val bilinear = new_definition ("bilinear", 402 ``bilinear f <=> (!x. linear(\y. f x y)) /\ (!y. linear(\x. f x y))``); 403 404val BILINEAR_SWAP = store_thm ("BILINEAR_SWAP", 405 ``!op:real->real->real. 406 bilinear(\x y. op y x) <=> bilinear op``, 407 SIMP_TAC std_ss [bilinear, ETA_AX] THEN METIS_TAC[]); 408 409val BILINEAR_LADD = store_thm ("BILINEAR_LADD", 410 ``!h x y z. bilinear h ==> (h (x + y) z = (h x z) + (h y z))``, 411 SIMP_TAC std_ss [bilinear, linear]); 412 413val BILINEAR_RADD = store_thm ("BILINEAR_RADD", 414 ``!h x y z. bilinear h ==> (h x (y + z) = (h x y) + (h x z))``, 415 SIMP_TAC std_ss [bilinear, linear]); 416 417val BILINEAR_LMUL = store_thm ("BILINEAR_LMUL", 418 ``!h c x y. bilinear h ==> (h (c * x) y = c * (h x y))``, 419 SIMP_TAC std_ss [bilinear, linear]); 420 421val BILINEAR_RMUL = store_thm ("BILINEAR_RMUL", 422 ``!h c x y. bilinear h ==> (h x (c * y) = c * (h x y))``, 423 SIMP_TAC std_ss [bilinear, linear]); 424 425val BILINEAR_LNEG = store_thm ("BILINEAR_LNEG", 426 ``!h x y. bilinear h ==> (h (-x) y = -(h x y))``, 427 ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN SIMP_TAC std_ss [BILINEAR_LMUL]); 428 429val BILINEAR_RNEG = store_thm ("BILINEAR_RNEG", 430 ``!h x y. bilinear h ==> (h x (-y) = -(h x y))``, 431 ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN SIMP_TAC std_ss [BILINEAR_RMUL]); 432 433val BILINEAR_LZERO = store_thm ("BILINEAR_LZERO", 434 ``!h x. bilinear h ==> (h (0) x = 0)``, 435 ONCE_REWRITE_TAC[REAL_ARITH ``(x = 0:real) <=> (x + x = x)``] THEN 436 SIMP_TAC std_ss [GSYM BILINEAR_LADD, REAL_ADD_LID]); 437 438val BILINEAR_RZERO = store_thm ("BILINEAR_RZERO", 439 ``!h x. bilinear h ==> (h x (0) = 0)``, 440 ONCE_REWRITE_TAC[REAL_ARITH ``(x = 0:real) <=> (x + x = x)``] THEN 441 SIMP_TAC std_ss [GSYM BILINEAR_RADD, REAL_ADD_LID]); 442 443val BILINEAR_LSUB = store_thm ("BILINEAR_LSUB", 444 ``!h x y z. bilinear h ==> (h (x - y) z = (h x z) - (h y z))``, 445 SIMP_TAC std_ss [real_sub, BILINEAR_LNEG, BILINEAR_LADD]); 446 447val BILINEAR_RSUB = store_thm ("BILINEAR_RSUB", 448 ``!h x y z. bilinear h ==> (h x (y - z) = (h x y) - (h x z))``, 449 SIMP_TAC std_ss [real_sub, BILINEAR_RNEG, BILINEAR_RADD]); 450 451val lemma = prove ( 452 ``!s t. s CROSS t = {(x,y) | x IN s /\ y IN t}``, 453 REWRITE_TAC [CROSS_DEF] THEN 454 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD]); 455 456val BILINEAR_SUM = store_thm ("BILINEAR_SUM", 457 ``!h:real->real->real. 458 bilinear h /\ FINITE s /\ FINITE t 459 ==> (h (sum s f) (sum t g) = sum (s CROSS t) (\(i,j). h (f i) (g j)))``, 460 REPEAT GEN_TAC THEN REWRITE_TAC [bilinear] THEN 461 KNOW_TAC ``(!x. linear (\y. h:real->real->real x y)) = (!x. linear (h x))`` THENL 462 [METIS_TAC [ETA_AX], ALL_TAC] THEN DISC_RW_KILL THEN 463 ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> (a /\ d) /\ (b /\ c)`] THEN 464 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN 465 KNOW_TAC ``((!y. linear (\x. h:real->real->real x y)) /\ FINITE s) = 466 ((!y. linear (\x. h x y) /\ FINITE s))`` THENL 467 [SIMP_TAC std_ss [LEFT_AND_FORALL_THM], ALL_TAC] THEN 468 DISC_RW_KILL THEN DISCH_TAC THEN 469 FIRST_ASSUM(MP_TAC o GEN_ALL o MATCH_MP LINEAR_SUM o SPEC_ALL) THEN 470 SIMP_TAC std_ss [] THEN 471 ASM_SIMP_TAC std_ss [LINEAR_SUM, o_DEF, SUM_SUM_PRODUCT] THEN 472 SIMP_TAC std_ss [lemma]); 473 474val lemma = prove ( 475 ``!x. x = sum (1:num..1:num) (\i. x * &i)``, 476 REWRITE_TAC [SUM_SING_NUMSEG] THEN BETA_TAC THEN REAL_ARITH_TAC); 477 478val BILINEAR_BOUNDED = store_thm ("BILINEAR_BOUNDED", 479 ``!h:real->real->real. 480 bilinear h ==> ?B. !x y. abs(h x y) <= B * abs(x) * abs(y)``, 481 REPEAT STRIP_TAC THEN 482 EXISTS_TAC ``sum ((1:num..1:num) CROSS (1:num..1:num)) 483 (\ (i,j). abs((h:real->real->real) 484 (&i) (&j)))`` THEN 485 REPEAT GEN_TAC THEN GEN_REWR_TAC 486 (LAND_CONV o RAND_CONV o BINOP_CONV) [lemma] THEN 487 ASM_SIMP_TAC std_ss [BILINEAR_SUM, FINITE_NUMSEG] THEN 488 ONCE_REWRITE_TAC [REAL_ARITH ``a * b * c = b * c * a:real``] THEN 489 REWRITE_TAC[GSYM SUM_LMUL] THEN MATCH_MP_TAC SUM_ABS_LE THEN 490 SIMP_TAC std_ss [FINITE_CROSS, FINITE_NUMSEG, FORALL_PROD, IN_CROSS] THEN 491 REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THEN 492 ASM_SIMP_TAC std_ss [BILINEAR_LMUL, ABS_MUL] THEN 493 ASM_SIMP_TAC std_ss [BILINEAR_RMUL, ABS_MUL, REAL_MUL_ASSOC] THEN 494 METIS_TAC [REAL_LE_LT]); 495 496val BILINEAR_BOUNDED_POS = store_thm ("BILINEAR_BOUNDED_POS", 497 ``!h. bilinear h 498 ==> ?B. &0 < B /\ !x y. abs(h x y) <= B * abs(x) * abs(y)``, 499 REPEAT STRIP_TAC THEN 500 FIRST_ASSUM(X_CHOOSE_TAC ``B:real`` o MATCH_MP BILINEAR_BOUNDED) THEN 501 EXISTS_TAC ``abs(B) + &1:real`` THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN 502 REPEAT GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPECL [`x:real`, `y:real`]) THEN 503 MATCH_MP_TAC(REAL_ARITH ``a <= b ==> x <= a ==> x <= b:real``) THEN 504 REPEAT(MATCH_MP_TAC REAL_LE_RMUL_IMP THEN 505 SIMP_TAC std_ss [ABS_POS, REAL_LE_MUL]) THEN 506 REAL_ARITH_TAC); 507 508val BILINEAR_SUM_PARTIAL_SUC = store_thm ("BILINEAR_SUM_PARTIAL_SUC", 509 ``!f g h:real->real->real m n. 510 bilinear h 511 ==> (sum (m..n) (\k. h (f k) (g(k + 1) - g(k))) = 512 if m <= n then h (f(n + 1)) (g(n + 1)) - h (f m) (g m) - 513 sum (m..n) (\k. h (f(k + 1) - f(k)) (g(k + 1))) 514 else 0)``, 515 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN 516 GEN_TAC THEN INDUCT_TAC THEN 517 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [SUM_TRIV_NUMSEG, NOT_LESS_EQ] THEN 518 ASM_REWRITE_TAC[SUM_CLAUSES_NUMSEG] THENL 519 [COND_CASES_TAC THEN ASM_SIMP_TAC arith_ss [] THENL 520 [ASM_SIMP_TAC std_ss [BILINEAR_RSUB, BILINEAR_LSUB] THEN REAL_ARITH_TAC, 521 FULL_SIMP_TAC std_ss [bilinear, linear]], FULL_SIMP_TAC std_ss [bilinear, linear], 522 POP_ASSUM MP_TAC THEN REWRITE_TAC [LE] THEN 523 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THENL [ALL_TAC, ASM_REWRITE_TAC []] THEN 524 ASM_SIMP_TAC std_ss [GSYM NOT_LESS, SUM_TRIV_NUMSEG, ARITH_PROVE ``n < SUC n``] THEN 525 ASM_SIMP_TAC std_ss [GSYM ADD1, ADD_CLAUSES] THEN 526 ASM_SIMP_TAC std_ss [BILINEAR_RSUB, BILINEAR_LSUB] THEN REAL_ARITH_TAC, 527 ALL_TAC] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC [LE] THEN 528 REWRITE_TAC [DE_MORGAN_THM] THEN 529 ASM_SIMP_TAC std_ss [GSYM NOT_LESS, SUM_TRIV_NUMSEG, ARITH_PROVE ``n < SUC n``] THEN 530 ASM_SIMP_TAC std_ss [GSYM ADD1, ADD_CLAUSES] THEN 531 ASM_SIMP_TAC std_ss [BILINEAR_RSUB, BILINEAR_LSUB] THEN REAL_ARITH_TAC); 532 533val BILINEAR_SUM_PARTIAL_PRE = store_thm ("BILINEAR_SUM_PARTIAL_PRE", 534 ``!f g h:real->real->real m n. 535 bilinear h 536 ==> (sum (m..n) (\k. h (f k) (g(k) - g(k - 1))) = 537 if m <= n then h (f(n + 1)) (g(n)) - h (f m) (g(m - 1)) - 538 sum (m..n) (\k. h (f(k + 1) - f(k)) (g(k))) 539 else 0)``, 540 REPEAT STRIP_TAC THEN 541 FIRST_ASSUM(MP_TAC o ISPECL [``f:num->real``, ``\k. (g:num->real)(k - 1)``, 542 ``m:num``, ``n:num``] o MATCH_MP BILINEAR_SUM_PARTIAL_SUC) THEN 543 BETA_TAC THEN REWRITE_TAC[ADD_SUB] THEN DISCH_THEN SUBST1_TAC THEN 544 COND_CASES_TAC THEN REWRITE_TAC[]); 545 546(* ------------------------------------------------------------------------- *) 547(* A bit of linear algebra. *) 548(* ------------------------------------------------------------------------- *) 549 550val subspace = new_definition ("subspace", 551 ``subspace s <=> 552 (0:real) IN s /\ 553 (!x y. x IN s /\ y IN s ==> (x + y) IN s) /\ 554 (!c x. x IN s ==> (c * x) IN s)``); 555 556val span = new_definition ("span", 557 ``span s = subspace hull s``); 558 559val dependent = new_definition ("dependent", 560 ``dependent s <=> ?a. a IN s /\ a IN span(s DELETE a)``); 561 562val independent = new_definition ("independent", 563 ``independent s <=> ~(dependent s)``); 564 565(* ------------------------------------------------------------------------- *) 566(* Closure properties of subspaces. *) 567(* ------------------------------------------------------------------------- *) 568 569val SUBSPACE_UNIV = store_thm ("SUBSPACE_UNIV", 570 ``subspace(UNIV:real->bool)``, 571 REWRITE_TAC[subspace, IN_UNIV]); 572 573val SUBSPACE_IMP_NONEMPTY = store_thm ("SUBSPACE_IMP_NONEMPTY", 574 ``!s. subspace s ==> ~(s = {})``, 575 REWRITE_TAC[subspace] THEN SET_TAC[]); 576 577val SUBSPACE_0 = store_thm ("SUBSPACE_0", 578 ``subspace s ==> (0:real) IN s``, 579 SIMP_TAC std_ss [subspace]); 580 581val SUBSPACE_ADD = store_thm ("SUBSPACE_ADD", 582 ``!x y s. subspace s /\ x IN s /\ y IN s ==> (x + y) IN s``, 583 SIMP_TAC std_ss [subspace]); 584 585val SUBSPACE_MUL = store_thm ("SUBSPACE_MUL", 586 ``!x c s. subspace s /\ x IN s ==> (c * x) IN s``, 587 SIMP_TAC std_ss [subspace]); 588 589val SUBSPACE_NEG = store_thm ("SUBSPACE_NEG", 590 ``!x s. subspace s /\ x IN s ==> (-x) IN s``, 591 METIS_TAC [REAL_ARITH ``-x = -(&1) * x:real``, SUBSPACE_MUL]); 592 593val SUBSPACE_SUB = store_thm ("SUBSPACE_SUB", 594 ``!x y s. subspace s /\ x IN s /\ y IN s ==> (x - y) IN s``, 595 SIMP_TAC std_ss [real_sub, SUBSPACE_ADD, SUBSPACE_NEG]); 596 597val SUBSPACE_SUM = store_thm ("SUBSPACE_SUM", 598 ``!s f t. subspace s /\ FINITE t /\ (!x. x IN t ==> f(x) IN s) 599 ==> (sum t f) IN s``, 600 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 601 GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN 602 ONCE_REWRITE_TAC [METIS [] ``!t. ((!x. x IN t ==> f x IN s) ==> sum t f IN s) = 603 (\t. (!x. x IN t ==> f x IN s) ==> sum t f IN s) t``] THEN 604 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 605 ASM_SIMP_TAC std_ss [SUM_CLAUSES, SUBSPACE_0, IN_INSERT, SUBSPACE_ADD]); 606 607val SUBSPACE_LINEAR_IMAGE = store_thm ("SUBSPACE_LINEAR_IMAGE", 608 ``!f s. linear f /\ subspace s ==> subspace(IMAGE f s)``, 609 SIMP_TAC std_ss [subspace, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 610 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN 611 METIS_TAC [linear, LINEAR_0]); 612 613val SUBSPACE_LINEAR_PREIMAGE = store_thm ("SUBSPACE_LINEAR_PREIMAGE", 614 ``!f s. linear f /\ subspace s ==> subspace {x | f(x) IN s}``, 615 SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN 616 METIS_TAC [linear, LINEAR_0]); 617 618val SUBSPACE_TRIVIAL = store_thm ("SUBSPACE_TRIVIAL", 619 ``subspace {0}``, 620 SIMP_TAC std_ss [subspace, IN_SING] THEN CONJ_TAC THEN REAL_ARITH_TAC); 621 622val SUBSPACE_INTER = store_thm ("SUBSPACE_INTER", 623 ``!s t. subspace s /\ subspace t ==> subspace (s INTER t)``, 624 REWRITE_TAC[subspace, IN_INTER] THEN METIS_TAC []); 625 626val SUBSPACE_BIGINTER = store_thm ("SUBSPACE_BIGINTER", 627 ``!f. (!s. s IN f ==> subspace s) ==> subspace(BIGINTER f)``, 628 SIMP_TAC std_ss [subspace, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, IN_BIGINTER]); 629 630val LINEAR_INJECTIVE_0_SUBSPACE = store_thm ("LINEAR_INJECTIVE_0_SUBSPACE", 631 ``!f:real->real s. 632 linear f /\ subspace s 633 ==> ((!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) <=> 634 (!x. x IN s /\ (f x = 0) ==> (x = 0)))``, 635 REPEAT STRIP_TAC THEN 636 GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_SUB_0] THEN 637 ASM_SIMP_TAC std_ss [GSYM LINEAR_SUB] THEN 638 METIS_TAC [REAL_SUB_RZERO, SUBSPACE_SUB, SUBSPACE_0]); 639 640val SUBSPACE_UNION_CHAIN = store_thm ("SUBSPACE_UNION_CHAIN", 641 ``!s t:real->bool. 642 subspace s /\ subspace t /\ subspace(s UNION t) 643 ==> s SUBSET t \/ t SUBSET s``, 644 REPEAT STRIP_TAC THEN REWRITE_TAC [SET_RULE 645 ``s SUBSET t \/ t SUBSET s <=> 646 ~(?x y. x IN s /\ ~(x IN t) /\ y IN t /\ ~(y IN s))``] THEN 647 STRIP_TAC THEN SUBGOAL_THEN ``(x + y:real) IN (s UNION t)`` MP_TAC THENL 648 [MATCH_MP_TAC SUBSPACE_ADD THEN ASM_REWRITE_TAC[] THEN ASM_SET_TAC[], 649 REWRITE_TAC[IN_UNION, DE_MORGAN_THM] THEN 650 METIS_TAC [SUBSPACE_SUB, REAL_ARITH 651 ``((x + y) - x:real = y) /\ ((x + y) - y:real = x)``]]); 652 653(* ------------------------------------------------------------------------- *) 654(* Lemmas. *) 655(* ------------------------------------------------------------------------- *) 656 657val SPAN_SPAN = store_thm ("SPAN_SPAN", 658 ``!s. span(span s) = span s``, 659 REWRITE_TAC[span, HULL_HULL]); 660 661val SPAN_MONO = store_thm ("SPAN_MONO", 662 ``!s t. s SUBSET t ==> span s SUBSET span t``, 663 REWRITE_TAC[span, HULL_MONO]); 664 665val SUBSPACE_SPAN = store_thm ("SUBSPACE_SPAN", 666 ``!s. subspace(span s)``, 667 GEN_TAC THEN REWRITE_TAC[span] THEN MATCH_MP_TAC P_HULL THEN 668 SIMP_TAC std_ss [subspace, IN_BIGINTER]); 669 670val SPAN_CLAUSES = store_thm ("SPAN_CLAUSES", 671 ``(!a s. a IN s ==> a IN span s) /\ 672 ((0) IN span s) /\ 673 (!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s) /\ 674 (!x c s. x IN span s ==> (c * x) IN span s)``, 675 MESON_TAC[span, HULL_SUBSET, SUBSET_DEF, SUBSPACE_SPAN, subspace]); 676 677val SPAN_INDUCT = store_thm ("SPAN_INDUCT", 678 ``!s h. (!x. x IN s ==> x IN h) /\ subspace h ==> !x. x IN span(s) ==> h(x)``, 679 REWRITE_TAC[span] THEN MESON_TAC[SUBSET_DEF, HULL_MINIMAL, IN_DEF]); 680 681val SPAN_EMPTY = store_thm ("SPAN_EMPTY", 682 ``span {} = {0}``, 683 REWRITE_TAC[span] THEN MATCH_MP_TAC HULL_UNIQUE THEN 684 SIMP_TAC std_ss [subspace, SUBSET_DEF, IN_SING, NOT_IN_EMPTY] THEN 685 REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 686 687val INDEPENDENT_EMPTY = store_thm ("INDEPENDENT_EMPTY", 688 ``independent {}``, 689 REWRITE_TAC[independent, dependent, NOT_IN_EMPTY]); 690 691val INDEPENDENT_NONZERO = store_thm ("INDEPENDENT_NONZERO", 692 ``!s. independent s ==> ~(0 IN s)``, 693 REWRITE_TAC[independent, dependent] THEN MESON_TAC[SPAN_CLAUSES]); 694 695val INDEPENDENT_MONO = store_thm ("INDEPENDENT_MONO", 696 ``!s t. independent t /\ s SUBSET t ==> independent s``, 697 REWRITE_TAC[independent, dependent] THEN 698 ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_DELETE]); 699 700val DEPENDENT_MONO = store_thm ("DEPENDENT_MONO", 701 ``!s t:real->bool. dependent s /\ s SUBSET t ==> dependent t``, 702 ONCE_REWRITE_TAC[TAUT `p /\ q ==> r <=> ~r /\ q ==> ~p`] THEN 703 REWRITE_TAC[GSYM independent, INDEPENDENT_MONO]); 704 705val SPAN_SUBSPACE = store_thm ("SPAN_SUBSPACE", 706 ``!b s. b SUBSET s /\ s SUBSET (span b) /\ subspace s ==> (span b = s)``, 707 MESON_TAC[SUBSET_ANTISYM, span, HULL_MINIMAL]); 708 709val SPAN_INDUCT_ALT = store_thm ("SPAN_INDUCT_ALT", 710 ``!s h. h(0) /\ 711 (!c x y. x IN s /\ h(y) ==> h(c * x + y)) 712 ==> !x:real. x IN span(s) ==> h(x)``, 713 REPEAT GEN_TAC THEN DISCH_TAC THEN 714 FIRST_ASSUM(MP_TAC o prove_nonschematic_inductive_relations_exist bool_monoset o concl) THEN 715 DISCH_THEN(X_CHOOSE_THEN ``g:real->bool`` STRIP_ASSUME_TAC) THEN 716 SUBGOAL_THEN ``!x:real. x IN span(s) ==> g(x)`` 717 (fn th => METIS_TAC [th]) THEN 718 MATCH_MP_TAC SPAN_INDUCT THEN SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN 719 SIMP_TAC std_ss [IN_DEF, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 720 ONCE_REWRITE_TAC [METIS [] ``(g x ==> g (c * x)) = (\c x:real. g x ==> g (c * x)) c x``] THEN 721 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN 722 REPEAT CONJ_TAC THENL 723 [METIS_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM, 724 REAL_MUL_LID, REAL_MUL_RZERO], 725 METIS_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM, 726 REAL_MUL_LID, REAL_MUL_RZERO], 727 ONCE_REWRITE_TAC [METIS [] ``!x. (!y. g y ==> g (x + y)) = 728 (\x. !y. g y ==> g (x + y)) (x:real)``] THEN 729 FIRST_X_ASSUM MATCH_MP_TAC THEN 730 SIMP_TAC std_ss [REAL_ADD_LDISTRIB, REAL_MUL_ASSOC] THEN 731 ASM_MESON_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM, 732 REAL_MUL_LID, REAL_MUL_RZERO], 733 ONCE_REWRITE_TAC [METIS [] ``(!x. g (x * y)) = 734 (\y.!x. g (x * y)) (y:real)``] THEN 735 FIRST_X_ASSUM MATCH_MP_TAC THEN 736 SIMP_TAC std_ss [REAL_ADD_LDISTRIB, REAL_MUL_ASSOC] THEN 737 ASM_MESON_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM, 738 REAL_MUL_LID, REAL_MUL_RZERO]]); 739 740(* ------------------------------------------------------------------------- *) 741(* Individual closure properties. *) 742(* ------------------------------------------------------------------------- *) 743 744val SPAN_SUPERSET = store_thm ("SPAN_SUPERSET", 745 ``!x. x IN s ==> x IN span s``, 746 MESON_TAC[SPAN_CLAUSES]); 747 748val SPAN_INC = store_thm ("SPAN_INC", 749 ``!s. s SUBSET span s``, 750 REWRITE_TAC[SUBSET_DEF, SPAN_SUPERSET]); 751 752val SPAN_UNION_SUBSET = store_thm ("SPAN_UNION_SUBSET", 753 ``!s t. span s UNION span t SUBSET span(s UNION t)``, 754 REWRITE_TAC[span, HULL_UNION_SUBSET]); 755 756val SPAN_UNIV = store_thm ("SPAN_UNIV", 757 ``span univ(:real) = univ(:real)``, 758 SIMP_TAC std_ss [SPAN_INC, SET_RULE ``UNIV SUBSET s ==> (s = UNIV)``]); 759 760val SPAN_0 = store_thm ("SPAN_0", 761 ``(0) IN span s``, 762 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_0]); 763 764val SPAN_ADD = store_thm ("SPAN_ADD", 765 ``!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s``, 766 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_ADD]); 767 768val SPAN_MUL = store_thm ("SPAN_MUL", 769 ``!x c s. x IN span s ==> (c * x) IN span s``, 770 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_MUL]); 771 772val SPAN_MUL_EQ = store_thm ("SPAN_MUL_EQ", 773 ``!x:real c s. ~(c = &0) ==> ((c * x) IN span s <=> x IN span s)``, 774 REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN ASM_SIMP_TAC std_ss [SPAN_MUL] THEN 775 SUBGOAL_THEN ``(inv(c) * c * x:real) IN span s`` MP_TAC THENL 776 [REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC std_ss [SPAN_MUL], 777 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID]]); 778 779val SPAN_NEG = store_thm ("SPAN_NEG", 780 ``!x s. x IN span s ==> (-x) IN span s``, 781 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_NEG]); 782 783val SPAN_NEG_EQ = store_thm ("SPAN_NEG_EQ", 784 ``!x s. -x IN span s <=> x IN span s``, 785 MESON_TAC[SPAN_NEG, REAL_NEG_NEG]); 786 787val SPAN_SUB = store_thm ("SPAN_SUB", 788 ``!x y s. x IN span s /\ y IN span s ==> (x - y) IN span s``, 789 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_SUB]); 790 791val SPAN_SUM = store_thm ("SPAN_SUM", 792 ``!s f t. FINITE t /\ (!x. x IN t ==> f(x) IN span(s)) 793 ==> (sum t f) IN span(s)``, 794 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_SUM]); 795 796val SPAN_ADD_EQ = store_thm ("SPAN_ADD_EQ", 797 ``!s x y. x IN span s ==> ((x + y) IN span s <=> y IN span s)``, 798 MESON_TAC[SPAN_ADD, SPAN_SUB, REAL_ARITH ``(x + y) - x:real = y``]); 799 800val SPAN_EQ_SELF = store_thm ("SPAN_EQ_SELF", 801 ``!s. (span s = s) <=> subspace s``, 802 GEN_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSPACE_SPAN], ALL_TAC] THEN 803 DISCH_TAC THEN MATCH_MP_TAC SPAN_SUBSPACE THEN 804 ASM_REWRITE_TAC[SUBSET_REFL, SPAN_INC]); 805 806val SPAN_SUBSET_SUBSPACE = store_thm ("SPAN_SUBSET_SUBSPACE", 807 ``!s t:real->bool. s SUBSET t /\ subspace t ==> span s SUBSET t``, 808 MESON_TAC[SPAN_MONO, SPAN_EQ_SELF]); 809 810val SURJECTIVE_IMAGE_EQ = store_thm ("SURJECTIVE_IMAGE_EQ", 811 ``!s t. (!y. y IN t ==> ?x. f x = y) /\ (!x. (f x) IN t <=> x IN s) 812 ==> (IMAGE f s = t)``, 813 SET_TAC[]); 814 815val SUBSPACE_TRANSLATION_SELF = store_thm ("SUBSPACE_TRANSLATION_SELF", 816 ``!s a. subspace s /\ a IN s ==> (IMAGE (\x. a + x) s = s)``, 817 REPEAT STRIP_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN 818 FIRST_ASSUM(SUBST1_TAC o SYM o REWRITE_RULE [GSYM SPAN_EQ_SELF]) THEN 819 ASM_SIMP_TAC std_ss [SPAN_ADD_EQ, SPAN_CLAUSES] THEN 820 REWRITE_TAC[REAL_ARITH ``(a + x:real = y) <=> (x = y - a)``, EXISTS_REFL]); 821 822val SUBSPACE_TRANSLATION_SELF_EQ = store_thm ("SUBSPACE_TRANSLATION_SELF_EQ", 823 ``!s a:real. subspace s ==> ((IMAGE (\x. a + x) s = s) <=> a IN s)``, 824 REPEAT STRIP_TAC THEN EQ_TAC THEN 825 ASM_SIMP_TAC std_ss [SUBSPACE_TRANSLATION_SELF] THEN 826 DISCH_THEN(MP_TAC o AP_TERM ``\s. (a:real) IN s``) THEN 827 SIMP_TAC std_ss [] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN 828 REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC ``0:real`` THEN 829 ASM_MESON_TAC[subspace, REAL_ADD_RID]); 830 831val SUBSPACE_SUMS = store_thm ("SUBSPACE_SUMS", 832 ``!s t. subspace s /\ subspace t 833 ==> subspace {x + y | x IN s /\ y IN t}``, 834 SIMP_TAC std_ss [subspace, FORALL_IN_GSPEC, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 835 SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN REPEAT STRIP_TAC THENL 836 [ASM_MESON_TAC[REAL_ADD_LID], 837 ONCE_REWRITE_TAC[REAL_ARITH 838 ``(x + y) + (x' + y'):real = (x + x') + (y + y')``] THEN 839 ASM_MESON_TAC[], 840 REWRITE_TAC[REAL_ADD_LDISTRIB] THEN ASM_MESON_TAC[]]); 841 842val SPAN_UNION = store_thm ("SPAN_UNION", 843 ``!s t. span(s UNION t) = {x + y:real | x IN span s /\ y IN span t}``, 844 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 845 [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN 846 SIMP_TAC std_ss [SUBSPACE_SUMS, SUBSPACE_SPAN] THEN 847 SIMP_TAC std_ss [SUBSET_DEF, IN_UNION, GSPECIFICATION, EXISTS_PROD] THEN 848 X_GEN_TAC ``x:real`` THEN STRIP_TAC THENL 849 [MAP_EVERY EXISTS_TAC [``x:real``, ``0:real``] THEN 850 ASM_SIMP_TAC std_ss [SPAN_SUPERSET, SPAN_0, REAL_ADD_RID], 851 MAP_EVERY EXISTS_TAC [``0:real``, ``x:real``] THEN 852 ASM_SIMP_TAC std_ss [SPAN_SUPERSET, SPAN_0, REAL_ADD_LID]], 853 SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_GSPEC] THEN 854 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_ADD THEN 855 ASM_MESON_TAC[SPAN_MONO, SUBSET_UNION, SUBSET_DEF]]); 856 857(* ------------------------------------------------------------------------- *) 858(* Equality in Cauchy-Schwarz and triangle inequalities. *) 859(* ------------------------------------------------------------------------- *) 860 861val ABS_CAUCHY_SCHWARZ_EQ = store_thm 862 ("ABS_CAUCHY_SCHWARZ_EQ", 863 ``!x:real y. (x * y = abs(x) * abs(y)) <=> (abs(x) * y = abs(y) * x)``, 864 REPEAT GEN_TAC THEN ASM_CASES_TAC ``0 <= x:real`` THEN 865 (ASM_CASES_TAC ``0 <= y:real``) THEN ASM_REWRITE_TAC [abs] THENL 866 [ASM_REAL_ARITH_TAC, ALL_TAC, ALL_TAC, ASM_REAL_ARITH_TAC] THEN 867 ((MP_TAC o SPECL [``x:real``,``y:real``]) REAL_LT_TOTAL THEN STRIP_TAC THEN 868 TRY (ASM_REAL_ARITH_TAC)) THEN COND_CASES_TAC THEN EQ_TAC THEN 869 TRY (ASM_REAL_ARITH_TAC)); 870 871val ABS_CAUCHY_SCHWARZ_ABS_EQ = store_thm 872 ("ABS_CAUCHY_SCHWARZ_ABS_EQ", 873 ``!x:real y. (abs(x * y) = abs(x) * abs(y)) <=> 874 (abs(x) * y = abs(y) * x) \/ (abs(x) * y = -abs(y) * x)``, 875 SIMP_TAC std_ss [REAL_ARITH ``&0 <= a ==> ((abs x = a) <=> (x = a) \/ (-x = a:real))``, 876 REAL_LE_MUL, ABS_POS, REAL_MUL_RNEG] THEN 877 REAL_ARITH_TAC); 878 879val REAL_EQ_LINV = store_thm 880 ("REAL_EQ_LINV", ``!x. (-x = (x :real)) <=> (x = 0)``, 881 GEN_TAC 882 >> REWRITE_TAC [SYM (Q.SPECL [`x`, `-x`, `x`] REAL_EQ_LADD)] 883 >> REWRITE_TAC [REAL_ADD_RINV, REAL_DOUBLE] 884 >> RW_TAC real_ss [REAL_ENTIRE]); 885 886val REAL_EQ_RINV = store_thm 887 ("REAL_EQ_RINV", ``!x. ((x :real) = -x) <=> (x = 0)``, 888 GEN_TAC 889 >> REWRITE_TAC [SYM (Q.SPECL [`x`, `x`, `-x`] REAL_EQ_LADD)] 890 >> REWRITE_TAC [REAL_ADD_RINV, REAL_DOUBLE] 891 >> RW_TAC real_ss [REAL_ENTIRE]); 892 893(* this proof is too advanced in realScript *) 894val ABS_TRIANGLE_EQ = store_thm ("ABS_TRIANGLE_EQ", 895 ``!x y:real. (abs(x + y) = abs(x) + abs(y)) <=> (abs(x) * y = abs(y) * x)``, 896 rpt GEN_TAC 897 >> ASM_CASES_TAC ``0 <= x:real`` 898 >> ASM_CASES_TAC ``0 <= y:real`` 899 >> ASM_REWRITE_TAC [abs] 900 >- ( `0 <= x + y` by PROVE_TAC [REAL_LE_ADD] \\ 901 ASM_SIMP_TAC bool_ss [] >> REAL_ARITH_TAC ) 902 >| [ (* goal 1 (of 3) *) 903 Cases_on `0 <= x + y` 904 >- ( ASM_SIMP_TAC bool_ss [REAL_EQ_LADD, Once REAL_MUL_SYM] \\ 905 EQ_TAC >- PROVE_TAC [] \\ 906 REWRITE_TAC [REAL_EQ_RMUL] \\ 907 STRIP_TAC >> FULL_SIMP_TAC bool_ss [REAL_ADD_LID] ) \\ 908 ASM_SIMP_TAC bool_ss [REAL_NEG_ADD, REAL_EQ_RADD, Once REAL_MUL_SYM] \\ 909 `(-x = x) = (x = 0)` by PROVE_TAC [REAL_EQ_LINV] \\ 910 POP_ASSUM (REWRITE_TAC o wrap) \\ 911 REWRITE_TAC [REAL_EQ_RMUL] \\ 912 EQ_TAC >- PROVE_TAC [] \\ 913 STRIP_TAC \\ 914 `y = 0` by PROVE_TAC [REAL_EQ_RINV] \\ 915 FULL_SIMP_TAC bool_ss [REAL_ADD_RID], 916 (* goal 2 (of 3) *) 917 Cases_on `0 <= x + y` 918 >- ( ASM_SIMP_TAC bool_ss [REAL_EQ_RADD, Once REAL_MUL_SYM] \\ 919 EQ_TAC >- PROVE_TAC [] \\ 920 REWRITE_TAC [REAL_EQ_LMUL] \\ 921 reverse STRIP_TAC >- ( MATCH_MP_TAC EQ_SYM >> ASM_REWRITE_TAC [] ) \\ 922 REWRITE_TAC [REAL_EQ_RINV] \\ 923 FULL_SIMP_TAC bool_ss [REAL_ADD_RID] ) \\ 924 FULL_SIMP_TAC bool_ss [REAL_NEG_ADD] \\ 925 REWRITE_TAC [REAL_EQ_LADD, REAL_EQ_LINV, Once REAL_MUL_SYM] \\ 926 EQ_TAC >- RW_TAC real_ss [] \\ 927 REWRITE_TAC [REAL_EQ_LMUL, REAL_EQ_LINV] >> STRIP_TAC \\ 928 FULL_SIMP_TAC bool_ss [REAL_ADD_LID], 929 (* goal 3 (of 3) *) 930 Know `~(0 <= x + y)` 931 >- (FULL_SIMP_TAC bool_ss [REAL_NOT_LE] \\ 932 PROVE_TAC [REAL_LT_ADD2, REAL_ADD_RID]) \\ 933 DISCH_TAC >> ASM_SIMP_TAC bool_ss [] \\ 934 REWRITE_TAC [REAL_NEG_ADD] \\ 935 PROVE_TAC [REAL_NEG_RMUL, REAL_MUL_SYM] ]); 936 937val DIST_TRIANGLE_EQ = store_thm ("DIST_TRIANGLE_EQ", 938 ``!x y z:real. (dist(x,z) = dist(x,y) + dist(y,z)) <=> 939 (abs (x - y) * (y - z) = abs (y - z) * (x - y))``, 940 REWRITE_TAC[GSYM ABS_TRIANGLE_EQ, dist] THEN REAL_ARITH_TAC); 941 942(* ------------------------------------------------------------------------- *) 943(* Collinearity. *) 944(* ------------------------------------------------------------------------- *) 945 946val _ = hide "collinear"; 947 948val collinear = new_definition ("collinear", 949 ``collinear s <=> ?u. !x y:real. x IN s /\ y IN s ==> ?c. x - y = c * u``); 950 951val COLLINEAR_SUBSET = store_thm ("COLLINEAR_SUBSET", 952 ``!s t. collinear t /\ s SUBSET t ==> collinear s``, 953 REWRITE_TAC[collinear] THEN SET_TAC[]); 954 955val COLLINEAR_EMPTY = store_thm ("COLLINEAR_EMPTY", 956 ``collinear {}``, 957 REWRITE_TAC[collinear, NOT_IN_EMPTY]); 958 959val COLLINEAR_SING = store_thm ("COLLINEAR_SING", 960 ``!x:real. collinear {x}``, 961 SIMP_TAC std_ss [collinear, IN_SING, REAL_SUB_REFL] THEN 962 METIS_TAC [REAL_MUL_LZERO]); 963 964val COLLINEAR_2 = store_thm ("COLLINEAR_2", 965 ``!x y:real. collinear {x;y}``, 966 REPEAT GEN_TAC THEN REWRITE_TAC[collinear, IN_INSERT, NOT_IN_EMPTY] THEN 967 EXISTS_TAC ``x - y:real`` THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THENL 968 [EXISTS_TAC ``&0:real``, EXISTS_TAC ``&1:real``, 969 EXISTS_TAC ``- &1:real``, EXISTS_TAC ``&0:real``] THEN 970 REAL_ARITH_TAC); 971 972val COLLINEAR_SMALL = store_thm ("COLLINEAR_SMALL", 973 ``!s. FINITE s /\ CARD s <= 2 ==> collinear s``, 974 REWRITE_TAC[ARITH_PROVE ``s <= 2 <=> (s = 0) \/ (s = 1) \/ (s = 2:num)``] THEN 975 REWRITE_TAC[LEFT_AND_OVER_OR, GSYM HAS_SIZE] THEN 976 REWRITE_TAC [ONE, TWO, HAS_SIZE_CLAUSES] THEN 977 REPEAT STRIP_TAC THEN 978 ASM_REWRITE_TAC[COLLINEAR_EMPTY, COLLINEAR_SING, COLLINEAR_2]); 979 980val COLLINEAR_3 = store_thm ("COLLINEAR_3", 981 ``!x y z. collinear {x;y;z} <=> collinear {0;x - y;z - y}``, 982 REPEAT GEN_TAC THEN 983 SIMP_TAC std_ss [collinear, FORALL_IN_INSERT, CONJ_EQ_IMP, 984 RIGHT_FORALL_IMP_THM, NOT_IN_EMPTY] THEN 985 AP_TERM_TAC THEN ABS_TAC THEN 986 METIS_TAC [REAL_ARITH ``x - y = (x - y) - 0:real``, 987 REAL_ARITH ``y - x = 0 - (x - y:real)``, 988 REAL_ARITH ``x - z:real = (x - y) - (z - y)``]); 989 990val COLLINEAR_LEMMA = store_thm ("COLLINEAR_LEMMA", 991 ``!x y:real. collinear {0;x;y} <=> 992 (x = 0) \/ (y = 0) \/ ?c. y = c * x``, 993 REPEAT GEN_TAC THEN 994 MAP_EVERY ASM_CASES_TAC [``x:real = 0``, ``y:real = 0``] THEN 995 TRY(ONCE_REWRITE_TAC [INSERT_COMM] THEN 996 ASM_REWRITE_TAC[INSERT_INSERT, COLLINEAR_SING, COLLINEAR_2] THEN NO_TAC) THEN 997 ASM_REWRITE_TAC[collinear] THEN EQ_TAC THENL 998 [DISCH_THEN(X_CHOOSE_THEN ``u:real`` 999 (fn th => MP_TAC(SPECL [``x:real``, ``0:real``] th) THEN 1000 MP_TAC(SPECL [``y:real``, ``0:real``] th))) THEN 1001 REWRITE_TAC[IN_INSERT, REAL_SUB_RZERO] THEN 1002 DISCH_THEN(X_CHOOSE_THEN ``e:real`` SUBST_ALL_TAC) THEN 1003 DISCH_THEN(X_CHOOSE_THEN ``d:real`` SUBST_ALL_TAC) THEN 1004 EXISTS_TAC ``e / d:real`` THEN REWRITE_TAC[REAL_MUL_ASSOC] THEN 1005 RULE_ASSUM_TAC(REWRITE_RULE[REAL_ENTIRE, DE_MORGAN_THM]) THEN 1006 ASM_SIMP_TAC real_ss [REAL_DIV_RMUL], 1007 STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN ASM_REWRITE_TAC[] THEN 1008 REWRITE_TAC[IN_INSERT, NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN 1009 ASM_REWRITE_TAC[] THENL 1010 [EXISTS_TAC ``&0:real``, EXISTS_TAC ``- &1:real``, EXISTS_TAC ``-c:real``, 1011 EXISTS_TAC ``&1:real``, EXISTS_TAC ``&0:real``, EXISTS_TAC ``&1 - c:real``, 1012 EXISTS_TAC ``c:real``, EXISTS_TAC ``c - &1:real``, EXISTS_TAC ``&0:real``] THEN 1013 REAL_ARITH_TAC]); 1014 1015val COLLINEAR_LEMMA_ALT = store_thm ("COLLINEAR_LEMMA_ALT", 1016 ``!x y. collinear {0;x;y} <=> (x = 0) \/ ?c. y = c * x``, 1017 REWRITE_TAC[COLLINEAR_LEMMA] THEN METIS_TAC [REAL_MUL_LZERO]); 1018 1019val ABS_CAUCHY_SCHWARZ_EQUAL = store_thm ("ABS_CAUCHY_SCHWARZ_EQUAL", 1020 ``!x y:real. (abs(x * y) = abs(x) * abs(y)) <=> collinear {0;x;y}``, 1021 REPEAT GEN_TAC THEN REWRITE_TAC[ABS_CAUCHY_SCHWARZ_ABS_EQ] THEN 1022 MAP_EVERY ASM_CASES_TAC [``x:real = 0``, ``y:real = 0``] THEN 1023 TRY(ONCE_ASM_REWRITE_TAC [INSERT_COMM] THEN 1024 ASM_REWRITE_TAC[INSERT_INSERT, COLLINEAR_SING, COLLINEAR_2, ABS_0, 1025 REAL_MUL_LZERO, REAL_MUL_RZERO] THEN NO_TAC) THEN 1026 ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN EQ_TAC THENL 1027 [STRIP_TAC THENL 1028 [EXISTS_TAC ``y / x:real``, EXISTS_TAC ``y / x:real``] THEN 1029 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL], 1030 ASM_REAL_ARITH_TAC]); 1031 1032val MUL_CAUCHY_SCHWARZ_EQUAL = store_thm ("MUL_CAUCHY_SCHWARZ_EQUAL", 1033 ``!x y:real. 1034 ((x * y) pow 2 = (x * x) * (y * y)) <=> 1035 collinear {0;x;y}``, 1036 REWRITE_TAC[GSYM ABS_CAUCHY_SCHWARZ_EQUAL] THEN 1037 REPEAT GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH 1038 ``&0 <= y /\ ((u:real = v) <=> (x = abs y)) ==> ((u = v) <=> (x = y:real))``) THEN 1039 SIMP_TAC std_ss [ABS_POS, REAL_LE_MUL] THEN 1040 REWRITE_TAC[REAL_EQ_SQUARE_ABS] THEN REWRITE_TAC[POW_MUL, GSYM POW_2] THEN 1041 REWRITE_TAC [POW_2] THEN REAL_ARITH_TAC); 1042 1043val COLLINEAR_3_EXPAND = store_thm ("COLLINEAR_3_EXPAND", 1044 ``!a b c:real. collinear{a;b;c} <=> ((a = c) \/ ?u. b = u * a + (&1 - u) * c)``, 1045 REPEAT GEN_TAC THEN 1046 ONCE_REWRITE_TAC[SET_RULE ``{a;b;c} = {a;c;b}``] THEN 1047 ONCE_REWRITE_TAC[COLLINEAR_3] THEN 1048 REWRITE_TAC[COLLINEAR_LEMMA, REAL_SUB_0] THEN 1049 ASM_CASES_TAC ``a:real = c`` THEN ASM_REWRITE_TAC[] THEN 1050 ASM_CASES_TAC ``b:real = c`` THEN 1051 ASM_REWRITE_TAC[REAL_ARITH ``u * c + (&1 - u) * c = c:real``] THENL 1052 [EXISTS_TAC ``&0:real`` THEN REAL_ARITH_TAC, 1053 AP_TERM_TAC THEN ABS_TAC THEN REAL_ARITH_TAC]); 1054 1055val COLLINEAR_TRIPLES = store_thm ("COLLINEAR_TRIPLES", 1056 ``!s a b:real. 1057 ~(a = b) 1058 ==> (collinear(a INSERT b INSERT s) <=> 1059 !x. x IN s ==> collinear{a;b;x})``, 1060 REPEAT STRIP_TAC THEN EQ_TAC THENL 1061 [REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP 1062 (REWRITE_RULE[CONJ_EQ_IMP] COLLINEAR_SUBSET)) THEN 1063 ASM_SET_TAC[], 1064 ONCE_REWRITE_TAC[SET_RULE ``{a;b;x} = {a;x;b}``] THEN 1065 ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN DISCH_TAC THEN 1066 SUBGOAL_THEN 1067 ``!x:real. x IN (a INSERT b INSERT s) ==> ?u. x = u * a + (&1 - u) * b`` 1068 MP_TAC THENL 1069 [ASM_SIMP_TAC real_ss [FORALL_IN_INSERT] THEN CONJ_TAC THENL 1070 [EXISTS_TAC ``&1:real`` THEN REAL_ARITH_TAC, 1071 EXISTS_TAC ``&0:real`` THEN REAL_ARITH_TAC], 1072 POP_ASSUM_LIST(K ALL_TAC) THEN DISCH_TAC THEN 1073 REWRITE_TAC[collinear] THEN EXISTS_TAC ``b - a:real`` THEN 1074 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 1075 FIRST_X_ASSUM(fn th => MP_TAC(SPEC ``x:real`` th) THEN MP_TAC(SPEC 1076 ``y:real`` th)) THEN 1077 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN 1078 ASM_REWRITE_TAC[REAL_ARITH 1079 ``(u * a + (&1 - u) * b) - (v * a + (&1 - v) * b):real = 1080 (v - u) * (b - a)``] THEN 1081 METIS_TAC []]]); 1082 1083val COLLINEAR_4_3 = store_thm ("COLLINEAR_4_3", 1084 ``!a b c d:real. 1085 ~(a = b) 1086 ==> (collinear {a;b;c;d} <=> collinear{a;b;c} /\ collinear{a;b;d})``, 1087 REPEAT STRIP_TAC THEN 1088 MP_TAC(ISPECL [``{c:real;d}``, ``a:real``, ``b:real``] 1089 COLLINEAR_TRIPLES) THEN 1090 ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN 1091 SIMP_TAC real_ss [FORALL_IN_INSERT, NOT_IN_EMPTY]); 1092 1093val COLLINEAR_3_TRANS = store_thm ("COLLINEAR_3_TRANS", 1094 ``!a b c d:real. 1095 collinear{a;b;c} /\ collinear{b;c;d} /\ ~(b = c) ==> collinear{a;b;d}``, 1096 REPEAT STRIP_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN 1097 EXISTS_TAC ``{b:real;c;a;d}`` THEN ASM_SIMP_TAC std_ss [COLLINEAR_4_3] THEN 1098 CONJ_TAC THENL [ALL_TAC, SET_TAC[]] THEN 1099 ONCE_ASM_REWRITE_TAC [SET_RULE ``{b;c;a} = {a;b;c}``] THEN METIS_TAC []); 1100 1101(* ------------------------------------------------------------------------- *) 1102(* Between-ness. *) 1103(* ------------------------------------------------------------------------- *) 1104 1105val between = new_definition ("between", 1106 ``between x (a,b) <=> (dist(a,b) = dist(a,x) + dist(x,b))``); 1107 1108val BETWEEN_REFL = store_thm ("BETWEEN_REFL", 1109 ``!a b. between a (a,b) /\ between b (a,b) /\ between a (a,a)``, 1110 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1111 1112val BETWEEN_REFL_EQ = store_thm ("BETWEEN_REFL_EQ", 1113 ``!a x. between x (a,a) <=> (x = a)``, 1114 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1115 1116val BETWEEN_SYM = store_thm ("BETWEEN_SYM", 1117 ``!a b x. between x (a,b) <=> between x (b,a)``, 1118 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1119 1120val BETWEEN_ANTISYM = store_thm ("BETWEEN_ANTISYM", 1121 ``!a b c. between a (b,c) /\ between b (a,c) ==> (a = b)``, 1122 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1123 1124val BETWEEN_TRANS = store_thm ("BETWEEN_TRANS", 1125 ``!a b c d. between a (b,c) /\ between d (a,c) ==> between d (b,c)``, 1126 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1127 1128val BETWEEN_TRANS_2 = store_thm ("BETWEEN_TRANS_2", 1129 ``!a b c d. between a (b,c) /\ between d (a,b) ==> between a (c,d)``, 1130 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1131 1132val BETWEEN_ABS = store_thm ("BETWEEN_ABS", 1133 ``!a b x:real. 1134 between x (a,b) <=> (abs(x - a) * (b - x) = abs(b - x) * (x - a))``, 1135 REPEAT GEN_TAC THEN REWRITE_TAC[between, DIST_TRIANGLE_EQ] THEN 1136 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [ABS_SUB] THEN REAL_ARITH_TAC); 1137 1138val BETWEEN_IMP_COLLINEAR = store_thm ("BETWEEN_IMP_COLLINEAR", 1139 ``!a b x:real. between x (a,b) ==> collinear {a;x;b}``, 1140 REPEAT GEN_TAC THEN ASM_CASES_TAC ``x:real = a`` THENL 1141 [ONCE_REWRITE_TAC[COLLINEAR_3, BETWEEN_ABS] THEN 1142 DISCH_TAC THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA, REAL_SUB_REFL] THEN 1143 ASM_REAL_ARITH_TAC, 1144 ONCE_REWRITE_TAC[COLLINEAR_3, BETWEEN_ABS] THEN 1145 DISCH_TAC THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN 1146 DISJ2_TAC THEN DISJ2_TAC THEN EXISTS_TAC ``(b - x) / (a - x:real)`` THEN 1147 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH 1148 ``(x <> a) = ((a - x) <> 0:real)``]) THEN 1149 ASM_SIMP_TAC real_ss [REAL_DIV_RMUL]]); 1150 1151val COLLINEAR_BETWEEN_CASES = store_thm ("COLLINEAR_BETWEEN_CASES", 1152 ``!a b c:real. 1153 collinear {a;b;c} <=> 1154 between a (b,c) \/ between b (c,a) \/ between c (a,b)``, 1155 REPEAT STRIP_TAC THEN EQ_TAC THENL 1156 [REWRITE_TAC[COLLINEAR_3_EXPAND] THEN 1157 ASM_CASES_TAC ``c:real = a`` THEN ASM_REWRITE_TAC[BETWEEN_REFL] THEN 1158 STRIP_TAC THEN ASM_REWRITE_TAC[between, dist] THEN 1159 ASM_REAL_ARITH_TAC, 1160 DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN (MP_TAC o MATCH_MP 1161 BETWEEN_IMP_COLLINEAR)) THEN 1162 METIS_TAC[INSERT_COMM]]); 1163 1164val COLLINEAR_DIST_BETWEEN = store_thm ("COLLINEAR_DIST_BETWEEN", 1165 ``!a b x. collinear {x;a;b} /\ 1166 dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b) 1167 ==> between x (a,b)``, 1168 SIMP_TAC std_ss [COLLINEAR_BETWEEN_CASES, between, dist] THEN REAL_ARITH_TAC); 1169 1170val COLLINEAR_1 = store_thm ("COLLINEAR_1", 1171 ``!s:real->bool. collinear s``, 1172 GEN_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN 1173 EXISTS_TAC ``(0:real) INSERT (1:real) INSERT s`` THEN 1174 CONJ_TAC THENL [ALL_TAC, SET_TAC[]] THEN 1175 W(MP_TAC o PART_MATCH (lhs o rand) COLLINEAR_TRIPLES o snd) THEN 1176 REWRITE_TAC[REAL_ARITH ``0 <> 1:real``] THEN DISCH_THEN SUBST1_TAC THEN 1177 REWRITE_TAC[COLLINEAR_BETWEEN_CASES] THEN 1178 REWRITE_TAC[between, dist, ABS_N] THEN 1179 REAL_ARITH_TAC); 1180 1181(* ------------------------------------------------------------------------- *) 1182(* Midpoint between two points. *) 1183(* ------------------------------------------------------------------------- *) 1184 1185val midpoint = new_definition ("midpoint", 1186 ``midpoint(a,b) = inv(&2:real) * (a + b)``); 1187 1188Theorem MIDPOINT_REFL: !x. midpoint(x,x) = x 1189Proof 1190 REWRITE_TAC[midpoint, REAL_DOUBLE, REAL_MUL_ASSOC] THEN 1191 SIMP_TAC std_ss [REAL_MUL_LINV, REAL_ARITH ``2 <> 0:real``] THEN 1192 REAL_ARITH_TAC 1193QED 1194 1195val MIDPOINT_SYM = store_thm ("MIDPOINT_SYM", 1196 ``!a b. midpoint(a,b) = midpoint(b,a)``, 1197 METIS_TAC[midpoint, REAL_ADD_SYM]); 1198 1199val DIST_MIDPOINT = store_thm ("DIST_MIDPOINT", 1200 ``!a b. (dist(a,midpoint(a,b)) = dist(a,b) / &2) /\ 1201 (dist(b,midpoint(a,b)) = dist(a,b) / &2) /\ 1202 (dist(midpoint(a,b),a) = dist(a,b) / &2) /\ 1203 (dist(midpoint(a,b),b) = dist(a,b) / &2)``, 1204 REWRITE_TAC[midpoint, dist] THEN 1205 SIMP_TAC std_ss [REAL_EQ_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 1206 ONCE_REWRITE_TAC [GSYM ABS_N] THEN 1207 REWRITE_TAC [GSYM ABS_MUL, REAL_SUB_RDISTRIB] THEN REWRITE_TAC [ABS_N] THEN 1208 ONCE_REWRITE_TAC [REAL_ARITH ``a * b * c = a * c * b:real``] THEN 1209 SIMP_TAC std_ss [REAL_MUL_LINV, REAL_ARITH ``2 <> 0:real``] THEN 1210 REAL_ARITH_TAC); 1211 1212val MIDPOINT_EQ_ENDPOINT = store_thm ("MIDPOINT_EQ_ENDPOINT", 1213 ``!a b. ((midpoint(a,b) = a) <=> (a = b)) /\ 1214 ((midpoint(a,b) = b) <=> (a = b)) /\ 1215 ((a = midpoint(a,b)) <=> (a = b)) /\ 1216 ((b = midpoint(a,b)) <=> (a = b))``, 1217 REWRITE_TAC[midpoint] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 1218 REWRITE_TAC [GSYM real_div] THEN 1219 SIMP_TAC std_ss 1220 [REAL_EQ_RDIV_EQ, REAL_EQ_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 1221 REAL_ARITH_TAC); 1222 1223val BETWEEN_MIDPOINT = store_thm ("BETWEEN_MIDPOINT", 1224 ``!a b. between (midpoint(a,b)) (a,b) /\ between (midpoint(a,b)) (b,a)``, 1225 REWRITE_TAC[between, midpoint] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 1226 REWRITE_TAC [dist, GSYM real_div] THEN 1227 ONCE_REWRITE_TAC [REAL_ARITH ``a / 2 - b = a / 2 - b * 1:real``] THEN 1228 ONCE_REWRITE_TAC [REAL_ARITH ``b - a / 2 = b * 1 - a / 2:real``] THEN 1229 REWRITE_TAC [ 1230 METIS [REAL_DIV_REFL, REAL_ARITH ``2 <> 0:real``] ``1 = 2/2:real``] THEN 1231 REWRITE_TAC [real_div, REAL_MUL_ASSOC, real_sub] THEN 1232 REWRITE_TAC [REAL_ARITH ``-(a * b) = -a * b:real``] THEN 1233 REWRITE_TAC [GSYM real_div] THEN SIMP_TAC std_ss [REAL_DIV_ADD] THEN 1234 REWRITE_TAC [real_div, ABS_MUL] THEN 1235 SIMP_TAC std_ss [ABS_N, ABS_INV, REAL_ARITH ``2 <> 0:real``] THEN 1236 REWRITE_TAC [GSYM REAL_ADD_RDISTRIB] THEN REWRITE_TAC [GSYM real_div] THEN 1237 SIMP_TAC std_ss [REAL_EQ_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 1238 REAL_ARITH_TAC); 1239 1240val MIDPOINT_LINEAR_IMAGE = store_thm ("MIDPOINT_LINEAR_IMAGE", 1241 ``!f a b. linear f ==> (midpoint(f a,f b) = f(midpoint(a,b)))``, 1242 SIMP_TAC std_ss [midpoint, LINEAR_ADD, LINEAR_CMUL]); 1243 1244val COLLINEAR_MIDPOINT = store_thm ("COLLINEAR_MIDPOINT", 1245 ``!a b. collinear{a;midpoint(a,b);b}``, 1246 REPEAT GEN_TAC THEN REWRITE_TAC[COLLINEAR_3_EXPAND, midpoint] THEN 1247 DISJ2_TAC THEN REWRITE_TAC [REAL_ARITH ``u * a + (1 - u) * b = 1248 a * u - b * u + b:real``] THEN 1249 EXISTS_TAC ``inv &2:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_MUL_SYM] THEN 1250 REWRITE_TAC [REAL_ADD_RDISTRIB] THEN 1251 GEN_REWR_TAC (RAND_CONV o RAND_CONV) [GSYM REAL_HALF] THEN 1252 REWRITE_TAC [GSYM real_div] THEN REAL_ARITH_TAC); 1253 1254Theorem MIDPOINT_COLLINEAR: 1255 !a b c:real. 1256 a <> c ==> 1257 ((b = midpoint(a,c)) <=> collinear{a;b;c} /\ (dist(a,b) = dist(b,c))) 1258Proof 1259 REPEAT STRIP_TAC THEN 1260 MATCH_MP_TAC(TAUT `(a ==> b) /\ (b ==> (a <=> c)) ==> (a <=> b /\ c)`) THEN 1261 SIMP_TAC std_ss [COLLINEAR_MIDPOINT] THEN 1262 ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN 1263 STRIP_TAC THEN ASM_REWRITE_TAC[midpoint, dist] THEN 1264 REWRITE_TAC 1265 [REAL_ARITH ``a - (u * a + (&1 - u) * c) = (&1 - u) * (a - c:real)``, 1266 REAL_ARITH ``(u * a + (&1 - u) * c) - c = u * (a - c:real)``] THEN 1267 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN 1268 SIMP_TAC std_ss [REAL_EQ_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 1269 ASM_REAL_ARITH_TAC 1270QED 1271 1272(* ------------------------------------------------------------------------ *) 1273(* MISC *) 1274(* ------------------------------------------------------------------------ *) 1275 1276val INDEPENDENT_MONO = store_thm ("INDEPENDENT_MONO", 1277 ``!s t. independent t /\ s SUBSET t ==> independent s``, 1278 SIMP_TAC std_ss [independent, dependent] THEN 1279 ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_DELETE]); 1280 1281val SPAN_BREAKDOWN = store_thm ("SPAN_BREAKDOWN", 1282 ``!b s a:real. b IN s /\ a IN span s ==> ?k. (a - k * b) IN span(s DELETE b)``, 1283 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 1284 REPEAT GEN_TAC THEN DISCH_TAC THEN 1285 ONCE_REWRITE_TAC [METIS [] 1286 ``(?k:real. a - k * b IN span (s DELETE b)) = 1287 (\a. ?k. a - k * b IN span (s DELETE b)) a``] THEN 1288 MATCH_MP_TAC SPAN_INDUCT THEN 1289 SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN CONJ_TAC THENL 1290 [GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC ``x:real = b``, ALL_TAC] THEN 1291 ASM_SIMP_TAC std_ss [IN_DEF] THENL 1292 [EXISTS_TAC ``1:real`` THEN SIMP_TAC real_ss [] THEN 1293 ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN REWRITE_TAC [SPAN_CLAUSES], 1294 EXISTS_TAC ``0:real`` THEN SIMP_TAC real_ss [] THEN 1295 ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN MATCH_MP_TAC SPAN_SUPERSET THEN 1296 ASM_SET_TAC [], 1297 ALL_TAC] THEN REPEAT CONJ_TAC THENL 1298 [EXISTS_TAC ``0:real`` THEN SIMP_TAC real_ss [] THEN 1299 ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN REWRITE_TAC [SPAN_CLAUSES], 1300 REPEAT STRIP_TAC THEN EXISTS_TAC ``k + k':real`` THEN 1301 ONCE_REWRITE_TAC [REAL_ARITH 1302 ``(x + y - (k + k') * b) = ((x - k * b) + (y - k' * b:real))``] THEN 1303 ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN 1304 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM SPECIFICATION]) THEN 1305 METIS_TAC [SPAN_ADD], 1306 REPEAT STRIP_TAC THEN EXISTS_TAC ``c * k:real`` THEN 1307 ONCE_REWRITE_TAC [ 1308 REAL_ARITH ``(c * x - (c * k) * y = c * (x - k * y:real))``] THEN 1309 ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN 1310 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM SPECIFICATION]) THEN 1311 METIS_TAC [SPAN_CLAUSES]]); 1312 1313val IN_SPAN_INSERT = store_thm ("IN_SPAN_INSERT", 1314 ``!a b:real s. a IN span(b INSERT s) /\ ~(a IN span s) 1315 ==> b IN span(a INSERT s)``, 1316 REPEAT STRIP_TAC THEN 1317 MP_TAC(ISPECL [``b:real``, ``(b:real) INSERT s``, ``a:real``] 1318 SPAN_BREAKDOWN) THEN ASM_REWRITE_TAC[IN_INSERT] THEN 1319 DISCH_THEN(X_CHOOSE_THEN ``k:real`` MP_TAC) THEN 1320 ASM_CASES_TAC ``k = &0:real`` THEN 1321 ASM_REWRITE_TAC[REAL_ARITH ``a - &0 * b = a:real``, DELETE_INSERT] THENL 1322 [ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, DELETE_SUBSET], ALL_TAC] THEN 1323 DISCH_THEN(MP_TAC o SPEC ``inv(k:real)`` o MATCH_MP SPAN_MUL) THEN 1324 ASM_SIMP_TAC real_ss [REAL_SUB_LDISTRIB, REAL_MUL_ASSOC, REAL_MUL_LINV] THEN 1325 DISCH_TAC THEN SUBST1_TAC(REAL_ARITH 1326 ``b:real = inv(k) * a - (inv(k) * a - b)``) THEN 1327 MATCH_MP_TAC SPAN_SUB THEN 1328 FULL_SIMP_TAC std_ss [SPAN_CLAUSES, IN_INSERT, SUBSET_DEF, IN_DELETE, 1329 SPAN_MONO] THEN 1330 POP_ASSUM MP_TAC THEN ABBREV_TAC ``y = inv k * a - b:real`` THEN 1331 SPEC_TAC (``y:real``, ``y:real``) THEN REWRITE_TAC [GSYM SUBSET_DEF] THEN 1332 MATCH_MP_TAC SPAN_MONO THEN ASM_SET_TAC []); 1333 1334val INDEPENDENT_INSERT = store_thm ("INDEPENDENT_INSERT", 1335 ``!a:real s. independent(a INSERT s) <=> 1336 if a IN s then independent s else independent s /\ ~(a IN span s)``, 1337 REPEAT GEN_TAC THEN ASM_CASES_TAC ``(a:real) IN s`` THEN 1338 ASM_SIMP_TAC std_ss [SET_RULE ``x IN s ==> (x INSERT s = s)``] THEN 1339 EQ_TAC THENL 1340 [DISCH_TAC THEN CONJ_TAC THENL 1341 [ASM_MESON_TAC[INDEPENDENT_MONO, SUBSET_DEF, IN_INSERT], 1342 POP_ASSUM MP_TAC THEN REWRITE_TAC[independent, dependent] THEN 1343 ASM_MESON_TAC[IN_INSERT, SET_RULE 1344 ``~(a IN s) ==> ((a INSERT s) DELETE a = s)``]], 1345 ALL_TAC] THEN 1346 SIMP_TAC std_ss [independent, dependent, NOT_EXISTS_THM] THEN 1347 STRIP_TAC THEN X_GEN_TAC ``b:real`` THEN 1348 REWRITE_TAC[IN_INSERT] THEN ASM_CASES_TAC ``b:real = a`` THEN 1349 ASM_SIMP_TAC std_ss [ 1350 SET_RULE ``~(a IN s) ==> ((a INSERT s) DELETE a = s)``] THEN 1351 ASM_SIMP_TAC std_ss [SET_RULE ``~(a IN s) /\ ~(b = a) 1352 ==> ((a INSERT s) DELETE b = a INSERT (s DELETE b))``] THEN 1353 ASM_MESON_TAC[IN_SPAN_INSERT, SET_RULE 1354 ``b IN s ==> (b INSERT (s DELETE b) = s)``]); 1355 1356val INDEPENDENT_EMPTY = store_thm ("INDEPENDENT_EMPTY", 1357 ``independent {}``, 1358 REWRITE_TAC[independent, dependent, NOT_IN_EMPTY]); 1359 1360val INDEPENDENT_SING = store_thm ("INDEPENDENT_SING", 1361 ``!x. independent {x} <=> ~(x = 0)``, 1362 REWRITE_TAC[INDEPENDENT_INSERT, NOT_IN_EMPTY, SPAN_EMPTY] THEN 1363 REWRITE_TAC[INDEPENDENT_EMPTY] THEN SET_TAC[]); 1364 1365val INDEPENDENT_STDBASIS = store_thm ("INDEPENDENT_STDBASIS", 1366 ``independent {i:real | 1 <= i /\ i <= 1}``, 1367 REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2] THEN 1368 REWRITE_TAC [INDEPENDENT_SING] THEN REAL_ARITH_TAC); 1369 1370val SPANNING_SUBSET_INDEPENDENT = store_thm ("SPANNING_SUBSET_INDEPENDENT", 1371 ``!s t:real->bool. 1372 t SUBSET s /\ independent s /\ s SUBSET span(t) ==> (s = t)``, 1373 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 1374 ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET_DEF] THEN 1375 X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN 1376 UNDISCH_TAC ``independent s`` THEN DISCH_TAC THEN 1377 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [independent]) THEN 1378 SIMP_TAC std_ss [dependent, NOT_EXISTS_THM] THEN 1379 DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN ASM_REWRITE_TAC[] THEN 1380 ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_DELETE]); 1381 1382val IN_SPAN_DELETE = store_thm ("IN_SPAN_DELETE", 1383 ``!a b s. 1384 a IN span s /\ ~(a IN span (s DELETE b)) 1385 ==> b IN span (a INSERT (s DELETE b))``, 1386 ASM_MESON_TAC[IN_SPAN_INSERT, SPAN_MONO, SUBSET_DEF, IN_INSERT, IN_DELETE]); 1387 1388val SPAN_TRANS = store_thm ("SPAN_TRANS", 1389 ``!x y:real s. x IN span(s) /\ y IN span(x INSERT s) ==> y IN span(s)``, 1390 REPEAT STRIP_TAC THEN 1391 MP_TAC(SPECL [``x:real``, ``(x:real) INSERT s``, ``y:real``] 1392 SPAN_BREAKDOWN) THEN 1393 ASM_SIMP_TAC std_ss [IN_INSERT] THEN 1394 DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN 1395 SUBST1_TAC(REAL_ARITH ``y:real = (y - k * x) + k * x``) THEN 1396 MATCH_MP_TAC SPAN_ADD THEN ASM_SIMP_TAC std_ss [SPAN_MUL] THEN 1397 ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_INSERT, IN_DELETE]); 1398 1399val EXCHANGE_LEMMA = store_thm ("EXCHANGE_LEMMA", 1400 ``!s t:real->bool. 1401 FINITE t /\ independent s /\ s SUBSET span t 1402 ==> ?t'. t' HAS_SIZE (CARD t) /\ 1403 s SUBSET t' /\ t' SUBSET (s UNION t) /\ s SUBSET (span t')``, 1404 REPEAT GEN_TAC THEN 1405 completeInduct_on `CARD(t DIFF s :real->bool)` THEN 1406 GEN_TAC THEN GEN_TAC THEN DISCH_TAC THEN FULL_SIMP_TAC std_ss [] THEN 1407 POP_ASSUM K_TAC THEN 1408 KNOW_TAC ``(!m. m < CARD (t:real->bool DIFF s) ==> 1409 !t:real->bool s:real->bool. (m = CARD (t DIFF s)) ==> 1410 FINITE t /\ independent s /\ s SUBSET span t ==> 1411 ?t'. t' HAS_SIZE CARD t /\ s SUBSET t' /\ t' SUBSET s UNION t /\ 1412 s SUBSET span t') ==> 1413 (!t'':real->bool s':real->bool'. (CARD (t'' DIFF s') < CARD (t DIFF s)) ==> 1414 FINITE t'' /\ independent s' /\ s' SUBSET span t'' ==> 1415 ?t'. t' HAS_SIZE CARD t'' /\ s' SUBSET t' /\ t' SUBSET s' UNION t'' /\ 1416 s' SUBSET span t')`` THENL 1417 [METIS_TAC [], ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN DISCH_TAC] THEN 1418 ASM_CASES_TAC ``(s:real->bool) SUBSET t`` THENL 1419 [ASM_MESON_TAC[HAS_SIZE, SUBSET_UNION], ALL_TAC] THEN 1420 ASM_CASES_TAC ``t SUBSET (s:real->bool)`` THENL 1421 [ASM_MESON_TAC[SPANNING_SUBSET_INDEPENDENT, HAS_SIZE], ALL_TAC] THEN 1422 STRIP_TAC THEN UNDISCH_TAC ``~(t SUBSET s:real->bool)`` THEN DISCH_TAC THEN 1423 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 1424 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP] THEN 1425 DISCH_THEN(X_CHOOSE_THEN ``b:real`` STRIP_ASSUME_TAC) THEN 1426 ASM_CASES_TAC ``s SUBSET span(t DELETE (b:real))`` THENL 1427 [FIRST_X_ASSUM(MP_TAC o 1428 SPECL [``t DELETE (b:real)``, ``s:real->bool``]) THEN 1429 ASM_REWRITE_TAC[SET_RULE ``s DELETE a DIFF t = (s DIFF t) DELETE a``] THEN 1430 ASM_SIMP_TAC arith_ss [CARD_DELETE, FINITE_DIFF, IN_DIFF, FINITE_DELETE, 1431 CARD_EQ_0, ARITH_PROVE ``n - 1 < n <=> ~(n = 0:num)``] THEN 1432 KNOW_TAC ``t DIFF s <> {}:real->bool`` THENL 1433 [UNDISCH_TAC ``~((s:real->bool) SUBSET t)`` THEN ASM_SET_TAC[], 1434 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 1435 DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 1436 EXISTS_TAC ``(b:real) INSERT u`` THEN 1437 ASM_SIMP_TAC std_ss [SUBSET_INSERT, INSERT_SUBSET, IN_UNION] THEN 1438 CONJ_TAC THENL 1439 [UNDISCH_TAC ``(u:real->bool) HAS_SIZE CARD(t:real->bool) - 1`` THEN 1440 SIMP_TAC std_ss [HAS_SIZE, FINITE_EMPTY, FINITE_INSERT, CARD_EMPTY, 1441 CARD_INSERT] THEN 1442 STRIP_TAC THEN COND_CASES_TAC THENL 1443 [ASM_MESON_TAC[SUBSET_DEF, IN_UNION, IN_DELETE], ALL_TAC] THEN 1444 ASM_MESON_TAC[ARITH_PROVE ``~(n = 0) ==> (SUC(n - 1) = n)``, 1445 CARD_EQ_0, MEMBER_NOT_EMPTY], ALL_TAC] THEN 1446 CONJ_TAC THENL 1447 [UNDISCH_TAC ``u SUBSET s UNION (t DELETE (b:real))`` THEN SET_TAC[], 1448 ASM_MESON_TAC[SUBSET_DEF, SPAN_MONO, IN_INSERT]], 1449 ALL_TAC] THEN 1450 UNDISCH_TAC ``~(s SUBSET span (t DELETE (b:real)))`` THEN 1451 GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SUBSET_DEF] THEN 1452 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP] THEN 1453 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 1454 SUBGOAL_THEN ``~(a:real = b)`` ASSUME_TAC THENL 1455 [ASM_MESON_TAC[], ALL_TAC] THEN 1456 SUBGOAL_THEN ``~((a:real) IN t)`` ASSUME_TAC THENL 1457 [ASM_MESON_TAC[IN_DELETE, SPAN_CLAUSES], ALL_TAC] THEN 1458 FIRST_X_ASSUM(MP_TAC o SPECL 1459 [``(a:real) INSERT (t DELETE b)``, ``s:real->bool``]) THEN 1460 KNOW_TAC ``CARD ((a INSERT t DELETE b) DIFF s) < CARD (t DIFF s:real->bool)`` 1461 THENL 1462 [ASM_SIMP_TAC std_ss [SET_RULE 1463 ``a IN s ==> ((a INSERT (t DELETE b)) DIFF s = (t DIFF s) DELETE b)``] THEN 1464 KNOW_TAC ``(b:real) IN (t DIFF s)`` 1465 THENL [METIS_TAC [IN_DIFF], DISCH_TAC] THEN 1466 KNOW_TAC ``FINITE (t DIFF s:real->bool)`` 1467 THENL [METIS_TAC [FINITE_DIFF], ALL_TAC] THEN 1468 SIMP_TAC std_ss [CARD_DELETE] THEN ASM_REWRITE_TAC [] THEN DISCH_TAC THEN 1469 ASM_SIMP_TAC std_ss [ARITH_PROVE ``n - 1 < n <=> ~(n = 0:num)``, CARD_EQ_0, 1470 FINITE_DIFF] THEN 1471 UNDISCH_TAC ``~((s:real->bool) SUBSET t)`` THEN ASM_SET_TAC[], 1472 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 1473 KNOW_TAC ``FINITE ((a:real) INSERT t DELETE b) /\ 1474 s SUBSET span (a INSERT t DELETE b)`` THENL 1475 [ASM_SIMP_TAC std_ss [FINITE_EMPTY, FINITE_INSERT, FINITE_DELETE] THEN 1476 REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN 1477 DISCH_TAC THEN MATCH_MP_TAC SPAN_TRANS THEN EXISTS_TAC ``b:real`` THEN 1478 ASM_MESON_TAC[IN_SPAN_DELETE, SUBSET_DEF, SPAN_MONO, 1479 SET_RULE ``t SUBSET (b INSERT (a INSERT (t DELETE b)))``], 1480 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 1481 DISCH_THEN (X_CHOOSE_TAC ``u:real->bool``) THEN 1482 EXISTS_TAC ``u:real->bool`` THEN 1483 POP_ASSUM MP_TAC THEN 1484 ASM_SIMP_TAC std_ss [HAS_SIZE, CARD_EMPTY, CARD_INSERT, CARD_DELETE, 1485 FINITE_DELETE, 1486 IN_DELETE, ARITH_PROVE ``(SUC(n - 1) = n) <=> ~(n = 0)``, 1487 CARD_EQ_0] THEN 1488 UNDISCH_TAC ``(b:real) IN t`` THEN ASM_SET_TAC[]); 1489 1490val CARD_STDBASIS = store_thm ("CARD_STDBASIS", 1491 ``CARD {1:real} = 1``, 1492 MESON_TAC[CARD_SING]); 1493 1494val INDEPENDENT_SPAN_BOUND = store_thm ("INDEPENDENT_SPAN_BOUND", 1495 ``!s t. FINITE t /\ independent s /\ s SUBSET span(t) 1496 ==> FINITE s /\ CARD(s) <= CARD(t)``, 1497 REPEAT GEN_TAC THEN DISCH_TAC THEN 1498 FIRST_ASSUM(MP_TAC o MATCH_MP EXCHANGE_LEMMA) THEN 1499 ASM_MESON_TAC[HAS_SIZE, CARD_SUBSET, SUBSET_FINITE_I]); 1500 1501val INDEPENDENT_BOUND = store_thm ("INDEPENDENT_BOUND", 1502 ``!s:real->bool. 1503 independent s ==> FINITE s /\ CARD(s) <= 1:num``, 1504 REPEAT GEN_TAC THEN DISCH_TAC THEN 1505 ONCE_REWRITE_TAC[GSYM CARD_STDBASIS] THEN 1506 MATCH_MP_TAC INDEPENDENT_SPAN_BOUND THEN 1507 KNOW_TAC ``span {1} = univ(:real)`` THENL 1508 [SIMP_TAC std_ss [EXTENSION, span, hull, IN_BIGINTER, IN_UNIV] THEN 1509 SIMP_TAC std_ss [SING_SUBSET, GSPECIFICATION, subspace] THEN 1510 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_RID] THEN 1511 FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [], 1512 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 1513 ASM_REWRITE_TAC[FINITE_SING, SUBSET_UNIV]); 1514 1515val MAXIMAL_INDEPENDENT_SUBSET_EXTEND = store_thm ("MAXIMAL_INDEPENDENT_SUBSET_EXTEND", 1516 ``!s v:real->bool. s SUBSET v /\ independent s ==> ?b. s SUBSET b /\ b SUBSET v /\ 1517 independent b /\ v SUBSET (span b)``, 1518 REPEAT GEN_TAC THEN 1519 completeInduct_on `(1:num) - CARD(s:real->bool)` THEN 1520 GEN_TAC THEN DISCH_TAC THEN FULL_SIMP_TAC std_ss [] THEN POP_ASSUM K_TAC THEN 1521 REPEAT STRIP_TAC THEN 1522 ASM_CASES_TAC ``v SUBSET (span(s:real->bool))`` THENL 1523 [ASM_MESON_TAC[SUBSET_REFL], ALL_TAC] THEN 1524 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 1525 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP] THEN 1526 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 1527 KNOW_TAC ``(!(m :num). m < (1 :num) - CARD (s :real -> bool) ==> 1528 !(s :real -> bool). (m = (1 :num) - CARD s) ==> 1529 s SUBSET (v :real -> bool) /\ independent s ==> 1530 ?(b :real -> bool). 1531 s SUBSET b /\ b SUBSET v /\ independent b /\ v SUBSET span b) ==> 1532 !s'. (1 - CARD s' < 1 - CARD s) ==> s' SUBSET v /\ independent s' ==> 1533 ?b. s' SUBSET b /\ b SUBSET v /\ independent b /\ v SUBSET span b`` THENL 1534 [METIS_TAC [], ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN 1535 FIRST_X_ASSUM(MP_TAC o SPEC ``(a:real) INSERT s``) THEN 1536 REWRITE_TAC[AND_IMP_INTRO] THEN 1537 KNOW_TAC ``1 - CARD (a INSERT s) < 1 - CARD s /\ a INSERT s SUBSET v /\ 1538 independent (a INSERT s:real->bool)`` THENL 1539 [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 1540 MESON_TAC[INSERT_SUBSET]] THEN 1541 SUBGOAL_THEN ``independent ((a:real) INSERT s)`` ASSUME_TAC THENL 1542 [ASM_REWRITE_TAC[INDEPENDENT_INSERT, COND_ID], ALL_TAC] THEN 1543 ASM_REWRITE_TAC[INSERT_SUBSET] THEN 1544 MATCH_MP_TAC(ARITH_PROVE ``(b = a + 1) /\ b <= n ==> n - b < n - a:num``) THEN 1545 ASM_SIMP_TAC std_ss [CARD_EMPTY, CARD_INSERT, INDEPENDENT_BOUND] THEN 1546 METIS_TAC[SPAN_SUPERSET, ADD1]); 1547 1548val MAXIMAL_INDEPENDENT_SUBSET = store_thm ("MAXIMAL_INDEPENDENT_SUBSET", 1549 ``!v:real->bool. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b)``, 1550 MP_TAC(SPEC ``EMPTY:real->bool`` MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN 1551 REWRITE_TAC[EMPTY_SUBSET, INDEPENDENT_EMPTY]); 1552 1553val SPAN_BREAKDOWN_EQ = store_thm ("SPAN_BREAKDOWN_EQ", 1554 ``!a:real s. (x IN span(a INSERT s) <=> (?k. (x - k * a) IN span s))``, 1555 REPEAT STRIP_TAC THEN EQ_TAC THENL 1556 [DISCH_THEN(MP_TAC o CONJ(SET_RULE ``(a:real) IN (a INSERT s)``)) THEN 1557 DISCH_THEN(MP_TAC o MATCH_MP SPAN_BREAKDOWN) THEN 1558 DISCH_THEN (X_CHOOSE_TAC ``k:real``) THEN EXISTS_TAC ``k:real`` THEN 1559 POP_ASSUM MP_TAC THEN SPEC_TAC(``x - k * a:real``,``y:real``) THEN 1560 REWRITE_TAC[GSYM SUBSET_DEF] THEN MATCH_MP_TAC SPAN_MONO THEN SET_TAC[], 1561 DISCH_THEN(X_CHOOSE_TAC ``k:real``) THEN 1562 SUBST1_TAC(REAL_ARITH ``x = (x - k * a) + k * a:real``) THEN 1563 MATCH_MP_TAC SPAN_ADD THEN 1564 ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_INSERT, SPAN_CLAUSES]]); 1565 1566val LINEAR_INDEPENDENT_EXTEND_LEMMA = store_thm ("LINEAR_INDEPENDENT_EXTEND_LEMMA", 1567 ``!f b. FINITE b ==> independent b ==> 1568 ?g:real->real. (!x y. x IN span b /\ y IN span b ==> 1569 (g(x + y) = g(x) + g(y))) /\ (!x c. x IN span b ==> 1570 (g(c * x) = c * g(x))) /\ (!x. x IN b ==> (g x = f x))``, 1571 GEN_TAC THEN 1572 ONCE_REWRITE_TAC [METIS [] 1573 ``!b. (independent b ==> 1574 ?g. (!x y. x IN span b /\ y IN span b ==> (g (x + y) = g x + g y)) /\ 1575 (!x c. x IN span b ==> (g (c * x) = c * g x)) /\ 1576 !x. x IN b ==> (g x = f x)) = 1577 (\b. independent b ==> 1578 ?g. (!x y. x IN span b /\ y IN span b ==> (g (x + y) = g x + g y)) /\ 1579 (!x c. x IN span b ==> (g (c * x) = c * g x)) /\ 1580 !x. x IN b ==> (g x = f x)) b``] THEN 1581 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 1582 REWRITE_TAC[NOT_IN_EMPTY, INDEPENDENT_INSERT] THEN CONJ_TAC THENL 1583 [REPEAT STRIP_TAC THEN EXISTS_TAC ``(\x. 0):real->real`` THEN 1584 SIMP_TAC std_ss [SPAN_EMPTY] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC, 1585 ALL_TAC] THEN 1586 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 1587 MAP_EVERY X_GEN_TAC [``b:real->bool``, ``a:real``] THEN 1588 REWRITE_TAC [AND_IMP_INTRO] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN 1589 REWRITE_TAC [CONJ_EQ_IMP] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 1590 DISCH_TAC THEN DISCH_TAC THEN REWRITE_TAC [AND_IMP_INTRO] THEN 1591 DISCH_THEN (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 1592 DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN 1593 ABBREV_TAC ``h = \z:real. @k. (z - k * a) IN span b`` THEN 1594 SUBGOAL_THEN ``!z:real. z IN span(a INSERT b) 1595 ==> (z - h(z) * a) IN span(b) /\ 1596 !k. (z - k * a) IN span(b) ==> (k = h(z))`` 1597 MP_TAC THENL 1598 [GEN_TAC THEN DISCH_TAC THEN 1599 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL 1600 [EXPAND_TAC "h" THEN CONV_TAC SELECT_CONV THEN 1601 ASM_MESON_TAC[SPAN_BREAKDOWN_EQ], 1602 ALL_TAC] THEN 1603 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM, AND_IMP_INTRO] THEN GEN_TAC THEN 1604 DISCH_THEN(MP_TAC o MATCH_MP SPAN_SUB) THEN 1605 REWRITE_TAC[REAL_ARITH ``(z - a * v) - (z - b * v) = (b - a) * v:real``] THEN 1606 ASM_CASES_TAC ``k = (h:real->real) z`` THEN ASM_REWRITE_TAC[] THEN 1607 DISCH_THEN(MP_TAC o SPEC ``inv(k - (h:real->real) z)`` o 1608 MATCH_MP SPAN_MUL) THEN 1609 ASM_SIMP_TAC real_ss [REAL_MUL_LINV, REAL_MUL_ASSOC, REAL_SUB_0], 1610 ALL_TAC] THEN 1611 SIMP_TAC std_ss [TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN 1612 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM, AND_IMP_INTRO] THEN 1613 DISCH_THEN (MP_TAC o SIMP_RULE std_ss [FORALL_AND_THM]) THEN STRIP_TAC THEN 1614 EXISTS_TAC ``\z:real. h(z) * (f:real->real)(a) + g(z - h(z) * a)`` THEN 1615 ONCE_REWRITE_TAC [CONJ_SYM] THEN REPEAT CONJ_TAC THENL 1616 [MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 1617 SUBGOAL_THEN ``(h:real->real)(x + y) = h(x) + h(y)`` ASSUME_TAC THENL 1618 [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 1619 REWRITE_TAC[REAL_ARITH 1620 ``(x + y) - (k + l) * a = (x - k * a) + (y - l * a:real)``] THEN 1621 CONJ_TAC THEN MATCH_MP_TAC SPAN_ADD THEN ASM_REWRITE_TAC[] THEN 1622 ASM_SIMP_TAC std_ss [], 1623 ALL_TAC] THEN 1624 ASM_SIMP_TAC std_ss [REAL_ARITH 1625 ``(x + y) - (k + l) * a = (x - k * a) + (y - l * a:real)``] THEN 1626 ASM_SIMP_TAC std_ss [] THEN REAL_ARITH_TAC, 1627 MAP_EVERY X_GEN_TAC [``x:real``, ``c:real``] THEN STRIP_TAC THEN 1628 SUBGOAL_THEN ``(h:real->real)(c * x) = c * h(x)`` ASSUME_TAC THENL 1629 [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 1630 REWRITE_TAC[REAL_ARITH 1631 ``c * x - (c * k) * a = c * (x - k * a:real)``] THEN 1632 CONJ_TAC THEN MATCH_MP_TAC SPAN_MUL THEN ASM_REWRITE_TAC[] THEN 1633 ASM_SIMP_TAC std_ss [], 1634 ALL_TAC] THEN 1635 ASM_SIMP_TAC std_ss [REAL_ARITH 1636 ``c * x - (c * k) * a = c * (x - k * a:real)``] THEN 1637 ASM_SIMP_TAC std_ss [] THEN REAL_ARITH_TAC, 1638 ALL_TAC] THEN 1639 X_GEN_TAC ``x:real`` THEN SIMP_TAC std_ss [IN_INSERT] THEN 1640 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THENL 1641 [SUBGOAL_THEN ``&1:real = h(a:real)`` (SUBST1_TAC o SYM) THENL 1642 [FIRST_X_ASSUM MATCH_MP_TAC, ALL_TAC] THEN 1643 REWRITE_TAC[REAL_ARITH ``a - &1 * a = 0:real``, SPAN_0] THENL 1644 [ASM_MESON_TAC[SPAN_SUPERSET, SUBSET_DEF, IN_INSERT], ALL_TAC] THEN 1645 UNDISCH_TAC ``!x y:real. x IN span b /\ y IN span b ==> 1646 ((g:real->real) (x + y) = g x + g y)`` THEN 1647 DISCH_TAC THEN SIMP_TAC std_ss [] THEN 1648 FIRST_X_ASSUM(MP_TAC o SPECL [``0:real``, ``0:real``]) THEN 1649 SIMP_TAC real_ss [SPAN_0, REAL_ADD_LID] THEN 1650 REWRITE_TAC[REAL_ARITH ``(a = a + a) <=> (a = 0:real)``] THEN 1651 DISCH_THEN SUBST1_TAC THEN REAL_ARITH_TAC, 1652 ALL_TAC] THEN 1653 SUBGOAL_THEN ``&0:real = h(x:real)`` (SUBST1_TAC o SYM) THENL 1654 [FIRST_X_ASSUM MATCH_MP_TAC, ALL_TAC] THEN 1655 SIMP_TAC std_ss [REAL_ADD_LID, REAL_MUL_LZERO, REAL_SUB_RZERO] THEN 1656 ASM_MESON_TAC[SUBSET_DEF, IN_INSERT, SPAN_SUPERSET]); 1657 1658val LINEAR_INDEPENDENT_EXTEND = store_thm ("LINEAR_INDEPENDENT_EXTEND", 1659 ``!f b. independent b ==> ?g:real->real. linear g /\ (!x. x IN b ==> (g x = f x))``, 1660 REPEAT STRIP_TAC THEN 1661 MP_TAC(ISPECL [``b:real->bool``, ``univ(:real)``] 1662 MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN 1663 ASM_SIMP_TAC std_ss [SUBSET_UNIV, UNIV_SUBSET] THEN 1664 REWRITE_TAC[EXTENSION, IN_UNIV] THEN 1665 DISCH_THEN(X_CHOOSE_THEN ``c:real->bool`` STRIP_ASSUME_TAC) THEN 1666 MP_TAC(ISPECL [``f:real->real``, ``c:real->bool``] 1667 LINEAR_INDEPENDENT_EXTEND_LEMMA) THEN 1668 ASM_SIMP_TAC std_ss [INDEPENDENT_BOUND, linear] THEN 1669 ASM_MESON_TAC[SUBSET_DEF]); 1670 1671val SUBSPACE_KERNEL = store_thm ("SUBSPACE_KERNEL", 1672 ``!f. linear f ==> subspace {x | f(x) = 0}``, 1673 SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN 1674 SIMP_TAC std_ss [LINEAR_ADD, LINEAR_CMUL, REAL_ADD_LID, REAL_MUL_RZERO] THEN 1675 MESON_TAC[LINEAR_0]); 1676 1677val LINEAR_EQ_0_SPAN = store_thm ("LINEAR_EQ_0_SPAN", 1678 ``!f:real->real b. linear f /\ (!x. x IN b ==> (f(x) = 0)) 1679 ==> !x. x IN span(b) ==> (f(x) = 0)``, 1680 REPEAT GEN_TAC THEN STRIP_TAC THEN RULE_ASSUM_TAC(SIMP_RULE std_ss [IN_DEF]) THEN 1681 ONCE_REWRITE_TAC [METIS [] ``(f x = 0) = (\x. (f:real->real) x = 0) x``] THEN 1682 MATCH_MP_TAC SPAN_INDUCT THEN ASM_SIMP_TAC std_ss [IN_DEF] THEN 1683 MP_TAC(ISPEC ``f:real->real`` SUBSPACE_KERNEL) THEN ASM_REWRITE_TAC[] THEN 1684 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 1685 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_DEF]); 1686 1687val LINEAR_EQ_0 = store_thm ("LINEAR_EQ_0", 1688 ``!f b s. linear f /\ s SUBSET (span b) /\ 1689 (!x. x IN b ==> (f(x) = 0)) ==> !x. x IN s ==> (f(x) = 0)``, 1690 MESON_TAC[LINEAR_EQ_0_SPAN, SUBSET_DEF]); 1691 1692val LINEAR_EQ = store_thm ("LINEAR_EQ", 1693 ``!f g b s. linear f /\ linear g /\ s SUBSET (span b) /\ 1694 (!x. x IN b ==> (f(x) = g(x))) ==> !x. x IN s ==> (f(x) = g(x))``, 1695 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN STRIP_TAC THEN 1696 ONCE_REWRITE_TAC [METIS [] ``(f x - g x = 0) = ((\x. (f:real->real) x - g x) x = 0)``] THEN 1697 MATCH_MP_TAC LINEAR_EQ_0 THEN SIMP_TAC std_ss [] THEN METIS_TAC[LINEAR_COMPOSE_SUB]); 1698 1699val LINEAR_EQ_STDBASIS = store_thm ("LINEAR_EQ_STDBASIS", 1700 ``!f:real->real g. linear f /\ linear g /\ 1701 (!i. 1 <= i /\ i <= 1 ==> (f i = g i)) ==> (f = g)``, 1702 REPEAT STRIP_TAC THEN 1703 SUBGOAL_THEN ``!x. x IN UNIV ==> ((f:real->real) x = g x)`` 1704 (fn th => MP_TAC th THEN SIMP_TAC std_ss [FUN_EQ_THM, IN_UNIV]) THEN 1705 MATCH_MP_TAC LINEAR_EQ THEN 1706 EXISTS_TAC ``{i :real | 1 <= i /\ i <= 1}`` THEN 1707 ASM_SIMP_TAC std_ss [SUBSET_REFL, GSPECIFICATION] THEN 1708 REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2] THEN 1709 KNOW_TAC ``span {1} = univ(:real)`` THENL 1710 [ALL_TAC, SIMP_TAC std_ss [SUBSET_REFL]] THEN 1711 SIMP_TAC std_ss [EXTENSION, span, hull, IN_BIGINTER, IN_UNIV] THEN 1712 SIMP_TAC std_ss [SING_SUBSET, GSPECIFICATION, subspace] THEN 1713 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_RID] THEN 1714 FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC []); 1715 1716val LINEAR_INJECTIVE_LEFT_INVERSE = store_thm ("LINEAR_INJECTIVE_LEFT_INVERSE", 1717 ``!f:real->real. linear f /\ (!x y. (f x = f y) ==> (x = y)) 1718 ==> ?g. linear g /\ (g o f = (\x. x))``, 1719 REWRITE_TAC[INJECTIVE_LEFT_INVERSE] THEN REPEAT STRIP_TAC THEN 1720 SUBGOAL_THEN ``?h. linear(h:real->real) /\ 1721 !x. x IN IMAGE (f:real->real) {i | 1 <= i /\ i <= 1} 1722 ==> (h x = g x)`` MP_TAC THENL 1723 [MATCH_MP_TAC LINEAR_INDEPENDENT_EXTEND THEN 1724 SIMP_TAC std_ss [REAL_LE_ANTISYM, GSPEC_EQ2, IMAGE_SING] THEN 1725 SIMP_TAC std_ss [INDEPENDENT_SING] THEN 1726 KNOW_TAC ``?g. !x. g ((f:real->real) x) = x`` THENL 1727 [METIS_TAC [], REWRITE_TAC [GSYM INJECTIVE_LEFT_INVERSE] THEN DISCH_TAC] THEN 1728 FULL_SIMP_TAC std_ss [linear] THEN KNOW_TAC ``0 = (f:real->real) 0`` THENL 1729 [UNDISCH_TAC ``!c x. (f:real->real) (c * x) = c * f x`` THEN 1730 DISCH_THEN (MP_TAC o SPECL [``0:real``, ``0:real``]) THEN REAL_ARITH_TAC, 1731 DISCH_TAC THEN ONCE_ASM_REWRITE_TAC []] THEN DISCH_TAC THEN 1732 UNDISCH_TAC ``!x y. ((f:real->real) x = f y) ==> (x = y)`` THEN 1733 DISCH_THEN (MP_TAC o SPECL [``1:real``,``0:real``]) THEN 1734 POP_ASSUM MP_TAC THEN REAL_ARITH_TAC, 1735 DISCH_THEN (X_CHOOSE_TAC ``h:real->real``) THEN EXISTS_TAC ``h:real->real`` THEN 1736 POP_ASSUM MP_TAC THEN 1737 ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE, GSPECIFICATION] THEN STRIP_TAC THEN 1738 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LINEAR_EQ_STDBASIS THEN 1739 ASM_SIMP_TAC std_ss [LINEAR_ID, LINEAR_COMPOSE, LINEAR_ID, o_THM] THEN 1740 ASM_MESON_TAC[]]); 1741 1742val dim = new_definition ("dim", 1743 ``dim v = @n. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\ 1744 b HAS_SIZE n``); 1745 1746val BASIS_EXISTS = store_thm ("BASIS_EXISTS", 1747 ``!v. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\ b HAS_SIZE (dim v)``, 1748 GEN_TAC THEN REWRITE_TAC[dim] THEN CONV_TAC SELECT_CONV THEN 1749 MESON_TAC[MAXIMAL_INDEPENDENT_SUBSET, HAS_SIZE, INDEPENDENT_BOUND]); 1750 1751val INDEPENDENT_CARD_LE_DIM = store_thm ("INDEPENDENT_CARD_LE_DIM", 1752 ``!v b:real->bool. b SUBSET v /\ independent b ==> FINITE b /\ CARD(b) <= dim v``, 1753 METIS_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, HAS_SIZE, SUBSET_TRANS]); 1754 1755val CARD_GE_DIM_INDEPENDENT = store_thm ("CARD_GE_DIM_INDEPENDENT", 1756 ``!v b:real->bool. b SUBSET v /\ independent b /\ dim v <= CARD(b) 1757 ==> v SUBSET (span b)``, 1758 REPEAT STRIP_TAC THEN 1759 SUBGOAL_THEN ``!a:real. ~(a IN v /\ ~(a IN span b))`` MP_TAC THENL 1760 [ALL_TAC, SET_TAC[]] THEN 1761 X_GEN_TAC ``a:real`` THEN STRIP_TAC THEN 1762 SUBGOAL_THEN ``independent((a:real) INSERT b)`` ASSUME_TAC THENL 1763 [METIS_TAC[INDEPENDENT_INSERT], ALL_TAC] THEN 1764 MP_TAC(ISPECL [``v:real->bool``, ``(a:real) INSERT b``] 1765 INDEPENDENT_CARD_LE_DIM) THEN 1766 ASM_SIMP_TAC std_ss [INSERT_SUBSET, CARD_EMPTY, CARD_INSERT, INDEPENDENT_BOUND] THEN 1767 METIS_TAC[SPAN_SUPERSET, SUBSET_DEF, ARITH_PROVE 1768 ``x <= y ==> ~(SUC y <= x)``]); 1769 1770val SPAN_EXPLICIT = store_thm ("SPAN_EXPLICIT", 1771 ``!(p:real -> bool). span p = 1772 {y | ?s u. FINITE s /\ s SUBSET p /\ (sum s (\v. u v * v) = y)}``, 1773 GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 1774 [ALL_TAC, 1775 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN 1776 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN 1777 MATCH_MP_TAC SPAN_SUM THEN ASM_REWRITE_TAC[] THEN 1778 ASM_MESON_TAC[SPAN_SUPERSET, SPAN_MUL]] THEN 1779 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN 1780 ONCE_REWRITE_TAC [METIS [] 1781 ``(?s u. FINITE s /\ (!x. x IN s ==> x IN p) /\ (sum s (\v. u v * v) = x)) = 1782 (\x. ?s u. FINITE s /\ (!x. x IN s ==> x IN p) /\ (sum s (\v. u v * v) = x)) x``] THEN 1783 MATCH_MP_TAC SPAN_INDUCT_ALT THEN SIMP_TAC std_ss [] THEN CONJ_TAC THENL 1784 [EXISTS_TAC ``{}:real->bool`` THEN 1785 SIMP_TAC std_ss [FINITE_EMPTY, FINITE_INSERT, SUM_CLAUSES, 1786 EMPTY_SUBSET, NOT_IN_EMPTY], ALL_TAC] THEN 1787 MAP_EVERY X_GEN_TAC [``c:real``, ``x:real``, ``y:real``] THEN 1788 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 1789 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 1790 MAP_EVERY X_GEN_TAC [``s:real->bool``, ``u:real->real``] THEN 1791 STRIP_TAC THEN EXISTS_TAC ``(x:real) INSERT s`` THEN 1792 EXISTS_TAC ``\y. if y = x then (if x IN s then (u:real->real) y + c else c) 1793 else u y`` THEN 1794 ASM_SIMP_TAC std_ss [FINITE_INSERT, IN_INSERT, SUM_CLAUSES] THEN 1795 CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC] THEN 1796 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN 1797 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL 1798 [FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE 1799 ``x IN s ==> (s = x INSERT (s DELETE x))``)) THEN 1800 ASM_SIMP_TAC std_ss [SUM_CLAUSES, FINITE_INSERT, FINITE_DELETE, IN_DELETE] THEN 1801 MATCH_MP_TAC(REAL_ARITH 1802 ``(y = z) ==> ((c + d) * x + y = d * x + (c * x + z:real))``), 1803 AP_TERM_TAC] THEN 1804 MATCH_MP_TAC SUM_EQ THEN METIS_TAC[IN_DELETE]); 1805 1806val DEPENDENT_EXPLICIT = store_thm ("DEPENDENT_EXPLICIT", 1807 ``!p. dependent (p:real -> bool) <=> 1808 ?s u. FINITE s /\ s SUBSET p /\ (?v. v IN s /\ ~(u v = &0)) /\ 1809 (sum s (\v. u v * v) = 0)``, 1810 GEN_TAC THEN SIMP_TAC std_ss [dependent, SPAN_EXPLICIT, GSPECIFICATION] THEN 1811 SIMP_TAC std_ss [GSYM RIGHT_EXISTS_AND_THM, GSYM LEFT_EXISTS_AND_THM] THEN 1812 EQ_TAC THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THENL 1813 [MAP_EVERY X_GEN_TAC [``s:real->bool``, ``u:real->real``] THEN 1814 STRIP_TAC THEN ABBREV_TAC ``a = sum s (\v. (u:real->real) v * v)`` THEN 1815 MAP_EVERY EXISTS_TAC 1816 [``(a:real) INSERT s``, 1817 ``\y. if y = a then - &1 else (u:real->real) y``, 1818 ``a:real``] THEN 1819 ASM_REWRITE_TAC[IN_INSERT, INSERT_SUBSET, FINITE_INSERT] THEN 1820 CONJ_TAC THENL [ASM_SET_TAC[], ASM_SIMP_TAC real_ss []] THEN 1821 ASM_SIMP_TAC std_ss [SUM_CLAUSES] THEN 1822 COND_CASES_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 1823 REWRITE_TAC[REAL_ARITH ``(-&1 * a + s = 0) <=> (a = s:real)``] THEN 1824 FIRST_X_ASSUM(fn th => GEN_REWR_TAC LAND_CONV [SYM th]) THEN 1825 MATCH_MP_TAC SUM_EQ THEN ASM_SET_TAC[], 1826 MAP_EVERY X_GEN_TAC [``s:real->bool``, ``u:real->real``, ``a:real``] THEN 1827 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 1828 [``s DELETE (a:real)``, 1829 ``\i. -((u:real->real) i) / (u (a:real))``] THEN 1830 ASM_SIMP_TAC std_ss [SUM_DELETE, FINITE_DELETE] THEN 1831 KNOW_TAC ``sum s (\v. -u v / (u:real->real) a * v) - -u a / u a * a = a`` THENL 1832 [REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN 1833 REWRITE_TAC [REAL_MUL_ASSOC] THEN SIMP_TAC real_ss [SUM_RMUL, SUM_NEG] THEN 1834 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_MUL_SYM]) THEN ASM_REWRITE_TAC [] THEN 1835 ASM_SIMP_TAC real_ss [REAL_MUL_LNEG, GSYM REAL_MUL_ASSOC, 1836 REAL_MUL_RNEG, REAL_MUL_RZERO] THEN 1837 ASM_SIMP_TAC real_ss [REAL_MUL_RINV], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 1838 ASM_SET_TAC []]); 1839 1840val INDEPENDENT_INJECTIVE_IMAGE_GEN = store_thm ("INDEPENDENT_INJECTIVE_IMAGE_GEN", 1841 ``!f:real->real s. independent s /\ linear f /\ 1842 (!x y. x IN span s /\ y IN span s /\ (f(x) = f(y)) ==> (x = y)) 1843 ==> independent (IMAGE f s)``, 1844 REPEAT GEN_TAC THEN 1845 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN 1846 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 1847 SIMP_TAC std_ss [independent, DEPENDENT_EXPLICIT] THEN 1848 REWRITE_TAC[CONJ_ASSOC, FINITE_SUBSET_IMAGE] THEN DISCH_TAC THEN 1849 KNOW_TAC ``(?s':real->bool u:real->real. (FINITE s' /\ s' SUBSET s) /\ 1850 (?v. v IN IMAGE f s' /\ ~(u v = &0)) /\ 1851 (sum (IMAGE f s') (\v. u v * v) = 0))`` THENL 1852 [METIS_TAC [], POP_ASSUM K_TAC] THEN 1853 SIMP_TAC std_ss [EXISTS_IN_IMAGE, LEFT_IMP_EXISTS_THM] THEN 1854 MAP_EVERY X_GEN_TAC [``t:real->bool``, ``u:real->real``] THEN 1855 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 1856 MAP_EVERY EXISTS_TAC 1857 [``t:real->bool``, ``(u:real->real) o (f:real->real)``] THEN 1858 ASM_REWRITE_TAC[o_THM] THEN 1859 FIRST_ASSUM MATCH_MP_TAC THEN REPEAT CONJ_TAC THENL 1860 [MATCH_MP_TAC SPAN_SUM THEN ASM_SIMP_TAC std_ss [] THEN 1861 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN 1862 MATCH_MP_TAC SPAN_SUPERSET THEN ASM_SET_TAC[], 1863 REWRITE_TAC[SPAN_0], 1864 ASM_SIMP_TAC std_ss [LINEAR_SUM] THEN 1865 FIRST_ASSUM(SUBST1_TAC o MATCH_MP LINEAR_0) THEN 1866 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN CONV_TAC SYM_CONV THEN 1867 W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o lhand o snd) THEN 1868 ASM_SIMP_TAC std_ss [o_DEF] THEN ASM_SIMP_TAC std_ss [LINEAR_CMUL] THEN 1869 DISCH_THEN MATCH_MP_TAC THEN ASM_MESON_TAC[SPAN_SUPERSET, SUBSET_DEF]]); 1870 1871val INDEPENDENT_INJECTIVE_IMAGE = store_thm ("INDEPENDENT_INJECTIVE_IMAGE", 1872 ``!f:real->real s. independent s /\ linear f /\ 1873 (!x y. (f(x) = f(y)) ==> (x = y)) ==> independent (IMAGE f s)``, 1874 REPEAT STRIP_TAC THEN MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN 1875 ASM_MESON_TAC[]); 1876 1877Theorem SPAN_LINEAR_IMAGE : 1878 !f:real->real s. linear f ==> (span(IMAGE f s) = IMAGE f (span s)) 1879Proof 1880 REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 1881 X_GEN_TAC ``x:real`` THEN EQ_TAC THENL 1882 [ONCE_REWRITE_TAC [METIS [] ``x IN IMAGE f (span s) <=> 1883 (\x. x IN IMAGE f (span s)) x``] THEN 1884 SPEC_TAC(``x:real``, ``x:real``) THEN MATCH_MP_TAC SPAN_INDUCT THEN 1885 SIMP_TAC std_ss [SET_RULE ``(\x. x IN s) = s``] THEN 1886 ASM_SIMP_TAC std_ss [SUBSPACE_SPAN, SUBSPACE_LINEAR_IMAGE] THEN 1887 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN 1888 MESON_TAC[SPAN_SUPERSET, SUBSET_DEF], 1889 SPEC_TAC(``x:real``, ``x:real``) THEN SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 1890 ONCE_REWRITE_TAC [METIS [] ``f x IN span (IMAGE f s) <=> 1891 (\x. f x IN span (IMAGE f s)) x``] THEN 1892 MATCH_MP_TAC SPAN_INDUCT THEN 1893 SIMP_TAC std_ss [SET_RULE ``(\x. f x IN span(s)) = {x | f(x) IN span s}``] THEN 1894 ASM_SIMP_TAC std_ss [SUBSPACE_LINEAR_PREIMAGE, SUBSPACE_SPAN] THEN 1895 SIMP_TAC std_ss [GSPECIFICATION] THEN 1896 MESON_TAC[SPAN_SUPERSET, SUBSET_DEF, IN_IMAGE]] 1897QED 1898 1899(* ------------------------------------------------------------------------- *) 1900(* An injective map real->real is also surjective. *) 1901(* ------------------------------------------------------------------------- *) 1902 1903val LINEAR_INJECTIVE_IMP_SURJECTIVE = store_thm ("LINEAR_INJECTIVE_IMP_SURJECTIVE", 1904 ``!f:real->real. linear f /\ (!x y. (f(x) = f(y)) ==> (x = y)) 1905 ==> !y. ?x. f(x) = y``, 1906 REPEAT STRIP_TAC THEN 1907 MP_TAC(ISPEC ``univ(:real)`` BASIS_EXISTS) THEN 1908 REWRITE_TAC[SUBSET_UNIV, HAS_SIZE] THEN 1909 DISCH_THEN(X_CHOOSE_THEN ``b:real->bool`` STRIP_ASSUME_TAC) THEN 1910 SUBGOAL_THEN ``UNIV SUBSET span(IMAGE (f:real->real) b)`` MP_TAC THENL 1911 [MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN 1912 ASM_MESON_TAC[INDEPENDENT_INJECTIVE_IMAGE, LESS_EQ_REFL, 1913 SUBSET_UNIV, CARD_IMAGE_INJ], 1914 ASM_SIMP_TAC std_ss [SPAN_LINEAR_IMAGE] THEN 1915 ASM_MESON_TAC[SUBSET_DEF, IN_IMAGE, IN_UNIV]]); 1916 1917(* ------------------------------------------------------------------------- *) 1918(* Left-invertible linear transformation has a lower bound. *) 1919(* ------------------------------------------------------------------------- *) 1920 1921val LINEAR_INVERTIBLE_BOUNDED_BELOW_POS = store_thm ("LINEAR_INVERTIBLE_BOUNDED_BELOW_POS", 1922 ``!f:real->real g. linear f /\ linear g /\ (g o f = I) 1923 ==> ?B. &0 < B /\ !x. B * abs(x) <= abs(f x)``, 1924 REPEAT STRIP_TAC THEN 1925 MP_TAC(ISPEC ``g:real->real`` LINEAR_BOUNDED_POS) THEN 1926 ASM_REWRITE_TAC[] THEN 1927 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 1928 EXISTS_TAC ``inv B:real`` THEN ASM_SIMP_TAC real_ss [REAL_LT_INV_EQ] THEN 1929 X_GEN_TAC ``x:real`` THEN MATCH_MP_TAC REAL_LE_TRANS THEN 1930 EXISTS_TAC ``inv(B) * abs(((g:real->real) o (f:real->real)) x)`` THEN 1931 CONJ_TAC THENL [ASM_SIMP_TAC real_ss [I_THM, REAL_LE_REFL], ALL_TAC] THEN 1932 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN 1933 ASM_SIMP_TAC real_ss [o_THM, REAL_LE_LDIV_EQ] THEN 1934 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_REWRITE_TAC[]); 1935 1936val LINEAR_INVERTIBLE_BOUNDED_BELOW = store_thm ("LINEAR_INVERTIBLE_BOUNDED_BELOW", 1937 ``!f:real->real g. linear f /\ linear g /\ (g o f = I) ==> 1938 ?B. !x. B * abs(x) <= abs(f x)``, 1939 MESON_TAC[LINEAR_INVERTIBLE_BOUNDED_BELOW_POS]); 1940 1941val LINEAR_INJECTIVE_BOUNDED_BELOW_POS = store_thm ("LINEAR_INJECTIVE_BOUNDED_BELOW_POS", 1942 ``!f:real->real. linear f /\ (!x y. (f x = f y) ==> (x = y)) 1943 ==> ?B. &0 < B /\ !x. abs(x) * B <= abs(f x)``, 1944 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN 1945 MATCH_MP_TAC LINEAR_INVERTIBLE_BOUNDED_BELOW_POS THEN 1946 METIS_TAC[LINEAR_INJECTIVE_LEFT_INVERSE, I_THM]); 1947 1948(* ------------------------------------------------------------------------- *) 1949(* Consequences of independence or spanning for cardinality. *) 1950(* ------------------------------------------------------------------------- *) 1951 1952val INDEPENDENT_CARD_LE_DIM = store_thm ("INDEPENDENT_CARD_LE_DIM", 1953 ``!v b:real->bool. b SUBSET v /\ independent b ==> FINITE b /\ CARD(b) <= dim v``, 1954 METIS_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, HAS_SIZE, SUBSET_TRANS]); 1955 1956val SPAN_CARD_GE_DIM = store_thm ("SPAN_CARD_GE_DIM", 1957 ``!v b:real->bool. v SUBSET (span b) /\ FINITE b ==> dim(v) <= CARD(b)``, 1958 METIS_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, HAS_SIZE, SUBSET_TRANS]); 1959 1960val BASIS_CARD_EQ_DIM = store_thm ("BASIS_CARD_EQ_DIM", 1961 ``!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b 1962 ==> FINITE b /\ (CARD b = dim v)``, 1963 METIS_TAC[LESS_EQUAL_ANTISYM, INDEPENDENT_CARD_LE_DIM, SPAN_CARD_GE_DIM]); 1964 1965val BASIS_HAS_SIZE_DIM = store_thm ("BASIS_HAS_SIZE_DIM", 1966 ``!v b. independent b /\ (span b = v) ==> b HAS_SIZE (dim v)``, 1967 REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_SIZE] THEN 1968 MATCH_MP_TAC BASIS_CARD_EQ_DIM THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN 1969 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[SPAN_INC]); 1970 1971val DIM_UNIQUE = store_thm ("DIM_UNIQUE", 1972 ``!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b /\ b HAS_SIZE n 1973 ==> (dim v = n)``, 1974 MESON_TAC[BASIS_CARD_EQ_DIM, HAS_SIZE]); 1975 1976val DIM_LE_CARD = store_thm ("DIM_LE_CARD", 1977 ``!s. FINITE s ==> dim s <= CARD s``, 1978 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN 1979 ASM_REWRITE_TAC[SPAN_INC, SUBSET_REFL]); 1980 1981(* ------------------------------------------------------------------------- *) 1982(* Standard bases are a spanning set, and obviously finite. *) 1983(* ------------------------------------------------------------------------- *) 1984 1985val SPAN_STDBASIS = store_thm ("SPAN_STDBASIS", 1986 ``span {i :real | 1 <= i /\ i <= 1} = UNIV``, 1987 REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2] THEN 1988 SIMP_TAC std_ss [EXTENSION, span, hull, IN_BIGINTER, IN_UNIV] THEN 1989 SIMP_TAC std_ss [SING_SUBSET, GSPECIFICATION, subspace] THEN 1990 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_RID] THEN 1991 FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC []); 1992 1993val HAS_SIZE_STDBASIS = store_thm ("HAS_SIZE_STDBASIS", 1994 ``{i :real | 1 <= i /\ i <= 1} HAS_SIZE 1``, 1995 REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2, HAS_SIZE] THEN 1996 REWRITE_TAC [FINITE_SING, CARD_SING]); 1997 1998(* ------------------------------------------------------------------------- *) 1999(* More lemmas about dimension. *) 2000(* ------------------------------------------------------------------------- *) 2001 2002val DIM_UNIV = store_thm ("DIM_UNIV", 2003 ``dim univ(:real) = 1:num``, 2004 MATCH_MP_TAC DIM_UNIQUE THEN EXISTS_TAC ``{i :real | &1 <= i /\ i <= &1}`` THEN 2005 REWRITE_TAC[SUBSET_UNIV, SPAN_STDBASIS, HAS_SIZE_STDBASIS, INDEPENDENT_STDBASIS]); 2006 2007val DIM_SUBSET = store_thm ("DIM_SUBSET", 2008 ``!s t:real->bool. s SUBSET t ==> dim(s) <= dim(t)``, 2009 MESON_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, SUBSET_DEF, HAS_SIZE]); 2010 2011val DIM_SUBSET_UNIV = store_thm ("DIM_SUBSET_UNIV", 2012 ``!s:real->bool. dim(s) <= (1:num)``, 2013 GEN_TAC THEN REWRITE_TAC[GSYM DIM_UNIV] THEN 2014 MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]); 2015 2016(* ------------------------------------------------------------------------- *) 2017(* Open and closed sets *) 2018(* ------------------------------------------------------------------------- *) 2019 2020val open_def = new_definition ("open_def", 2021 ``Open s <=> !x. x IN s ==> ?e. &0 < e /\ !x'. dist(x',x) < e ==> x' IN s``); 2022 2023val _ = overload_on ("open",``Open``); 2024 2025val closed_def = new_definition ("closed_def", 2026 ``Closed(s:real->bool) <=> open(UNIV DIFF s)``); 2027 2028val _ = overload_on ("closed",``Closed``); 2029 2030val euclidean = new_definition ("euclidean", 2031 ``euclidean = topology open``); 2032 2033val OPEN_EMPTY = store_thm ("OPEN_EMPTY", 2034 ``open {}``, 2035 REWRITE_TAC[open_def, NOT_IN_EMPTY]); 2036 2037val OPEN_UNIV = store_thm ("OPEN_UNIV", 2038 ``open univ(:real)``, 2039 REWRITE_TAC[open_def, IN_UNIV] THEN MESON_TAC[REAL_LT_01]); 2040 2041val OPEN_INTER = store_thm ("OPEN_INTER", 2042 ``!s t. open s /\ open t ==> open (s INTER t)``, 2043 REPEAT GEN_TAC THEN REWRITE_TAC [open_def] THEN 2044 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REWRITE_TAC [IN_INTER] THEN 2045 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN 2046 STRIP_TAC THEN STRIP_TAC THEN FULL_SIMP_TAC real_ss [] THEN 2047 Cases_on `e < e'` THENL [EXISTS_TAC ``e:real`` THEN 2048 ASM_REWRITE_TAC [] THEN GEN_TAC THEN 2049 UNDISCH_TAC (Term `!x'. dist (x',x) < e ==> x' IN s`) THEN 2050 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN RW_TAC std_ss [] THEN 2051 UNDISCH_TAC (Term `!x'. dist (x',x) < e' ==> x' IN t`) THEN 2052 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN 2053 KNOW_TAC ``dist (x',x) < e'`` THENL [MATCH_MP_TAC REAL_LT_TRANS THEN 2054 EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC [], ALL_TAC] THEN 2055 RW_TAC std_ss [] THEN Cases_on `e' < e` THEN 2056 EXISTS_TAC ``e':real`` THEN ASM_REWRITE_TAC [], 2057 Cases_on `e' < e` THENL [EXISTS_TAC ``e':real`` THEN 2058 ASM_REWRITE_TAC [] THEN GEN_TAC THEN 2059 UNDISCH_TAC (Term `!x'. dist (x',x) < e' ==> x' IN t`) THEN 2060 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN 2061 RW_TAC std_ss [] THEN 2062 UNDISCH_TAC (Term `!x'. dist (x',x) < e ==> x' IN s`) THEN 2063 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN 2064 KNOW_TAC ``dist (x',x) < e`` THENL [MATCH_MP_TAC REAL_LT_TRANS THEN 2065 EXISTS_TAC ``e':real`` THEN ASM_REWRITE_TAC [], ALL_TAC] THEN 2066 RW_TAC std_ss [], 2067 FULL_SIMP_TAC std_ss [REAL_NOT_LT] THEN KNOW_TAC ``(e:real) = e'`` THENL 2068 [METIS_TAC [REAL_LE_ANTISYM], ALL_TAC] THEN DISCH_TAC THEN 2069 EXISTS_TAC ``e:real`` THEN CONJ_TAC THEN FULL_SIMP_TAC real_ss []]]); 2070 2071val OPEN_BIGUNION = store_thm ("OPEN_BIGUNION", 2072 ``(!s. s IN f ==> open s) ==> open(BIGUNION f)``, 2073 REWRITE_TAC[open_def, IN_BIGUNION] THEN MESON_TAC[]); 2074 2075val OPEN_EXISTS_IN = store_thm ("OPEN_EXISTS_IN", 2076 ``!P Q:'a->real->bool. 2077 (!a. P a ==> open {x | Q a x}) ==> open {x | ?a. P a /\ Q a x}``, 2078 REPEAT STRIP_TAC THEN 2079 SUBGOAL_THEN ``open(BIGUNION {{x | Q (a:'a) (x:real)} | P a})`` MP_TAC THENL 2080 [MATCH_MP_TAC OPEN_BIGUNION THEN ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN 2081 METIS_TAC [], MATCH_MP_TAC (TAUT `(a <=> b) ==> a ==> b`) THEN AP_TERM_TAC THEN 2082 SIMP_TAC std_ss [EXTENSION, IN_BIGUNION, GSPECIFICATION] THEN 2083 SET_TAC[]]); 2084 2085val OPEN_EXISTS = store_thm ("OPEN_EXISTS", 2086 ``!Q:'a->real->bool. (!a. open {x | Q a x}) ==> open {x | ?a. Q a x}``, 2087 MP_TAC(ISPEC ``\x:'a. T`` OPEN_EXISTS_IN) THEN REWRITE_TAC[]); 2088 2089val OPEN_IN = store_thm ("OPEN_IN", 2090 ``!s:real->bool. open s <=> open_in euclidean s``, 2091 GEN_TAC THEN REWRITE_TAC[euclidean] THEN CONV_TAC SYM_CONV THEN 2092 AP_THM_TAC THEN REWRITE_TAC[GSYM(CONJUNCT2 topology_tybij)] THEN 2093 SIMP_TAC std_ss [REWRITE_RULE[IN_DEF] istopology] THEN 2094 REWRITE_TAC[OPEN_EMPTY, OPEN_INTER, SUBSET_DEF] THEN 2095 MESON_TAC[IN_DEF, OPEN_BIGUNION]); 2096 2097val TOPSPACE_EUCLIDEAN = store_thm ("TOPSPACE_EUCLIDEAN", 2098 ``topspace euclidean = univ(:real)``, 2099 SIMP_TAC std_ss [topspace, EXTENSION, IN_UNIV, IN_BIGUNION, GSPECIFICATION] THEN 2100 MESON_TAC[OPEN_UNIV, IN_UNIV, OPEN_IN]); 2101 2102val TOPSPACE_EUCLIDEAN_SUBTOPOLOGY = store_thm ("TOPSPACE_EUCLIDEAN_SUBTOPOLOGY", 2103 ``!s. topspace (subtopology euclidean s) = s``, 2104 REWRITE_TAC[TOPSPACE_EUCLIDEAN, TOPSPACE_SUBTOPOLOGY, INTER_UNIV]); 2105 2106val OPEN_IN_REFL = store_thm ("OPEN_IN_REFL", 2107 ``!s:real->bool. open_in (subtopology euclidean s) s``, 2108 REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL, TOPSPACE_EUCLIDEAN, SUBSET_UNIV]); 2109 2110val CLOSED_IN_REFL = store_thm ("CLOSED_IN_REFL", 2111 ``!s:real->bool. closed_in (subtopology euclidean s) s``, 2112 REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY_REFL, TOPSPACE_EUCLIDEAN, SUBSET_UNIV]); 2113 2114val CLOSED_IN = store_thm ("CLOSED_IN", 2115 ``!s:real->bool. closed s <=> closed_in euclidean s``, 2116 REWRITE_TAC[closed_def, closed_in, TOPSPACE_EUCLIDEAN, OPEN_IN, SUBSET_UNIV]); 2117 2118val OPEN_UNION = store_thm ("OPEN_UNION", 2119 ``!s t. open s /\ open t ==> open(s UNION t)``, 2120 REWRITE_TAC [open_def] THEN REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN 2121 POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN 2122 POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN 2123 REPEAT STRIP_TAC THEN Cases_on `x IN s` THENL 2124 [FULL_SIMP_TAC std_ss [] THEN EXISTS_TAC ``e:real`` THEN 2125 FULL_SIMP_TAC std_ss [IN_UNION], FULL_SIMP_TAC std_ss [IN_UNION] THEN 2126 EXISTS_TAC ``e:real`` THEN FULL_SIMP_TAC std_ss [IN_UNION]]); 2127 2128val OPEN_SUB_OPEN = store_thm ("OPEN_SUB_OPEN", 2129 ``!s. open s <=> !x. x IN s ==> ?t. open t /\ x IN t /\ t SUBSET s``, 2130 GEN_TAC THEN EQ_TAC THENL 2131 [RW_TAC std_ss [] THEN EXISTS_TAC ``s:real->bool`` THEN 2132 ASM_REWRITE_TAC [SUBSET_REFL], DISCH_TAC THEN 2133 REWRITE_TAC [open_def] THEN GEN_TAC THEN 2134 POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN DISCH_TAC THEN DISCH_TAC THEN 2135 FULL_SIMP_TAC std_ss [open_def] THEN 2136 UNDISCH_TAC (Term `!x. x IN t ==> ?e. 0 < e /\ !x'. dist (x',x) < e ==> x' IN t `) 2137 THEN DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN 2138 RW_TAC std_ss [] THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC [] 2139 THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN 2140 RW_TAC std_ss [] THEN METIS_TAC [SUBSET_DEF]]); 2141 2142val CLOSED_EMPTY = store_thm ("CLOSED_EMPTY", 2143 ``closed {}``, 2144 REWRITE_TAC[CLOSED_IN, CLOSED_IN_EMPTY]); 2145 2146val CLOSED_UNIV = store_thm ("CLOSED_UNIV", 2147 ``closed(UNIV:real->bool)``, 2148 REWRITE_TAC[CLOSED_IN, GSYM TOPSPACE_EUCLIDEAN, CLOSED_IN_TOPSPACE]); 2149 2150val CLOSED_UNION = store_thm ("CLOSED_UNION", 2151 ``!s t. closed s /\ closed t ==> closed(s UNION t)``, 2152 REWRITE_TAC[CLOSED_IN, CLOSED_IN_UNION]); 2153 2154val CLOSED_INTER = store_thm ("CLOSED_INTER", 2155 ``!s t. closed s /\ closed t ==> closed(s INTER t)``, 2156 REWRITE_TAC[CLOSED_IN, CLOSED_IN_INTER]); 2157 2158val CLOSED_BIGINTER = store_thm ("CLOSED_BIGINTER", 2159 ``!f. (!s:real->bool. s IN f ==> closed s) ==> closed(BIGINTER f)``, 2160 REWRITE_TAC[CLOSED_IN] THEN REPEAT STRIP_TAC THEN 2161 ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN 2162 ASM_SIMP_TAC std_ss [CLOSED_IN_BIGINTER, BIGINTER_EMPTY] THEN 2163 REWRITE_TAC[GSYM TOPSPACE_EUCLIDEAN, CLOSED_IN_TOPSPACE]); 2164 2165val BIGINTER_GSPEC = store_thm ("BIGINTER_GSPEC", 2166 ``(!P f. BIGINTER {f x | P x} = {a | !x. P x ==> a IN (f x)}) /\ 2167 (!P f. BIGINTER {f x y | P x y} = {a | !x y. P x y ==> a IN (f x y)}) /\ 2168 (!P f. BIGINTER {f x y z | P x y z} = 2169 {a | !x y z. P x y z ==> a IN (f x y z)})``, 2170 REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 2171 SIMP_TAC std_ss [IN_BIGINTER, GSPECIFICATION, EXISTS_PROD] THEN MESON_TAC[]); 2172 2173val CLOSED_FORALL_IN = store_thm ("CLOSED_FORALL_IN", 2174 ``!P Q:'a->real->bool. 2175 (!a. P a ==> closed {x | Q a x}) ==> closed {x | !a. P a ==> Q a x}``, 2176 REPEAT STRIP_TAC THEN 2177 SUBGOAL_THEN ``closed(BIGINTER {{x | Q (a:'a) (x:real)} | P a})`` MP_TAC THENL 2178 [MATCH_MP_TAC CLOSED_BIGINTER THEN ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC], 2179 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN SIMP_TAC std_ss [BIGINTER_GSPEC] THEN 2180 SET_TAC[]]); 2181 2182val CLOSED_FORALL = store_thm ("CLOSED_FORALL", 2183 ``!Q:'a->real->bool. (!a. closed {x | Q a x}) ==> closed {x | !a. Q a x}``, 2184 MP_TAC(ISPEC ``\x:'a. T`` CLOSED_FORALL_IN) THEN REWRITE_TAC[]); 2185 2186val OPEN_CLOSED = store_thm ("OPEN_CLOSED", 2187 ``!s:real->bool. open s <=> closed(UNIV DIFF s)``, 2188 SIMP_TAC std_ss [OPEN_IN, CLOSED_IN, TOPSPACE_EUCLIDEAN, SUBSET_UNIV, 2189 OPEN_IN_CLOSED_IN_EQ]); 2190 2191val OPEN_DIFF = store_thm ("OPEN_DIFF", 2192 ``!s t. open s /\ closed t ==> open(s DIFF t)``, 2193 REWRITE_TAC[OPEN_IN, CLOSED_IN, OPEN_IN_DIFF]); 2194 2195val CLOSED_DIFF = store_thm ("CLOSED_DIFF", 2196 ``!s t. closed s /\ open t ==> closed(s DIFF t)``, 2197 REWRITE_TAC[OPEN_IN, CLOSED_IN, CLOSED_IN_DIFF]); 2198 2199val OPEN_BIGINTER = store_thm ("OPEN_BIGINTER", 2200 ``!s. FINITE s /\ (!t. t IN s ==> open t) ==> (open (BIGINTER s))``, 2201 REWRITE_TAC [GSYM AND_IMP_INTRO] THEN GEN_TAC THEN 2202 KNOW_TAC `` (!t. t IN s ==> open t) ==> open (BIGINTER s) <=> 2203 (\x. (!t. t IN x ==> open t) ==> open (BIGINTER x)) s`` THENL 2204 [SIMP_TAC std_ss [GSPECIFICATION] THEN DISCH_TAC THEN 2205 ASM_REWRITE_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN 2206 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 2207 REWRITE_TAC [BIGINTER_INSERT, BIGINTER_EMPTY, OPEN_UNIV, 2208 IN_INSERT] THEN MESON_TAC [OPEN_INTER]); 2209 2210val CLOSED_BIGUNION = store_thm ("CLOSED_BIGUNION", 2211 ``!s. FINITE s /\ (!t. t IN s ==> closed t) ==> closed(BIGUNION s)``, 2212 REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 2213 KNOW_TAC ``!s. ((!t. t IN s ==> closed t) ==> closed(BIGUNION s)) <=> 2214 (\s. (!t. t IN s ==> closed t) ==> closed(BIGUNION s)) s`` THENL 2215 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 2216 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 2217 REWRITE_TAC[BIGUNION_INSERT, BIGUNION_EMPTY, CLOSED_EMPTY, IN_INSERT] THEN 2218 MESON_TAC[CLOSED_UNION]); 2219 2220(* ------------------------------------------------------------------------- *) 2221(* Open and closed balls. *) 2222(* ------------------------------------------------------------------------- *) 2223 2224(* new definition based on metricTheory *) 2225Definition ball_def : 2226 ball = metric$B(mr1) 2227End 2228 2229(* old definition now becomes a theorem *) 2230Theorem ball : 2231 !x e. ball(x,e) = { y | dist(x,y) < e} 2232Proof 2233 RW_TAC std_ss [ball_def, dist_def, metricTheory.ball, 2234 Once EXTENSION, GSPECIFICATION] 2235 >> rw [IN_APP] 2236QED 2237 2238val cball = new_definition ("cball", 2239 ``cball(x,e) = { y | dist(x,y) <= e}``); 2240 2241val sphere = new_definition ("sphere", 2242 ``sphere(x,e) = { y | dist(x,y) = e}``); 2243 2244val IN_BALL = store_thm ("IN_BALL", 2245 ``!x y e. y IN ball(x,e) <=> dist(x,y) < e``, 2246 REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [ball, GSPECIFICATION]); 2247 2248val IN_CBALL = store_thm ("IN_CBALL", 2249 ``!x y e. y IN cball(x,e) <=> dist(x,y) <= e``, 2250 REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [cball, GSPECIFICATION]); 2251 2252val IN_SPHERE = store_thm ("IN_SPHERE", 2253 ``!x y e. y IN sphere(x,e) <=> (dist(x,y) = e)``, 2254 REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [sphere, GSPECIFICATION]); 2255 2256val IN_BALL_0 = store_thm ("IN_BALL_0", 2257 ``!x e. x IN ball(0,e) <=> abs(x) < e``, 2258 REWRITE_TAC [IN_BALL, dist, REAL_SUB_LZERO, ABS_NEG]); 2259 2260val IN_CBALL_0 = store_thm ("IN_CBALL_0", 2261 ``!x e. x IN cball(0,e) <=> abs(x) <= e``, 2262 REWRITE_TAC[IN_CBALL, dist, REAL_SUB_LZERO, ABS_NEG]); 2263 2264val IN_SPHERE_0 = store_thm ("IN_SPHERE_0", 2265 ``!x e. x IN sphere(0,e) <=> (abs(x) = e)``, 2266 REWRITE_TAC[IN_SPHERE, dist, REAL_SUB_LZERO, ABS_NEG]); 2267 2268val BALL_TRIVIAL = store_thm ("BALL_TRIVIAL", 2269 ``!x. ball(x,&0) = {}``, 2270 REWRITE_TAC[EXTENSION, IN_BALL, IN_SING, NOT_IN_EMPTY, dist] THEN REAL_ARITH_TAC); 2271 2272val CBALL_TRIVIAL = store_thm ("CBALL_TRIVIAL", 2273 ``!x. cball(x,&0) = {x}``, 2274 REWRITE_TAC[EXTENSION, IN_CBALL, IN_SING, NOT_IN_EMPTY, dist] THEN REAL_ARITH_TAC); 2275 2276val CENTRE_IN_CBALL = store_thm ("CENTRE_IN_CBALL", 2277 ``!x e. x IN cball(x,e) <=> &0 <= e``, 2278 MESON_TAC[IN_CBALL, DIST_REFL]); 2279 2280val BALL_SUBSET_CBALL = store_thm ("BALL_SUBSET_CBALL", 2281 ``!x e. ball(x,e) SUBSET cball(x,e)``, 2282 REWRITE_TAC[IN_BALL, IN_CBALL, SUBSET_DEF] THEN REAL_ARITH_TAC); 2283 2284val SPHERE_SUBSET_CBALL = store_thm ("SPHERE_SUBSET_CBALL", 2285 ``!x e. sphere(x,e) SUBSET cball(x,e)``, 2286 REWRITE_TAC[IN_SPHERE, IN_CBALL, SUBSET_DEF] THEN REAL_ARITH_TAC); 2287 2288val SUBSET_BALL = store_thm ("SUBSET_BALL", 2289 ``!x d e. d <= e ==> ball(x,d) SUBSET ball(x,e)``, 2290 REWRITE_TAC[SUBSET_DEF, IN_BALL] THEN MESON_TAC[REAL_LTE_TRANS]); 2291 2292val SUBSET_CBALL = store_thm ("SUBSET_CBALL", 2293 ``!x d e. d <= e ==> cball(x,d) SUBSET cball(x,e)``, 2294 REWRITE_TAC[SUBSET_DEF, IN_CBALL] THEN MESON_TAC[REAL_LE_TRANS]); 2295 2296val BALL_MAX_UNION = store_thm ("BALL_MAX_UNION", 2297 ``!a r s. ball(a,max r s) = ball(a,r) UNION ball(a,s)``, 2298 rpt GEN_TAC 2299 >> REWRITE_TAC [IN_BALL, IN_UNION, EXTENSION, dist] 2300 >> GEN_TAC >> Q.ABBREV_TAC `b = abs (a - x)` 2301 >> REWRITE_TAC [REAL_LT_MAX]); 2302 2303val BALL_MIN_INTER = store_thm ("BALL_MIN_INTER", 2304 ``!a r s. ball(a,min r s) = ball(a,r) INTER ball(a,s)``, 2305 rpt GEN_TAC 2306 >> REWRITE_TAC [IN_BALL, IN_INTER, EXTENSION, dist] 2307 >> GEN_TAC >> Q.ABBREV_TAC `b = abs (a - x)` 2308 >> REWRITE_TAC [REAL_LT_MIN]); 2309 2310val CBALL_MAX_UNION = store_thm ("CBALL_MAX_UNION", 2311 ``!a r s. cball(a,max r s) = cball(a,r) UNION cball(a,s)``, 2312 rpt GEN_TAC 2313 >> REWRITE_TAC [IN_CBALL, IN_UNION, EXTENSION, dist] 2314 >> GEN_TAC >> Q.ABBREV_TAC `b = abs (a - x)` 2315 >> REWRITE_TAC [REAL_LE_MAX]); 2316 2317val CBALL_MIN_INTER = store_thm ("CBALL_MIN_INTER", 2318 ``!x d e. cball(x,min d e) = cball(x,d) INTER cball(x,e)``, 2319 rpt GEN_TAC 2320 >> REWRITE_TAC [EXTENSION, IN_INTER, IN_CBALL, dist] 2321 >> Q.X_GEN_TAC `a` >> Q.ABBREV_TAC `b = abs (x - a)` 2322 >> REWRITE_TAC [REAL_LE_MIN]); 2323 2324val BALL_TRANSLATION = store_thm ("BALL_TRANSLATION", 2325 ``!a x r. ball(a + x,r) = IMAGE (\y. a + y) (ball(x,r))``, 2326 REPEAT GEN_TAC THEN REWRITE_TAC [EXTENSION, IN_BALL, IN_IMAGE, dist] THEN 2327 GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x' - a:real`` THEN 2328 RW_TAC std_ss [REAL_SUB_ADD2] THEN 2329 ASM_REWRITE_TAC [REAL_ARITH ``x - (x' - a) = a + x - x':real``], 2330 RW_TAC std_ss [] THEN 2331 METIS_TAC [REAL_ARITH ``a - (b + c) = a - b - c:real``, REAL_ADD_SUB]]); 2332 2333val CBALL_TRANSLATION = store_thm ("CBALL_TRANSLATION", 2334 ``!a x r. cball(a + x,r) = IMAGE (\y. a + y) (cball(x,r))``, 2335 REPEAT GEN_TAC THEN REWRITE_TAC [EXTENSION, IN_CBALL, IN_IMAGE, dist] THEN 2336 GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x' - a:real`` THEN 2337 RW_TAC std_ss [REAL_SUB_ADD2] THEN 2338 ASM_REWRITE_TAC [REAL_ARITH ``x - (x' - a) = a + x - x':real``], 2339 RW_TAC std_ss [] THEN 2340 METIS_TAC [REAL_ARITH ``a - (b + c) = a - b - c:real``, REAL_ADD_SUB]]); 2341 2342val SPHERE_TRANSLATION = store_thm ("SPHERE_TRANSLATION", 2343 ``!a x r. sphere(a + x,r) = IMAGE (\y. a + y) (sphere(x,r))``, 2344 REPEAT GEN_TAC THEN REWRITE_TAC [EXTENSION, IN_SPHERE, IN_IMAGE, dist] THEN 2345 GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x' - a:real`` THEN 2346 RW_TAC std_ss [REAL_SUB_ADD2] THEN 2347 ASM_REWRITE_TAC [REAL_ARITH ``x - (x' - a) = a + x - x':real``], 2348 RW_TAC std_ss [] THEN 2349 METIS_TAC [REAL_ARITH ``a - (b + c) = a - b - c:real``, REAL_ADD_SUB]]); 2350 2351val BALL_LINEAR_IMAGE = store_thm ("BALL_LINEAR_IMAGE", 2352 ``!f:real->real x r. 2353 linear f /\ (!y. ?x. f x = y) /\ (!x. abs(f x) = abs x) 2354 ==> (ball(f x,r) = IMAGE f (ball(x,r)))``, 2355 REWRITE_TAC[ball] THEN 2356 SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION] THEN 2357 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL 2358 [UNDISCH_TAC ``!y. ?x. (f:real->real) x = y`` THEN DISCH_TAC THEN 2359 POP_ASSUM (MP_TAC o SPEC ``x':real``) THEN STRIP_TAC THEN 2360 EXISTS_TAC ``x'':real`` THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN 2361 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x. abs ((f:real->real) x) = abs x`` THEN 2362 DISCH_THEN (MP_TAC o SYM o SPEC ``x - x'':real``) THEN DISCH_TAC THEN 2363 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2364 DISCH_THEN (MP_TAC o SPECL [``x:real``, ``-x'':real``]) THEN 2365 REWRITE_TAC [GSYM real_sub] THEN DISCH_TAC THEN 2366 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-x = -1 * x:real``] THEN 2367 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2368 DISCH_THEN (MP_TAC o SPECL [``-1:real``,``x'':real``]) THEN ASM_REAL_ARITH_TAC, 2369 ASM_REWRITE_TAC [real_sub] THEN REWRITE_TAC [REAL_ARITH ``-(f:real->real) x = -1 * f x``] THEN 2370 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2371 DISCH_THEN (MP_TAC o SYM o SPECL [``-1:real``,``x'':real``]) THEN DISCH_TAC THEN 2372 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-1 * x:real = -x``] THEN 2373 UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2374 DISCH_THEN (MP_TAC o SYM o SPECL [``x:real``, ``-x'':real``]) THEN DISCH_TAC THEN 2375 ASM_REWRITE_TAC [GSYM real_sub]]); 2376 2377val CBALL_LINEAR_IMAGE = store_thm ("CBALL_LINEAR_IMAGE", 2378 ``!f:real->real x r. 2379 linear f /\ (!y. ?x. f x = y) /\ (!x. abs(f x) = abs x) 2380 ==> (cball(f x,r) = IMAGE f (cball(x,r)))``, 2381 REWRITE_TAC[cball] THEN 2382 SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION] THEN 2383 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL 2384 [UNDISCH_TAC ``!y. ?x. (f:real->real) x = y`` THEN DISCH_TAC THEN 2385 POP_ASSUM (MP_TAC o SPEC ``x':real``) THEN STRIP_TAC THEN 2386 EXISTS_TAC ``x'':real`` THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN 2387 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x. abs ((f:real->real) x) = abs x`` THEN 2388 DISCH_THEN (MP_TAC o SYM o SPEC ``x - x'':real``) THEN DISCH_TAC THEN 2389 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2390 DISCH_THEN (MP_TAC o SPECL [``x:real``, ``-x'':real``]) THEN 2391 REWRITE_TAC [GSYM real_sub] THEN DISCH_TAC THEN 2392 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-x = -1 * x:real``] THEN 2393 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2394 DISCH_THEN (MP_TAC o SPECL [``-1:real``,``x'':real``]) THEN ASM_REAL_ARITH_TAC, 2395 ASM_REWRITE_TAC [real_sub] THEN REWRITE_TAC [REAL_ARITH ``-(f:real->real) x = -1 * f x``] THEN 2396 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2397 DISCH_THEN (MP_TAC o SYM o SPECL [``-1:real``,``x'':real``]) THEN DISCH_TAC THEN 2398 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-1 * x:real = -x``] THEN 2399 UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2400 DISCH_THEN (MP_TAC o SYM o SPECL [``x:real``, ``-x'':real``]) THEN DISCH_TAC THEN 2401 ASM_REWRITE_TAC [GSYM real_sub]]); 2402 2403val SPHERE_LINEAR_IMAGE = store_thm ("SPHERE_LINEAR_IMAGE", 2404 ``!f:real->real x r. 2405 linear f /\ (!y. ?x. f x = y) /\ (!x. abs(f x) = abs x) 2406 ==> (sphere(f x,r) = IMAGE f (sphere(x,r)))``, 2407 REWRITE_TAC[sphere] THEN 2408 SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION] THEN 2409 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL 2410 [UNDISCH_TAC ``!y. ?x. (f:real->real) x = y`` THEN DISCH_TAC THEN 2411 POP_ASSUM (MP_TAC o SPEC ``x':real``) THEN STRIP_TAC THEN 2412 EXISTS_TAC ``x'':real`` THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN 2413 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x. abs ((f:real->real) x) = abs x`` THEN 2414 DISCH_THEN (MP_TAC o SYM o SPEC ``x - x'':real``) THEN DISCH_TAC THEN 2415 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2416 DISCH_THEN (MP_TAC o SPECL [``x:real``, ``-x'':real``]) THEN 2417 REWRITE_TAC [GSYM real_sub] THEN DISCH_TAC THEN 2418 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-x = -1 * x:real``] THEN 2419 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2420 DISCH_THEN (MP_TAC o SPECL [``-1:real``,``x'':real``]) THEN ASM_REAL_ARITH_TAC, 2421 ASM_REWRITE_TAC [real_sub] THEN REWRITE_TAC [REAL_ARITH ``-(f:real->real) x = -1 * f x``] THEN 2422 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2423 DISCH_THEN (MP_TAC o SYM o SPECL [``-1:real``,``x'':real``]) THEN DISCH_TAC THEN 2424 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-1 * x:real = -x``] THEN 2425 UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2426 DISCH_THEN (MP_TAC o SYM o SPECL [``x:real``, ``-x'':real``]) THEN DISCH_TAC THEN 2427 ASM_REWRITE_TAC [GSYM real_sub]]); 2428 2429val BALL_SCALING = store_thm ("BALL_SCALING", 2430 ``!c. &0 < c ==> !x r. ball(c * x,c * r) = IMAGE (\x. c * x) (ball(x,r))``, 2431 REWRITE_TAC [IMAGE_DEF, IN_BALL] THEN BETA_TAC THEN 2432 SIMP_TAC std_ss [ball, EXTENSION, GSPECIFICATION, dist] THEN 2433 REPEAT STRIP_TAC THEN EQ_TAC THENL [DISCH_TAC THEN 2434 EXISTS_TAC ``x' / c:real`` THEN 2435 FULL_SIMP_TAC std_ss [REAL_DIV_LMUL, REAL_POS_NZ] THEN 2436 KNOW_TAC `` abs (x - x' / c) < r <=> abs c * abs (x - x' / c) < c * r:real`` THENL 2437 [FULL_SIMP_TAC std_ss [abs, REAL_LT_IMP_LE, REAL_LT_LMUL], ALL_TAC] THEN 2438 DISC_RW_KILL THEN REWRITE_TAC [GSYM ABS_MUL] THEN 2439 FULL_SIMP_TAC std_ss [REAL_SUB_LDISTRIB, REAL_DIV_LMUL, REAL_POS_NZ], 2440 STRIP_TAC THEN FULL_SIMP_TAC std_ss [GSYM dist, DIST_MUL, abs, 2441 REAL_LT_IMP_LE, REAL_LT_LMUL]]); 2442 2443val CBALL_SCALING = store_thm ("CBALL_SCALING", 2444 ``!c. &0 < c ==> !x r. cball(c * x,c * r) = IMAGE (\x. c * x) (cball(x,r))``, 2445 REWRITE_TAC [IMAGE_DEF, IN_CBALL] THEN BETA_TAC THEN 2446 SIMP_TAC std_ss [cball, EXTENSION, GSPECIFICATION, dist] THEN 2447 REPEAT STRIP_TAC THEN EQ_TAC THENL [DISCH_TAC THEN 2448 EXISTS_TAC ``x' / c:real`` THEN 2449 FULL_SIMP_TAC std_ss [REAL_DIV_LMUL, REAL_POS_NZ] THEN 2450 KNOW_TAC `` abs (x - x' / c) <= r <=> abs c * abs (x - x' / c) <= c * r:real`` THENL 2451 [FULL_SIMP_TAC std_ss [abs, REAL_LT_IMP_LE, REAL_LE_LMUL], ALL_TAC] THEN 2452 DISC_RW_KILL THEN REWRITE_TAC [GSYM ABS_MUL] THEN 2453 FULL_SIMP_TAC std_ss [REAL_SUB_LDISTRIB, REAL_DIV_LMUL, REAL_POS_NZ], 2454 STRIP_TAC THEN FULL_SIMP_TAC std_ss [GSYM dist, DIST_MUL, abs, 2455 REAL_LT_IMP_LE, REAL_LE_LMUL]]); 2456 2457val CBALL_DIFF_BALL = store_thm ("CBALL_DIFF_BALL", 2458 ``!a r. cball(a,r) DIFF ball(a,r) = sphere(a,r)``, 2459 SIMP_TAC std_ss [ball, cball, sphere, EXTENSION, IN_DIFF, GSPECIFICATION] THEN 2460 REAL_ARITH_TAC); 2461 2462val BALL_UNION_SPHERE = store_thm ("BALL_UNION_SPHERE", 2463 ``!a r. ball(a,r) UNION sphere(a,r) = cball(a,r)``, 2464 SIMP_TAC std_ss [ball, cball, sphere, EXTENSION, IN_UNION, GSPECIFICATION] THEN 2465 REAL_ARITH_TAC); 2466 2467val SPHERE_UNION_BALL = store_thm ("SPHERE_UNION_BALL", 2468 ``!a r. sphere(a,r) UNION ball(a,r) = cball(a,r)``, 2469 SIMP_TAC std_ss [ball, cball, sphere, EXTENSION, IN_UNION, GSPECIFICATION] THEN 2470 REAL_ARITH_TAC); 2471 2472val CBALL_DIFF_SPHERE = store_thm ("CBALL_DIFF_SPHERE", 2473 ``!a r. cball(a,r) DIFF sphere(a,r) = ball(a,r)``, 2474 REWRITE_TAC[EXTENSION, IN_DIFF, IN_SPHERE, IN_BALL, IN_CBALL] THEN 2475 REAL_ARITH_TAC); 2476 2477val OPEN_BALL = store_thm ("OPEN_BALL", 2478 ``!x e. open(ball(x,e))``, 2479 REPEAT GEN_TAC THEN REWRITE_TAC[open_def, ball] THEN 2480 FULL_SIMP_TAC std_ss [GSPECIFICATION] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN 2481 MESON_TAC [REAL_SUB_LT, REAL_LT_SUB_LADD, REAL_ADD_SYM, REAL_LET_TRANS, 2482 DIST_TRIANGLE_ALT]); 2483 2484val CENTRE_IN_BALL = store_thm ("CENTRE_IN_BALL", 2485 ``!x e. x IN ball(x,e) <=> &0 < e``, 2486 MESON_TAC[IN_BALL, DIST_REFL]); 2487 2488val OPEN_CONTAINS_BALL = store_thm ("OPEN_CONTAINS_BALL", 2489 ``!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ ball(x,e) SUBSET s``, 2490 REWRITE_TAC[open_def, SUBSET_DEF, IN_BALL] THEN SIMP_TAC std_ss [DIST_SYM]); 2491 2492val OPEN_CONTAINS_BALL_EQ = store_thm ("OPEN_CONTAINS_BALL_EQ", 2493 ``!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ ball(x,e) SUBSET s)``, 2494 MESON_TAC[OPEN_CONTAINS_BALL, SUBSET_DEF, CENTRE_IN_BALL]); 2495 2496val BALL_EQ_EMPTY = store_thm ("BALL_EQ_EMPTY", 2497 ``!x e. (ball(x,e) = {}) <=> e <= &0``, 2498 REWRITE_TAC[EXTENSION, IN_BALL, NOT_IN_EMPTY, REAL_NOT_LT] THEN 2499 MESON_TAC[DIST_POS_LE, REAL_LE_TRANS, DIST_REFL]); 2500 2501val BALL_EMPTY = store_thm ("BALL_EMPTY", 2502 ``!x e. e <= &0 ==> (ball(x,e) = {})``, 2503 REWRITE_TAC[BALL_EQ_EMPTY]); 2504 2505val OPEN_CONTAINS_CBALL = store_thm ("OPEN_CONTAINS_CBALL", 2506 ``!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ cball(x,e) SUBSET s``, 2507 GEN_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN EQ_TAC THENL 2508 [ALL_TAC, ASM_MESON_TAC[SUBSET_TRANS, BALL_SUBSET_CBALL]] THEN 2509 KNOW_TAC ``!x. (x IN s ==> ?e. 0 < e /\ cball (x,e) SUBSET s) = 2510 (\x:real. x IN s ==> ?e. 0 < e /\ cball (x,e) SUBSET s) x`` THENL 2511 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 2512 KNOW_TAC ``!x. (x IN s ==> ?e. 0 < e /\ ball (x,e) SUBSET s) = 2513 (\x:real. x IN s ==> ?e. 0 < e /\ ball (x,e) SUBSET s) x`` THENL 2514 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 2515 MATCH_MP_TAC MONO_ALL THEN GEN_TAC THEN BETA_TAC THEN 2516 MATCH_MP_TAC MONO_IMP THEN 2517 REWRITE_TAC[SUBSET_DEF, IN_BALL, IN_CBALL] THEN 2518 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 2519 EXISTS_TAC ``e / &2:real`` THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN 2520 SUBGOAL_THEN ``e / &2 < e:real`` (fn th => ASM_MESON_TAC[th, REAL_LET_TRANS]) THEN 2521 UNDISCH_TAC ``0 < e:real`` THEN SIMP_TAC arith_ss [REAL_LT_HALF2]); 2522 2523val OPEN_CONTAINS_CBALL_EQ = store_thm ("OPEN_CONTAINS_CBALL_EQ", 2524 ``!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ cball(x,e) SUBSET s)``, 2525 MESON_TAC[OPEN_CONTAINS_CBALL, SUBSET_DEF, REAL_LT_IMP_LE, CENTRE_IN_CBALL]); 2526 2527val SPHERE_EQ_EMPTY = store_thm ("SPHERE_EQ_EMPTY", 2528 ``!a:real r. (sphere(a,r) = {}) <=> r < &0``, 2529 SIMP_TAC std_ss [sphere, EXTENSION, GSPECIFICATION, NOT_IN_EMPTY] THEN 2530 REPEAT GEN_TAC THEN EQ_TAC THENL [CCONTR_TAC THEN 2531 FULL_SIMP_TAC std_ss [REAL_NOT_LT] THEN 2532 UNDISCH_TAC ``!x. dist (a,x) <> r`` THEN 2533 FULL_SIMP_TAC std_ss [REAL_LE_LT, dist] THENL 2534 [EXISTS_TAC ``a - r:real`` THEN POP_ASSUM MP_TAC THEN 2535 REAL_ARITH_TAC, EXISTS_TAC ``a:real`` THEN 2536 METIS_TAC [REAL_SUB_REFL, EQ_SYM_EQ, ABS_0]], DISCH_TAC THEN 2537 ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN CCONTR_TAC THEN 2538 UNDISCH_TAC ``r < 0:real`` THEN FULL_SIMP_TAC std_ss [REAL_NOT_LT, DIST_POS_LE]]); 2539 2540val SPHERE_EMPTY = store_thm ("SPHERE_EMPTY", 2541 ``!a:real r. r < &0 ==> (sphere(a,r) = {})``, 2542 REWRITE_TAC[SPHERE_EQ_EMPTY]); 2543 2544val NEGATIONS_BALL = store_thm ("NEGATIONS_BALL", 2545 ``!r. IMAGE (\x:real. -x) (ball(0:real,r)) = ball(0,r)``, 2546 GEN_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_BALL_0] THEN 2547 GEN_TAC THEN EQ_TAC THENL [METIS_TAC [ABS_NEG], DISCH_TAC THEN 2548 EXISTS_TAC ``-x:real`` THEN 2549 FULL_SIMP_TAC std_ss [ABS_NEG, REAL_NEG_NEG]]); 2550 2551val NEGATIONS_CBALL = store_thm ("NEGATIONS_CBALL", 2552 ``!r. IMAGE (\x. -x) (cball(0:real,r)) = cball(0,r)``, 2553 GEN_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_CBALL_0] THEN 2554 GEN_TAC THEN EQ_TAC THENL [METIS_TAC [ABS_NEG], DISCH_TAC THEN 2555 EXISTS_TAC ``-x:real`` THEN 2556 FULL_SIMP_TAC std_ss [ABS_NEG, REAL_NEG_NEG]]); 2557 2558val NEGATIONS_SPHERE = store_thm ("NEGATIONS_SPHERE", 2559 ``!r. IMAGE (\x. -x) (sphere(0:real,r)) = sphere(0,r)``, 2560 GEN_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_SPHERE_0] THEN 2561 GEN_TAC THEN EQ_TAC THENL [METIS_TAC [ABS_NEG], DISCH_TAC THEN 2562 EXISTS_TAC ``-x:real`` THEN 2563 FULL_SIMP_TAC std_ss [ABS_NEG, REAL_NEG_NEG]]); 2564 2565(* ------------------------------------------------------------------------- *) 2566(* Basic "localization" results are handy for connectedness. *) 2567(* ------------------------------------------------------------------------- *) 2568 2569val OPEN_IN_OPEN = store_thm ("OPEN_IN_OPEN", 2570 ``!s:real->bool u. 2571 open_in (subtopology euclidean u) s <=> ?t. open t /\ (s = u INTER t)``, 2572 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [OPEN_IN_SUBTOPOLOGY, GSYM OPEN_IN] THEN 2573 SIMP_TAC std_ss [INTER_ACI]); 2574 2575val OPEN_IN_INTER_OPEN = store_thm ("OPEN_IN_INTER_OPEN", 2576 ``!s t u:real->bool. 2577 open_in (subtopology euclidean u) s /\ open t 2578 ==> open_in (subtopology euclidean u) (s INTER t)``, 2579 SIMP_TAC std_ss [OPEN_IN_OPEN] THEN REPEAT STRIP_TAC THEN 2580 ASM_MESON_TAC[INTER_ASSOC, OPEN_INTER]); 2581 2582val OPEN_IN_OPEN_INTER = store_thm ("OPEN_IN_OPEN_INTER", 2583 ``!u s. open s ==> open_in (subtopology euclidean u) (u INTER s)``, 2584 REWRITE_TAC[OPEN_IN_OPEN] THEN MESON_TAC[]); 2585 2586val OPEN_OPEN_IN_TRANS = store_thm ("OPEN_OPEN_IN_TRANS", 2587 ``!s t. open s /\ open t /\ t SUBSET s 2588 ==> open_in (subtopology euclidean s) t``, 2589 MESON_TAC[OPEN_IN_OPEN_INTER, SET_RULE ``(t:real->bool) SUBSET s ==> (t = s INTER t)``]); 2590 2591val OPEN_SUBSET = store_thm ("OPEN_SUBSET", 2592 ``!s t:real->bool. 2593 s SUBSET t /\ open s ==> open_in (subtopology euclidean t) s``, 2594 REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN 2595 EXISTS_TAC ``s:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 2596 2597val CLOSED_IN_CLOSED = store_thm ("CLOSED_IN_CLOSED", 2598 ``!s:real->bool u. 2599 closed_in (subtopology euclidean u) s <=> ?t. closed t /\ (s = u INTER t)``, 2600 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [CLOSED_IN_SUBTOPOLOGY, GSYM CLOSED_IN] THEN 2601 SIMP_TAC std_ss [INTER_ACI]); 2602 2603val CLOSED_SUBSET_EQ = store_thm ("CLOSED_SUBSET_EQ", 2604 ``!u s:real->bool. 2605 closed s ==> (closed_in (subtopology euclidean u) s <=> s SUBSET u)``, 2606 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 2607 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN 2608 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY], 2609 REWRITE_TAC[CLOSED_IN_CLOSED] THEN EXISTS_TAC ``s:real->bool`` THEN 2610 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]); 2611 2612val CLOSED_IN_INTER_CLOSED = store_thm ("CLOSED_IN_INTER_CLOSED", 2613 ``!s t u:real->bool. 2614 closed_in (subtopology euclidean u) s /\ closed t 2615 ==> closed_in (subtopology euclidean u) (s INTER t)``, 2616 SIMP_TAC std_ss [CLOSED_IN_CLOSED] THEN REPEAT STRIP_TAC THEN 2617 ASM_MESON_TAC[INTER_ASSOC, CLOSED_INTER]); 2618 2619val CLOSED_IN_CLOSED_INTER = store_thm ("CLOSED_IN_CLOSED_INTER", 2620 ``!u s. closed s ==> closed_in (subtopology euclidean u) (u INTER s)``, 2621 REWRITE_TAC[CLOSED_IN_CLOSED] THEN MESON_TAC[]); 2622 2623val CLOSED_SUBSET = store_thm ("CLOSED_SUBSET", 2624 ``!s t:real->bool. 2625 s SUBSET t /\ closed s ==> closed_in (subtopology euclidean t) s``, 2626 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN 2627 EXISTS_TAC ``s:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 2628 2629val OPEN_IN_SUBSET_TRANS = store_thm ("OPEN_IN_SUBSET_TRANS", 2630 ``!s t u:real->bool. 2631 open_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u 2632 ==> open_in (subtopology euclidean t) s``, 2633 REPEAT GEN_TAC THEN SIMP_TAC std_ss [OPEN_IN_OPEN, LEFT_EXISTS_AND_THM] THEN 2634 SET_TAC[]); 2635 2636val CLOSED_IN_SUBSET_TRANS = store_thm ("CLOSED_IN_SUBSET_TRANS", 2637 ``!s t u:real->bool. 2638 closed_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u 2639 ==> closed_in (subtopology euclidean t) s``, 2640 REPEAT GEN_TAC THEN SIMP_TAC std_ss [CLOSED_IN_CLOSED] THEN 2641 REPEAT STRIP_TAC THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 2642 2643val open_in = store_thm ("open_in", 2644 ``!u s:real->bool. 2645 open_in (subtopology euclidean u) s <=> 2646 s SUBSET u /\ 2647 !x. x IN s ==> ?e. &0 < e /\ 2648 !x'. x' IN u /\ dist(x',x) < e ==> x' IN s``, 2649 REPEAT GEN_TAC THEN 2650 SIMP_TAC std_ss [OPEN_IN_SUBTOPOLOGY, GSYM OPEN_IN] THEN EQ_TAC THENL 2651 [REWRITE_TAC[open_def] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[INTER_SUBSET, IN_INTER], 2652 ALL_TAC] THEN 2653 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN DISCH_TAC THEN 2654 FULL_SIMP_TAC std_ss [GSYM RIGHT_EXISTS_IMP_THM] THEN POP_ASSUM MP_TAC THEN 2655 SIMP_TAC std_ss [SKOLEM_THM] THEN DISCH_THEN(X_CHOOSE_TAC ``d:real->real``) THEN 2656 EXISTS_TAC ``BIGUNION {b | ?x:real. (b = ball(x,d x)) /\ x IN s}`` THEN 2657 CONJ_TAC THENL 2658 [MATCH_MP_TAC OPEN_BIGUNION THEN 2659 ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN METIS_TAC [LEFT_EXISTS_IMP_THM, OPEN_BALL], 2660 GEN_REWR_TAC I [EXTENSION] THEN 2661 SIMP_TAC std_ss [IN_INTER, IN_BIGUNION, GSPECIFICATION] THEN 2662 ASM_MESON_TAC[SUBSET_DEF, DIST_REFL, DIST_SYM, IN_BALL]]); 2663 2664val OPEN_IN_CONTAINS_BALL = store_thm ("OPEN_IN_CONTAINS_BALL", 2665 ``!s t:real->bool. 2666 open_in (subtopology euclidean t) s <=> 2667 s SUBSET t /\ 2668 !x. x IN s ==> ?e. &0 < e /\ ball(x,e) INTER t SUBSET s``, 2669 SIMP_TAC std_ss [open_in, INTER_DEF, SUBSET_DEF, GSPECIFICATION, IN_BALL] THEN 2670 MESON_TAC[DIST_SYM]); 2671 2672val OPEN_IN_CONTAINS_CBALL = store_thm ("OPEN_IN_CONTAINS_CBALL", 2673 ``!s t:real->bool. 2674 open_in (subtopology euclidean t) s <=> 2675 s SUBSET t /\ 2676 !x. x IN s ==> ?e. &0 < e /\ cball(x,e) INTER t SUBSET s``, 2677 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_CONTAINS_BALL] THEN 2678 AP_TERM_TAC THEN REWRITE_TAC[IN_BALL, IN_INTER, SUBSET_DEF, IN_CBALL] THEN 2679 MESON_TAC[METIS [REAL_LT_HALF1, REAL_LT_HALF2, REAL_LET_TRANS] 2680 ``&0 < e:real ==> &0 < e / &2 /\ (x <= e / &2 ==> x < e)``, 2681 REAL_LT_IMP_LE]); 2682 2683(* ------------------------------------------------------------------------- *) 2684(* These "transitivity" results are handy too. *) 2685(* ------------------------------------------------------------------------- *) 2686 2687val OPEN_IN_TRANS = store_thm ("OPEN_IN_TRANS", 2688 ``!s t u. open_in (subtopology euclidean t) s /\ 2689 open_in (subtopology euclidean u) t 2690 ==> open_in (subtopology euclidean u) s``, 2691 ASM_MESON_TAC[OPEN_IN_OPEN, OPEN_IN, OPEN_INTER, INTER_ASSOC]); 2692 2693val OPEN_IN_TRANS_EQ = store_thm ("OPEN_IN_TRANS_EQ", 2694 ``!s t:real->bool. 2695 (!u. open_in (subtopology euclidean t) u 2696 ==> open_in (subtopology euclidean s) t) 2697 <=> open_in (subtopology euclidean s) t``, 2698 MESON_TAC[OPEN_IN_TRANS, OPEN_IN_REFL]); 2699 2700val OPEN_IN_OPEN_TRANS = store_thm ("OPEN_IN_OPEN_TRANS", 2701 ``!s t. open_in (subtopology euclidean t) s /\ open t ==> open s``, 2702 REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] OPEN_IN] THEN 2703 REWRITE_TAC[OPEN_IN_TRANS]); 2704 2705val CLOSED_IN_TRANS = store_thm ("CLOSED_IN_TRANS", 2706 ``!s t u. closed_in (subtopology euclidean t) s /\ 2707 closed_in (subtopology euclidean u) t 2708 ==> closed_in (subtopology euclidean u) s``, 2709 ASM_MESON_TAC[CLOSED_IN_CLOSED, CLOSED_IN, CLOSED_INTER, INTER_ASSOC]); 2710 2711val CLOSED_IN_TRANS_EQ = store_thm ("CLOSED_IN_TRANS_EQ", 2712 ``!s t:real->bool. 2713 (!u. closed_in (subtopology euclidean t) u 2714 ==> closed_in (subtopology euclidean s) t) 2715 <=> closed_in (subtopology euclidean s) t``, 2716 MESON_TAC[CLOSED_IN_TRANS, CLOSED_IN_REFL]); 2717 2718val CLOSED_IN_CLOSED_TRANS = store_thm ("CLOSED_IN_CLOSED_TRANS", 2719 ``!s t. closed_in (subtopology euclidean t) s /\ closed t ==> closed s``, 2720 REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] CLOSED_IN] THEN 2721 REWRITE_TAC[CLOSED_IN_TRANS]); 2722 2723val OPEN_IN_SUBTOPOLOGY_INTER_SUBSET = store_thm ("OPEN_IN_SUBTOPOLOGY_INTER_SUBSET", 2724 ``!s u v. open_in (subtopology euclidean u) (u INTER s) /\ v SUBSET u 2725 ==> open_in (subtopology euclidean v) (v INTER s)``, 2726 REPEAT GEN_TAC THEN SIMP_TAC std_ss [OPEN_IN_OPEN, GSYM LEFT_EXISTS_AND_THM] THEN 2727 STRIP_TAC THEN EXISTS_TAC ``t:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 2728 2729val OPEN_IN_OPEN_EQ = store_thm ("OPEN_IN_OPEN_EQ", 2730 ``!s t. open s 2731 ==> (open_in (subtopology euclidean s) t <=> open t /\ t SUBSET s)``, 2732 MESON_TAC[OPEN_OPEN_IN_TRANS, OPEN_IN_OPEN_TRANS, open_in]); 2733 2734val CLOSED_IN_CLOSED_EQ = store_thm ("CLOSED_IN_CLOSED_EQ", 2735 ``!s t. closed s 2736 ==> (closed_in (subtopology euclidean s) t <=> 2737 closed t /\ t SUBSET s)``, 2738 MESON_TAC[CLOSED_SUBSET, CLOSED_IN_CLOSED_TRANS, closed_in, 2739 TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]); 2740 2741(* ------------------------------------------------------------------------- *) 2742(* Line segments, with open/closed overloading of (a,b) and [a,b]. *) 2743(* ------------------------------------------------------------------------- *) 2744 2745val closed_segment = new_definition ("closed_segment", 2746 ``closed_segment (l:(real#real)list) = 2747 {((&1:real) - u) * FST(HD l) + u * SND(HD l) | &0 <= u /\ u <= &1}``); 2748 2749val open_segment = new_definition ("open_segment", 2750 ``open_segment(a,b) = closed_segment[a,b] DIFF {a;b}``); 2751 2752val OPEN_SEGMENT_ALT = store_thm ("OPEN_SEGMENT_ALT", 2753 ``!a b:real. 2754 ~(a = b) 2755 ==> (open_segment(a,b) = {(&1 - u) * a + u * b | &0 < u /\ u < &1:real})``, 2756 REPEAT STRIP_TAC THEN REWRITE_TAC[open_segment, closed_segment, FST, SND, HD] THEN 2757 SIMP_TAC std_ss [EXTENSION, IN_DIFF, IN_INSERT, NOT_IN_EMPTY, GSPECIFICATION] THEN 2758 X_GEN_TAC ``x:real`` THEN SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM] THEN 2759 AP_TERM_TAC THEN SIMP_TAC std_ss [FUN_EQ_THM] THEN 2760 X_GEN_TAC ``u:real`` THEN ASM_CASES_TAC ``x:real = (&1 - u) * a + u * b`` THEN 2761 ASM_REWRITE_TAC[REAL_LE_LT, 2762 REAL_ARITH ``((&1 - u) * a + u * b = a) <=> (u * (b - a) = 0:real)``, 2763 REAL_ARITH ``((&1 - u) * a + u * b = b) <=> ((&1 - u) * (b - a) = 0:real)``, 2764 REAL_ENTIRE, REAL_SUB_0] THEN UNDISCH_TAC ``a <> b:real`` THEN DISCH_TAC THEN 2765 POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN DISCH_TAC THEN 2766 ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC); 2767 2768val _ = overload_on ("segment", ``open_segment``); 2769val _ = overload_on ("segment", ``closed_segment``); 2770 2771val segment = store_thm ("segment", 2772 ``(segment[a,b] = {(&1 - u) * a + u * b | &0 <= u /\ u <= &1:real}) /\ 2773 (segment(a,b) = segment[a,b] DIFF {a;b:real})``, 2774 REWRITE_TAC[open_segment, closed_segment, HD]); 2775 2776val SEGMENT_REFL = store_thm ("SEGMENT_REFL", 2777 ``(!a. segment[a,a] = {a}) /\ 2778 (!a. segment(a,a) = {})``, 2779 REWRITE_TAC[segment, REAL_ARITH ``(&1 - u) * a + u * a = a:real``] THEN 2780 CONJ_TAC THENL [ALL_TAC, SET_TAC[REAL_POS]] THEN 2781 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION] THEN REPEAT GEN_TAC THEN 2782 EQ_TAC THEN REWRITE_TAC [IN_SING] THENL [METIS_TAC [], ALL_TAC] THEN DISCH_TAC THEN 2783 ASM_REWRITE_TAC [] THEN EXISTS_TAC ``1:real`` THEN REAL_ARITH_TAC); 2784 2785val IN_SEGMENT = store_thm ("IN_SEGMENT", 2786 ``!a b x:real. 2787 ((x IN segment[a,b] <=> 2788 ?u. &0 <= u /\ u <= &1 /\ (x = (&1 - u) * a + u * b:real))) /\ 2789 ((x IN segment(a,b) <=> 2790 ~(a = b) /\ ?u. &0 < u /\ u < &1 /\ (x = (&1 - u) * a + u * b:real)))``, 2791 REPEAT STRIP_TAC THENL 2792 [SIMP_TAC std_ss [segment, GSPECIFICATION, CONJ_ASSOC], ALL_TAC] THEN 2793 ASM_CASES_TAC ``a:real = b`` THEN 2794 ASM_REWRITE_TAC[SEGMENT_REFL, NOT_IN_EMPTY] THEN 2795 ASM_SIMP_TAC std_ss [OPEN_SEGMENT_ALT, GSPECIFICATION, CONJ_ASSOC] THEN METIS_TAC []); 2796 2797val SEGMENT_SYM = store_thm ("SEGMENT_SYM", 2798 ``(!a b:real. segment[a,b] = segment[b,a]) /\ 2799 (!a b:real. segment(a,b) = segment(b,a))``, 2800 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN 2801 SIMP_TAC std_ss [open_segment] THEN 2802 CONJ_TAC THENL [ALL_TAC, SIMP_TAC std_ss [INSERT_COMM, INSERT_INSERT]] THEN 2803 REWRITE_TAC[EXTENSION, IN_SEGMENT] THEN REPEAT GEN_TAC THEN EQ_TAC THEN 2804 DISCH_THEN(X_CHOOSE_TAC ``u:real``) THEN EXISTS_TAC ``&1 - u:real`` THEN 2805 ASM_REWRITE_TAC[] THEN 2806 REPEAT CONJ_TAC THEN TRY ASM_ARITH_TAC THEN ASM_REAL_ARITH_TAC); 2807 2808val ENDS_IN_SEGMENT = store_thm ("ENDS_IN_SEGMENT", 2809 ``!a b. a IN segment[a,b] /\ b IN segment[a,b]``, 2810 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [segment, GSPECIFICATION] THENL 2811 [EXISTS_TAC ``&0:real``, EXISTS_TAC ``&1:real``] THEN 2812 (CONJ_TAC THENL [REAL_ARITH_TAC, REAL_ARITH_TAC])); 2813 2814val ENDS_NOT_IN_SEGMENT = store_thm ("ENDS_NOT_IN_SEGMENT", 2815 ``!a b. ~(a IN segment(a,b)) /\ ~(b IN segment(a,b))``, 2816 REWRITE_TAC[open_segment] THEN SET_TAC[]); 2817 2818val SEGMENT_CLOSED_OPEN = store_thm ("SEGMENT_CLOSED_OPEN", 2819 ``!a b. segment[a,b] = segment(a,b) UNION {a;b}``, 2820 REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN MATCH_MP_TAC(SET_RULE 2821 ``a IN s /\ b IN s ==> (s = (s DIFF {a;b}) UNION {a;b})``) THEN 2822 REWRITE_TAC[ENDS_IN_SEGMENT]); 2823 2824val SEGMENT_OPEN_SUBSET_CLOSED = store_thm ("SEGMENT_OPEN_SUBSET_CLOSED", 2825 ``!a b. segment(a,b) SUBSET segment[a,b]``, 2826 REWRITE_TAC[CONJUNCT2(SPEC_ALL segment)] THEN SET_TAC[]); 2827 2828val MIDPOINT_IN_SEGMENT = store_thm ("MIDPOINT_IN_SEGMENT", 2829 ``(!a b:real. midpoint(a,b) IN segment[a,b]) /\ 2830 (!a b:real. midpoint(a,b) IN segment(a,b) <=> ~(a = b))``, 2831 REWRITE_TAC[IN_SEGMENT] THEN REPEAT STRIP_TAC THENL 2832 [ALL_TAC, ASM_CASES_TAC ``a:real = b`` THEN ASM_REWRITE_TAC[]] THEN 2833 EXISTS_TAC ``&1 / &2:real`` THEN REWRITE_TAC[midpoint] THEN 2834 REWRITE_TAC [REAL_HALF_BETWEEN] THEN 2835 REWRITE_TAC [METIS [REAL_HALF_DOUBLE, REAL_EQ_SUB_RADD] 2836 ``1 - 1 / 2 = 1 / 2:real``] THEN REWRITE_TAC [GSYM REAL_LDISTRIB] THEN 2837 REWRITE_TAC [REAL_INV_1OVER]); 2838 2839val BETWEEN_IN_SEGMENT = store_thm ("BETWEEN_IN_SEGMENT", 2840 ``!x a b:real. between x (a,b) <=> x IN segment[a,b]``, 2841 REPEAT GEN_TAC THEN REWRITE_TAC[between] THEN 2842 ASM_CASES_TAC ``a:real = b`` THEN 2843 ASM_REWRITE_TAC[SEGMENT_REFL, IN_SING] THENL 2844 [REWRITE_TAC [dist] THEN REAL_ARITH_TAC, ALL_TAC] THEN 2845 SIMP_TAC std_ss [segment, GSPECIFICATION] THEN EQ_TAC THENL 2846 [DISCH_THEN(ASSUME_TAC o SYM) THEN 2847 EXISTS_TAC ``dist(a:real,x) / dist(a,b)`` THEN 2848 ASM_SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ, DIST_POS_LT] THEN CONJ_TAC 2849 THENL [FIRST_ASSUM(SUBST1_TAC o SYM) THEN 2850 ASM_REWRITE_TAC [dist] THEN REWRITE_TAC [REAL_SUB_RDISTRIB, REAL_MUL_LID] THEN 2851 ONCE_REWRITE_TAC [REAL_ARITH ``(x = a - y + z) = (y - z = a - x:real)``] THEN 2852 REWRITE_TAC [GSYM REAL_SUB_LDISTRIB] THEN KNOW_TAC ``(a - b:real) <> 0`` THENL 2853 [ASM_REAL_ARITH_TAC, DISCH_TAC] THEN ASM_SIMP_TAC std_ss [GSYM ABS_DIV] THEN 2854 Cases_on `0 < a - b:real` THENL 2855 [ASM_SIMP_TAC std_ss [GSYM REAL_EQ_RDIV_EQ] THEN REWRITE_TAC [ABS_REFL] THEN 2856 ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_MUL_LZERO] THEN 2857 FULL_SIMP_TAC std_ss [dist] THEN ASM_REAL_ARITH_TAC, 2858 FULL_SIMP_TAC std_ss [REAL_NOT_LT, REAL_LE_LT] THENL 2859 [ALL_TAC, ASM_REAL_ARITH_TAC] THEN 2860 POP_ASSUM MP_TAC THEN GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_LT_NEG] THEN 2861 ONCE_REWRITE_TAC [REAL_ARITH ``(-0 = 0:real) /\ (-(a - b) = (b - a:real))``] THEN 2862 DISCH_TAC THEN ONCE_REWRITE_TAC [REAL_ARITH ``((a - b) = -(b - a:real))``] THEN 2863 ONCE_ASM_REWRITE_TAC [REAL_ARITH ``a * -b = -a * b:real``] THEN 2864 ASM_SIMP_TAC std_ss [GSYM REAL_EQ_RDIV_EQ] THEN REWRITE_TAC [real_div] THEN 2865 ONCE_REWRITE_TAC [REAL_ARITH ``(-a * b = -(a * b:real))``] THEN 2866 REWRITE_TAC [REAL_EQ_NEG] THEN KNOW_TAC ``(b - a:real) <> 0`` THENL 2867 [ASM_REAL_ARITH_TAC, DISCH_TAC] THEN ASM_SIMP_TAC std_ss [GSYM REAL_NEG_INV] THEN 2868 ONCE_REWRITE_TAC [REAL_ARITH ``(-(a * b) = (a * -b:real))``] THEN 2869 FULL_SIMP_TAC std_ss [REAL_NEG_NEG, dist] THEN 2870 REWRITE_TAC [ABS_REFL, GSYM real_div] THEN 2871 ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_MUL_LZERO] THEN 2872 ASM_REAL_ARITH_TAC], ALL_TAC] THEN FULL_SIMP_TAC std_ss [dist] THEN 2873 ASM_REAL_ARITH_TAC, ALL_TAC] THEN 2874 STRIP_TAC THEN ASM_REWRITE_TAC[dist] THEN 2875 SIMP_TAC std_ss [REAL_ARITH ``a - ((&1 - u) * a + u * b) = u * (a - b:real)``, 2876 REAL_ARITH ``((&1 - u) * a + u * b) - b = (&1 - u) * (a - b:real)``, 2877 ABS_MUL, GSYM REAL_ADD_RDISTRIB] THEN 2878 FULL_SIMP_TAC std_ss [REAL_ARITH ``u <= 1 <=> 0 <= 1 - u:real``, GSYM ABS_REFL] THEN 2879 REAL_ARITH_TAC); 2880 2881val REAL_CONVEX_BOUND_LE = store_thm ("REAL_CONVEX_BOUND_LE", 2882 ``!x y a u v. x <= a /\ y <= a /\ &0 <= u /\ &0 <= v /\ (u + v = &1:real) 2883 ==> u * x + v * y <= a:real``, 2884 REPEAT STRIP_TAC THEN 2885 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``(u + v) * a:real`` THEN 2886 CONJ_TAC THENL [ALL_TAC, ASM_SIMP_TAC std_ss [REAL_LE_REFL, REAL_MUL_LID]] THEN 2887 ASM_SIMP_TAC std_ss [REAL_ADD_RDISTRIB] THEN MATCH_MP_TAC REAL_LE_ADD2 THEN 2888 UNDISCH_TAC ``0 <= v:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_LE_LT] THEN 2889 STRIP_TAC THEN UNDISCH_TAC ``0 <= u:real`` THEN 2890 GEN_REWR_TAC LAND_CONV [REAL_LE_LT] THEN STRIP_TAC THEN 2891 ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 2892 POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN DISCH_TAC THEN 2893 DISCH_TAC THEN ASM_REWRITE_TAC [REAL_LE_LT, REAL_MUL_LZERO]); 2894 2895val IN_SEGMENT_COMPONENT = store_thm ("IN_SEGMENT_COMPONENT", 2896 ``!a b x:real i. x IN segment[a,b] 2897 ==> min (a) (b) <= x /\ x <= max (a) (b)``, 2898 REPEAT STRIP_TAC THEN 2899 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [IN_SEGMENT]) THEN 2900 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 2901 FIRST_X_ASSUM(X_CHOOSE_THEN ``t:real`` STRIP_ASSUME_TAC) THEN 2902 ASM_REWRITE_TAC [] THEN 2903 SIMP_TAC std_ss [REAL_ARITH ``c <= u * a + t * b <=> u * -a + t * -b <= -c:real``] THEN 2904 MATCH_MP_TAC REAL_CONVEX_BOUND_LE THEN 2905 RW_TAC real_ss [] THEN 2906 ASM_REAL_ARITH_TAC); 2907 2908val SEGMENT_TRANSLATION = store_thm ("SEGMENT_TRANSLATION", 2909 ``(!c a b. segment[c + a,c + b] = IMAGE (\x. c + x) (segment[a,b])) /\ 2910 (!c a b. segment(c + a,c + b) = IMAGE (\x. c + x) (segment(a,b)))``, 2911 SIMP_TAC std_ss [EXTENSION, IN_SEGMENT, IN_IMAGE] THEN 2912 SIMP_TAC std_ss [REAL_ARITH ``(&1 - u) * (c + a) + u * (c + b) = 2913 c + (&1 - u) * a + u * b:real``] THEN 2914 SIMP_TAC std_ss [REAL_ARITH ``(c + a:real = c + b) <=> (a = b)``] THEN 2915 CONJ_TAC THEN 2916 (REPEAT GEN_TAC THEN EQ_TAC THENL 2917 [REPEAT STRIP_TAC THEN EXISTS_TAC ``(1 - u) * a + u * b:real`` THEN 2918 ASM_SIMP_TAC std_ss [REAL_ADD_ASSOC] THEN EXISTS_TAC ``u:real`` THEN 2919 ASM_SIMP_TAC std_ss [], 2920 REPEAT STRIP_TAC THEN EXISTS_TAC ``u:real`` THEN 2921 ASM_SIMP_TAC std_ss [REAL_ADD_ASSOC]])); 2922 2923val CLOSED_SEGMENT_LINEAR_IMAGE = store_thm ("CLOSED_SEGMENT_LINEAR_IMAGE", 2924 ``!f a b. linear f 2925 ==> (segment[f a,f b] = IMAGE f (segment[a,b]))``, 2926 REPEAT STRIP_TAC THEN REWRITE_TAC[EXTENSION, IN_IMAGE, IN_SEGMENT] THEN 2927 FIRST_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN 2928 FIRST_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_ADD th)]) THEN 2929 MESON_TAC[]); 2930 2931val OPEN_SEGMENT_LINEAR_IMAGE = store_thm ("OPEN_SEGMENT_LINEAR_IMAGE", 2932 ``!f:real->real a b. 2933 linear f /\ (!x y. (f x = f y) ==> (x = y)) 2934 ==> (segment(f a,f b) = IMAGE f (segment(a,b)))``, 2935 REWRITE_TAC[open_segment, closed_segment, FST, SND, HD] THEN 2936 SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION, IN_DIFF] THEN 2937 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL 2938 [EXISTS_TAC ``(1 - u) * a + u * b:real`` THEN 2939 CONJ_TAC THENL [METIS_TAC [], ALL_TAC] THEN 2940 CONJ_TAC THENL [EXISTS_TAC ``u:real`` THEN ASM_REWRITE_TAC [], ALL_TAC] THEN 2941 ASM_SET_TAC [], 2942 CONJ_TAC THENL [EXISTS_TAC ``u:real`` THEN METIS_TAC [], ALL_TAC] THEN 2943 ASM_SET_TAC []]); 2944 2945val IN_OPEN_SEGMENT = store_thm ("IN_OPEN_SEGMENT", 2946 ``!a b x:real. 2947 x IN segment(a,b) <=> x IN segment[a,b] /\ ~(x = a) /\ ~(x = b)``, 2948 REPEAT GEN_TAC THEN REWRITE_TAC[open_segment, IN_DIFF] THEN SET_TAC[]); 2949 2950val IN_OPEN_SEGMENT_ALT = store_thm ("IN_OPEN_SEGMENT_ALT", 2951 ``!a b x:real. 2952 x IN segment(a,b) <=> 2953 x IN segment[a,b] /\ ~(x = a) /\ ~(x = b) /\ ~(a = b)``, 2954 REPEAT GEN_TAC THEN ASM_CASES_TAC ``a:real = b`` THEN 2955 ASM_REWRITE_TAC[SEGMENT_REFL, IN_SING, NOT_IN_EMPTY] THEN 2956 ASM_MESON_TAC[IN_OPEN_SEGMENT]); 2957 2958val COLLINEAR_DIST_IN_CLOSED_SEGMENT = store_thm ("COLLINEAR_DIST_IN_CLOSED_SEGMENT", 2959 ``!a b x. collinear {x;a;b} /\ 2960 dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b) 2961 ==> x IN segment[a,b]``, 2962 REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT, COLLINEAR_DIST_BETWEEN]); 2963 2964val COLLINEAR_DIST_IN_OPEN_SEGMENT = store_thm ("COLLINEAR_DIST_IN_OPEN_SEGMENT", 2965 ``!a b x. collinear {x;a;b} /\ 2966 dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b) 2967 ==> x IN segment(a,b)``, 2968 REWRITE_TAC[IN_OPEN_SEGMENT] THEN 2969 METIS_TAC[COLLINEAR_DIST_IN_CLOSED_SEGMENT, REAL_LT_LE, DIST_SYM]); 2970 2971val DIST_IN_OPEN_CLOSED_SEGMENT = store_thm ("DIST_IN_OPEN_CLOSED_SEGMENT", 2972 ``(!a b x:real. 2973 x IN segment[a,b] ==> dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)) /\ 2974 (!a b x:real. 2975 x IN segment(a,b) ==> dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b))``, 2976 SIMP_TAC std_ss [IN_SEGMENT, GSYM RIGHT_EXISTS_AND_THM, LEFT_IMP_EXISTS_THM, dist, 2977 REAL_ARITH 2978 ``(((&1 - u) * a + u * b) - a:real = u * (b - a)) /\ 2979 (((&1 - u) * a + u * b) - b = -(&1 - u) * (b - a))``] THEN 2980 REWRITE_TAC[ABS_MUL, ABS_NEG] THEN ONCE_REWRITE_TAC [ABS_SUB] THEN CONJ_TAC THEN 2981 REPEAT GEN_TAC THEN STRIP_TAC THENL 2982 [ONCE_REWRITE_TAC [REAL_ARITH 2983 ``x * y <= abs (b - a) <=> x * y <= abs (a - b:real)``] THEN 2984 REWRITE_TAC[REAL_ARITH ``x * y <= y <=> x * y <= &1 * y:real``] THEN 2985 CONJ_TAC THEN MATCH_MP_TAC REAL_LE_RMUL_IMP THEN 2986 REWRITE_TAC[ABS_POS] THEN ASM_REAL_ARITH_TAC, 2987 ONCE_REWRITE_TAC [REAL_ARITH 2988 ``x * y < abs (b - a) <=> x * y < abs (a - b:real)``] THEN 2989 REWRITE_TAC[REAL_ARITH ``x * y < y <=> x * y < &1 * y:real``] THEN 2990 CONJ_TAC THEN MATCH_MP_TAC REAL_LT_RMUL_IMP THEN 2991 ASM_REAL_ARITH_TAC]); 2992 2993val DIST_IN_CLOSED_SEGMENT = store_thm ("DIST_IN_CLOSED_SEGMENT", 2994 ``(!a b x:real. 2995 x IN segment[a,b] ==> dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b))``, 2996 REWRITE_TAC [DIST_IN_OPEN_CLOSED_SEGMENT]); 2997 2998val DIST_IN_OPEN_SEGMENT = store_thm ("DIST_IN_OPEN_SEGMENT", 2999 ``(!a b x:real. 3000 x IN segment(a,b) ==> dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b))``, 3001 REWRITE_TAC [DIST_IN_OPEN_CLOSED_SEGMENT]); 3002 3003(* ------------------------------------------------------------------------- *) 3004(* Connectedness. *) 3005(* ------------------------------------------------------------------------- *) 3006 3007val connected = new_definition ("connected", 3008 ``connected s <=> 3009 ~(?e1 e2. open e1 /\ open e2 /\ s SUBSET (e1 UNION e2) /\ 3010 (e1 INTER e2 INTER s = {}) /\ 3011 ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))``); 3012 3013val CONNECTED_CLOSED = store_thm ("CONNECTED_CLOSED", 3014 ``!s:real->bool. 3015 connected s <=> 3016 ~(?e1 e2. closed e1 /\ closed e2 /\ s SUBSET (e1 UNION e2) /\ 3017 (e1 INTER e2 INTER s = {}) /\ 3018 ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))``, 3019 GEN_TAC THEN REWRITE_TAC[connected] THEN AP_TERM_TAC THEN 3020 EQ_TAC THEN STRIP_TAC THEN 3021 MAP_EVERY EXISTS_TAC [``univ(:real) DIFF e1``, ``univ(:real) DIFF e2``] THEN 3022 ASM_REWRITE_TAC[GSYM closed_def, GSYM OPEN_CLOSED] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 3023 3024val CONNECTED_OPEN_IN = store_thm ("CONNECTED_OPEN_IN", 3025 ``!s. connected s <=> 3026 ~(?e1 e2. 3027 open_in (subtopology euclidean s) e1 /\ 3028 open_in (subtopology euclidean s) e2 /\ 3029 s SUBSET e1 UNION e2 /\ 3030 (e1 INTER e2 = {}) /\ 3031 ~(e1 = {}) /\ 3032 ~(e2 = {}))``, 3033 GEN_TAC THEN REWRITE_TAC[connected, OPEN_IN_OPEN] THEN 3034 SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM] THEN 3035 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN SET_TAC[]); 3036 3037val CONNECTED_OPEN_IN_EQ = store_thm ("CONNECTED_OPEN_IN_EQ", 3038 ``!s. connected s <=> 3039 ~(?e1 e2. 3040 open_in (subtopology euclidean s) e1 /\ 3041 open_in (subtopology euclidean s) e2 /\ 3042 (e1 UNION e2 = s) /\ (e1 INTER e2 = {}) /\ 3043 ~(e1 = {}) /\ ~(e2 = {}))``, 3044 GEN_TAC THEN REWRITE_TAC[CONNECTED_OPEN_IN] THEN 3045 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN 3046 EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN 3047 RULE_ASSUM_TAC(REWRITE_RULE[OPEN_IN_CLOSED_IN_EQ, 3048 TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN 3049 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 3050 3051val CONNECTED_CLOSED_IN = store_thm ("CONNECTED_CLOSED_IN", 3052 ``!s. connected s <=> 3053 ~(?e1 e2. 3054 closed_in (subtopology euclidean s) e1 /\ 3055 closed_in (subtopology euclidean s) e2 /\ 3056 s SUBSET e1 UNION e2 /\ 3057 (e1 INTER e2 = {}) /\ 3058 ~(e1 = {}) /\ 3059 ~(e2 = {}))``, 3060 GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED, CLOSED_IN_CLOSED] THEN 3061 SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM] THEN 3062 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN SET_TAC[]); 3063 3064val CONNECTED_CLOSED_IN_EQ = store_thm ("CONNECTED_CLOSED_IN_EQ", 3065 ``!s. connected s <=> 3066 ~(?e1 e2. 3067 closed_in (subtopology euclidean s) e1 /\ 3068 closed_in (subtopology euclidean s) e2 /\ 3069 (e1 UNION e2 = s) /\ (e1 INTER e2 = {}) /\ 3070 ~(e1 = {}) /\ ~(e2 = {}))``, 3071 GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED_IN] THEN 3072 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN 3073 EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN 3074 RULE_ASSUM_TAC(REWRITE_RULE[closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN 3075 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 3076 3077val EXISTS_DIFF = store_thm ("EXISTS_DIFF", 3078 ``(?s:'a->bool. P(UNIV DIFF s)) <=> (?s. P s)``, 3079 MESON_TAC[prove(``UNIV DIFF (UNIV DIFF s) = s``,SET_TAC[])]); 3080 3081val CONNECTED_CLOPEN = store_thm ("CONNECTED_CLOPEN", 3082 ``!s. connected s <=> 3083 !t. open_in (subtopology euclidean s) t /\ 3084 closed_in (subtopology euclidean s) t ==> (t = {}) \/ (t = s)``, 3085 GEN_TAC THEN REWRITE_TAC[connected, OPEN_IN_OPEN, CLOSED_IN_CLOSED] THEN 3086 REWRITE_TAC [METIS [GSYM EXISTS_DIFF] ``!e1. (?e2. open e2) <=> 3087 ?e2. open (univ(:real) DIFF e2)``] THEN 3088 KNOW_TAC ``(?e1 e2. open e1 /\ open e2 /\ s SUBSET e1 UNION e2 /\ 3089 (e1 INTER e2 INTER s = {}) /\ e1 INTER s <> {} /\ 3090 e2 INTER s <> {}) <=> 3091 (?e1 e2. open e1 /\ open (univ(:real) DIFF e2) /\ 3092 s SUBSET e1 UNION (univ(:real) DIFF e2) /\ 3093 (e1 INTER (univ(:real) DIFF e2) INTER s = {}) /\ e1 INTER s <> {} /\ 3094 (univ(:real) DIFF e2) INTER s <> {})`` THENL 3095 [EQ_TAC THENL [STRIP_TAC THEN EXISTS_TAC ``e1:real->bool`` THEN 3096 ASM_SIMP_TAC std_ss [EXISTS_DIFF] THEN METIS_TAC [], 3097 METIS_TAC [GSYM EXISTS_DIFF]], ALL_TAC] THEN DISC_RW_KILL THEN 3098 ONCE_REWRITE_TAC[TAUT `(~a <=> b) <=> (a <=> ~b)`] THEN 3099 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, GSYM CONJ_ASSOC, DE_MORGAN_THM] THEN 3100 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> b /\ a /\ c /\ d`] THEN 3101 KNOW_TAC ``(?t. (?t'. closed t' /\ (t = s INTER t')) /\ 3102 (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s) <=> 3103 (?t t'. (closed t' /\ (t = s INTER t')) /\ 3104 (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s)`` THENL 3105 [SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM], ALL_TAC] THEN DISC_RW_KILL THEN 3106 REWRITE_TAC [GSYM closed_def] THEN 3107 KNOW_TAC ``((?e1 e2. closed e2 /\ open e1 /\ s SUBSET e1 UNION (univ(:real) DIFF e2) /\ 3108 (e1 INTER (univ(:real) DIFF e2) INTER s = {}) /\ e1 INTER s <> {} /\ 3109 (univ(:real) DIFF e2) INTER s <> {}) <=> ?t t'. (closed t' /\ (t = s INTER t')) /\ 3110 (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s) <=> 3111 ((?e2 e1. closed e2 /\ open e1 /\ s SUBSET e1 UNION (univ(:real) DIFF e2) /\ 3112 (e1 INTER (univ(:real) DIFF e2) INTER s = {}) /\ e1 INTER s <> {} /\ 3113 (univ(:real) DIFF e2) INTER s <> {}) <=> ?t' t. (closed t' /\ (t = s INTER t')) /\ 3114 (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s)`` THENL 3115 [METIS_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN AP_TERM_TAC THEN ABS_TAC THEN 3116 KNOW_TAC ``(?t. (closed e2 /\ (t = s INTER e2)) /\ 3117 (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s) <=> 3118 (?t' t.(closed e2 /\ (t = s INTER e2)) /\ 3119 (open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s)`` THENL 3120 [METIS_TAC [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM], ALL_TAC] THEN 3121 DISC_RW_KILL THEN AP_TERM_TAC THEN ABS_TAC THEN 3122 REWRITE_TAC[TAUT `(a /\ b) /\ (c /\ d) /\ e <=> a /\ c /\ b /\ d /\ e`] THEN 3123 SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN 3124 AP_TERM_TAC THEN AP_TERM_TAC THEN SET_TAC[]); 3125 3126val CONNECTED_CLOSED_SET = store_thm ("CONNECTED_CLOSED_SET", 3127 ``!s:real->bool. 3128 closed s 3129 ==> (connected s <=> 3130 ~(?e1 e2. closed e1 /\ closed e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\ 3131 (e1 UNION e2 = s) /\ (e1 INTER e2 = {})))``, 3132 REPEAT STRIP_TAC THEN EQ_TAC THENL 3133 [REWRITE_TAC [CONNECTED_CLOSED, GSYM MONO_NOT_EQ] THEN 3134 STRIP_TAC THEN EXISTS_TAC ``e1:real->bool`` THEN 3135 EXISTS_TAC ``e2:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN 3136 REWRITE_TAC [AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN 3137 SIMP_TAC std_ss [] THEN SET_TAC[], 3138 REWRITE_TAC [CONNECTED_CLOSED_IN, GSYM MONO_NOT_EQ] THEN 3139 SIMP_TAC std_ss [PULL_EXISTS] THEN 3140 SIMP_TAC std_ss [CLOSED_IN_CLOSED, LEFT_IMP_EXISTS_THM, GSYM AND_IMP_INTRO] THEN 3141 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 3142 REWRITE_TAC[AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN 3143 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 3144 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 3145 [``s INTER u:real->bool``, ``s INTER v:real->bool``] THEN 3146 ASM_SIMP_TAC std_ss [CLOSED_INTER] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]); 3147 3148val CONNECTED_OPEN_SET = store_thm ("CONNECTED_OPEN_SET", 3149 ``!s:real->bool. 3150 open s 3151 ==> (connected s <=> 3152 ~(?e1 e2. open e1 /\ open e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\ 3153 (e1 UNION e2 = s) /\ (e1 INTER e2 = {})))``, 3154 REPEAT STRIP_TAC THEN EQ_TAC THENL 3155 [REWRITE_TAC[connected, GSYM MONO_NOT_EQ] THEN 3156 STRIP_TAC THEN EXISTS_TAC ``e1:real->bool`` THEN 3157 EXISTS_TAC ``e2:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN 3158 REWRITE_TAC [AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN 3159 SIMP_TAC std_ss [] THEN SET_TAC[], 3160 REWRITE_TAC [CONNECTED_OPEN_IN, GSYM MONO_NOT_EQ] THEN 3161 SIMP_TAC std_ss [PULL_EXISTS] THEN 3162 SIMP_TAC std_ss [OPEN_IN_OPEN, LEFT_IMP_EXISTS_THM, GSYM AND_IMP_INTRO] THEN 3163 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 3164 REWRITE_TAC[AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN 3165 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 3166 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 3167 [``s INTER u:real->bool``, ``s INTER v:real->bool``] THEN 3168 ASM_SIMP_TAC std_ss [OPEN_INTER] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]); 3169 3170val CONNECTED_IFF_CONNECTABLE_POINTS = store_thm ("CONNECTED_IFF_CONNECTABLE_POINTS", 3171 ``!s:real->bool. 3172 connected s <=> 3173 !a b. a IN s /\ b IN s 3174 ==> ?t. connected t /\ t SUBSET s /\ a IN t /\ b IN t``, 3175 GEN_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSET_REFL], DISCH_TAC] THEN 3176 SIMP_TAC std_ss [connected, NOT_EXISTS_THM] THEN 3177 MAP_EVERY X_GEN_TAC [``e1:real->bool``, ``e2:real->bool``] THEN 3178 REWRITE_TAC [METIS [DE_MORGAN_THM] 3179 ``~a \/ ~b \/ ~c \/ (d <> e) \/ (f = g) \/ (h = i) <=> 3180 ~(a /\ b /\ c /\ (d = e) /\ (f <> g) /\ (h <> i))``] THEN 3181 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 3182 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 3183 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 3184 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 3185 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER] THEN DISCH_THEN(CONJUNCTS_THEN2 3186 (X_CHOOSE_TAC ``a:real``) (X_CHOOSE_TAC ``b:real``)) THEN 3187 FIRST_X_ASSUM(MP_TAC o SPECL [``a:real``, ``b:real``]) THEN 3188 ASM_REWRITE_TAC[connected] THEN 3189 DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN 3190 REWRITE_TAC[] THEN 3191 MAP_EVERY EXISTS_TAC [``e1:real->bool``, ``e2:real->bool``] THEN 3192 ASM_SET_TAC[]); 3193 3194val CONNECTED_EMPTY = store_thm ("CONNECTED_EMPTY", 3195 ``connected {}``, 3196 REWRITE_TAC[connected, INTER_EMPTY]); 3197 3198val CONNECTED_SING = store_thm ("CONNECTED_SING", 3199 ``!a. connected{a}``, 3200 REWRITE_TAC[connected] THEN SET_TAC[]); 3201 3202val CONNECTED_REAL_LEMMA = store_thm ("CONNECTED_REAL_LEMMA", 3203 ``!f:real->real a b e1 e2. 3204 a <= b /\ f(a) IN e1 /\ f(b) IN e2 /\ 3205 (!e x. a <= x /\ x <= b /\ &0 < e 3206 ==> ?d. &0 < d /\ 3207 !y. abs(y - x) < d ==> dist(f(y),f(x)) < e) /\ 3208 (!y. y IN e1 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e1) /\ 3209 (!y. y IN e2 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e2) /\ 3210 ~(?x. a <= x /\ x <= b /\ f(x) IN e1 /\ f(x) IN e2) 3211 ==> ?x. a <= x /\ x <= b /\ ~(f(x) IN e1) /\ ~(f(x) IN e2)``, 3212 REWRITE_TAC[EXTENSION, NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN 3213 MP_TAC(SPEC ``\c. !x:real. a <= x /\ x <= c ==> (f(x):real) IN e1`` 3214 REAL_COMPLETE) THEN 3215 SIMP_TAC std_ss [] THEN 3216 KNOW_TAC ``(?x:real. !x'. a <= x' /\ x' <= x ==> (f x'):real IN e1) /\ 3217 (?M. !x. (!x'. a <= x' /\ x' <= x ==> f x' IN e1) ==> x <= M)`` THENL 3218 [METIS_TAC[REAL_LT_IMP_LE, REAL_LE_TOTAL, REAL_LE_ANTISYM], 3219 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 3220 DISCH_THEN (X_CHOOSE_TAC ``x:real``) THEN EXISTS_TAC ``x:real`` THEN 3221 POP_ASSUM MP_TAC THEN STRIP_TAC THEN 3222 SUBGOAL_THEN ``a <= x /\ x <= b:real`` STRIP_ASSUME_TAC THENL 3223 [METIS_TAC[REAL_LT_IMP_LE, REAL_LE_TOTAL, REAL_LE_ANTISYM], ALL_TAC] THEN 3224 ASM_REWRITE_TAC[] THEN 3225 SUBGOAL_THEN ``!z:real. a <= z /\ z < x ==> (f(z):real) IN e1`` ASSUME_TAC THENL 3226 [METIS_TAC[REAL_NOT_LT, REAL_LT_IMP_LE], ALL_TAC] THEN 3227 REPEAT STRIP_TAC THENL 3228 [SUBGOAL_THEN 3229 ``?d:real. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real) IN e1`` 3230 STRIP_ASSUME_TAC THENL [METIS_TAC[], ALL_TAC] THEN 3231 METIS_TAC[REAL_ARITH ``z <= x + e /\ e < d ==> z < x \/ abs(z - x) < d:real``, 3232 REAL_ARITH ``&0 < e ==> ~(x + e <= x:real)``, REAL_DOWN], 3233 SUBGOAL_THEN 3234 ``?d:real. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real) IN e2`` 3235 STRIP_ASSUME_TAC THENL [METIS_TAC[], ALL_TAC] THEN 3236 MP_TAC(SPECL [``x - a:real``, ``d:real``] REAL_DOWN2) THEN 3237 KNOW_TAC ``0 < x - a:real /\ 0 < d:real`` THENL 3238 [METIS_TAC[REAL_LT_LE, REAL_SUB_LT], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 3239 METIS_TAC[REAL_ARITH ``e < x - a ==> a <= x - e:real``, 3240 REAL_ARITH ``&0 < e /\ x <= b ==> x - e <= b:real``, 3241 REAL_ARITH ``&0 < e /\ e < d ==> x - e < x /\ abs((x - e) - x) < d:real``]]); 3242 3243val CONNECTED_SEGMENT = store_thm ("CONNECTED_SEGMENT", 3244 ``(!a b:real. connected(segment[a,b])) /\ 3245 (!a b:real. connected(segment(a,b)))``, 3246 CONJ_TAC THEN REPEAT GEN_TAC THENL 3247 [ASM_CASES_TAC ``b:real = a`` THEN 3248 ASM_SIMP_TAC std_ss [SEGMENT_REFL, CONNECTED_EMPTY, CONNECTED_SING] THEN 3249 ASM_SIMP_TAC std_ss [connected, OPEN_SEGMENT_ALT, CONJUNCT1 segment, 3250 NOT_EXISTS_THM] THEN 3251 REWRITE_TAC [METIS [DE_MORGAN_THM] 3252 ``~a \/ ~b \/ ~c \/ (d <> e) \/ (f = g) \/ (h = i) <=> 3253 ~(a /\ b /\ c /\ (d = e) /\ (f <> g) /\ (h <> i))`` ] THEN 3254 MAP_EVERY X_GEN_TAC [``e1:real->bool``, ``e2:real->bool``] THEN 3255 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 3256 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 3257 PURE_ONCE_REWRITE_TAC[INTER_COMM] THEN 3258 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REWRITE_TAC [IN_INTER] THEN 3259 DISCH_TAC THEN DISCH_TAC THEN 3260 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN 3261 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN 3262 REWRITE_TAC [GSYM CONJ_ASSOC] THEN 3263 SIMP_TAC std_ss [NOT_EXISTS_THM, LEFT_IMP_EXISTS_THM] THEN 3264 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN 3265 MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN 3266 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 3267 MAP_EVERY (fn t => SPEC_TAC(t,t)) 3268 [``e2:real->bool``, ``e1:real->bool``, ``v:real``, ``u:real``] THEN 3269 KNOW_TAC ``!(u :real) (v :real). (\u v. !(e1 :real -> bool) (e2 :real -> bool). 3270 (e1 INTER e2 INTER 3271 {((1 :real) - u) * (a :real) + u * (b :real) | 3272 (0 :real) <= u /\ u <= (1 :real)} = 3273 ({} :real -> bool)) /\ 3274 {((1 :real) - u) * a + u * b | 3275 (0 :real) <= u /\ u <= (1 :real)} SUBSET e1 UNION e2 /\ 3276 (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3277 (0 :real) <= u /\ u <= (1 :real) /\ 3278 ((1 :real) - u) * a + u * b IN e1 ==> 3279 ~((0 :real) <= v) \/ ~(v <= (1 :real)) \/ 3280 ((1 :real) - v) * a + v * b NOTIN e2) u v`` THENL 3281 [ALL_TAC, METIS_TAC []] THEN 3282 MATCH_MP_TAC REAL_WLOG_LE THEN CONJ_TAC THENL 3283 [MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN BETA_TAC THEN 3284 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) 3285 [UNION_COMM, INTER_COMM] THEN 3286 KNOW_TAC ``(!(e1 :real -> bool) (e2 :real -> bool). 3287 (e1 INTER e2 INTER 3288 {((1 :real) - u) * (a :real) + u * (b :real) | 3289 (0 :real) <= u /\ u <= (1 :real)} = 3290 ({} :real -> bool)) /\ 3291 {((1 :real) - u) * a + u * b | 3292 (0 :real) <= u /\ u <= (1 :real)} SUBSET e1 UNION e2 /\ 3293 (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3294 (0 :real) <= (u :real) /\ u <= (1 :real) /\ 3295 ((1 :real) - u) * a + u * b IN e1 ==> 3296 ~((0 :real) <= (v :real)) \/ ~(v <= (1 :real)) \/ 3297 ((1 :real) - v) * a + v * b NOTIN e2) <=> 3298 !(e2 :real -> bool) (e1 :real -> bool). 3299 ({((1 :real) - u) * a + u * b | 3300 (0 :real) <= u /\ u <= (1 :real)} INTER (e1 INTER e2) = 3301 ({} :real -> bool)) /\ 3302 {((1 :real) - u) * a + u * b | 3303 (0 :real) <= u /\ u <= (1 :real)} SUBSET e2 UNION e1 /\ 3304 (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3305 (0 :real) <= v /\ v <= (1 :real) /\ 3306 ((1 :real) - v) * a + v * b IN e1 ==> 3307 ~((0 :real) <= u) \/ ~(u <= (1 :real)) \/ 3308 ((1 :real) - u) * a + u * b NOTIN e2`` THENL 3309 [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]] THEN 3310 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN 3311 SIMP_TAC std_ss [UNION_ACI, INTER_ACI] THEN METIS_TAC[], 3312 ALL_TAC] THEN 3313 MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN 3314 SIMP_TAC std_ss [] THEN 3315 REPEAT STRIP_TAC THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 3316 MP_TAC(ISPECL 3317 [``\u. (&1 - u) * a + u * b:real``, ``u:real``, ``v:real``, 3318 ``e1:real->bool``, ``e2:real->bool``] 3319 CONNECTED_REAL_LEMMA) THEN BETA_TAC THEN 3320 ASM_REWRITE_TAC [GSYM open_def, REAL_POS, NOT_IMP] THEN 3321 REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL 3322 [MAP_EVERY X_GEN_TAC [``e:real``, ``x:real``] THEN STRIP_TAC THEN 3323 EXISTS_TAC ``e / dist(a:real,b)`` THEN 3324 ASM_SIMP_TAC std_ss [REAL_LT_DIV, GSYM DIST_NZ] THEN 3325 GEN_TAC THEN REWRITE_TAC[dist] THEN STRIP_TAC THEN 3326 ASM_SIMP_TAC std_ss [ABS_MUL, GSYM REAL_LT_RDIV_EQ, GSYM ABS_NZ, REAL_SUB_0, 3327 ABS_NEG, REAL_ARITH 3328 ``((&1 - y') * a + y' * b) - ((&1 - x') * a + x' * b):real = 3329 -((y' - x') * (a - b))``], 3330 RULE_ASSUM_TAC(SIMP_RULE std_ss [EXTENSION, IN_INTER, GSPECIFICATION, 3331 SUBSET_DEF, IN_UNION, NOT_IN_EMPTY]) THEN 3332 METIS_TAC[REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS]], ALL_TAC] THEN 3333 ASM_CASES_TAC ``b:real = a`` THEN 3334 ASM_SIMP_TAC std_ss [SEGMENT_REFL, CONNECTED_EMPTY, CONNECTED_SING] THEN 3335 ASM_SIMP_TAC std_ss [connected, OPEN_SEGMENT_ALT, CONJUNCT1 segment, 3336 NOT_EXISTS_THM] THEN 3337 REWRITE_TAC [METIS [DE_MORGAN_THM] 3338 ``~a \/ ~b \/ ~c \/ (d <> e) \/ (f = g) \/ (h = i) <=> 3339 ~(a /\ b /\ c /\ (d = e) /\ (f <> g) /\ (h <> i))`` ] THEN 3340 MAP_EVERY X_GEN_TAC [``e1:real->bool``, ``e2:real->bool``] THEN 3341 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 3342 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 3343 PURE_ONCE_REWRITE_TAC[INTER_COMM] THEN 3344 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REWRITE_TAC [IN_INTER] THEN 3345 DISCH_TAC THEN DISCH_TAC THEN 3346 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN 3347 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN 3348 REWRITE_TAC [GSYM CONJ_ASSOC] THEN 3349 SIMP_TAC std_ss [NOT_EXISTS_THM, LEFT_IMP_EXISTS_THM] THEN 3350 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN 3351 MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN 3352 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 3353 MAP_EVERY (fn t => SPEC_TAC(t,t)) 3354 [``e2:real->bool``, ``e1:real->bool``, ``v:real``, ``u:real``] THEN 3355 KNOW_TAC ``!(u :real) (v :real). (\u v. !(e1 :real -> bool) (e2 :real -> bool). 3356 (e1 INTER e2 INTER 3357 {((1 :real) - u) * (a :real) + u * (b :real) | 3358 (0 :real) < u /\ u < (1 :real)} = 3359 ({} :real -> bool)) /\ 3360 {((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} SUBSET 3361 e1 UNION e2 /\ (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3362 (0 :real) < u /\ u < (1 :real) /\ 3363 ((1 :real) - u) * a + u * b IN e1 ==> 3364 ~((0 :real) < v) \/ ~(v < (1 :real)) \/ 3365 ((1 :real) - v) * a + v * b NOTIN e2) u v`` THENL 3366 [ALL_TAC, METIS_TAC []] THEN 3367 MATCH_MP_TAC REAL_WLOG_LE THEN CONJ_TAC THENL 3368 [MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN BETA_TAC THEN 3369 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) 3370 [UNION_COMM, INTER_COMM] THEN 3371 KNOW_TAC `` (!(e1 :real -> bool) (e2 :real -> bool). 3372 (e1 INTER e2 INTER 3373 {((1 :real) - u) * (a :real) + u * (b :real) | 3374 (0 :real) < u /\ u < (1 :real)} = 3375 ({} :real -> bool)) /\ 3376 {((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} SUBSET 3377 e1 UNION e2 /\ (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3378 (0 :real) < (u :real) /\ u < (1 :real) /\ 3379 ((1 :real) - u) * a + u * b IN e1 ==> 3380 ~((0 :real) < (v :real)) \/ ~(v < (1 :real)) \/ 3381 ((1 :real) - v) * a + v * b NOTIN e2) <=> 3382 !(e2 :real -> bool) (e1 :real -> bool). 3383 ({((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} INTER 3384 (e1 INTER e2) = 3385 ({} :real -> bool)) /\ 3386 {((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} SUBSET 3387 e2 UNION e1 /\ (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3388 (0 :real) < v /\ v < (1 :real) /\ 3389 ((1 :real) - v) * a + v * b IN e1 ==> 3390 ~((0 :real) < u) \/ ~(u < (1 :real)) \/ 3391 ((1 :real) - u) * a + u * b NOTIN e2`` THENL 3392 [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]] THEN 3393 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN 3394 SIMP_TAC std_ss [UNION_ACI, INTER_ACI] THEN METIS_TAC[], 3395 ALL_TAC] THEN 3396 MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN 3397 SIMP_TAC std_ss [] THEN 3398 REPEAT STRIP_TAC THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 3399 MP_TAC(ISPECL 3400 [``\u. (&1 - u) * a + u * b:real``, ``u:real``, ``v:real``, 3401 ``e1:real->bool``, ``e2:real->bool``] 3402 CONNECTED_REAL_LEMMA) THEN BETA_TAC THEN 3403 ASM_REWRITE_TAC [GSYM open_def, REAL_POS, NOT_IMP] THEN 3404 REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL 3405 [MAP_EVERY X_GEN_TAC [``e:real``, ``x:real``] THEN STRIP_TAC THEN 3406 EXISTS_TAC ``e / dist(a:real,b)`` THEN 3407 ASM_SIMP_TAC std_ss [REAL_LT_DIV, GSYM DIST_NZ] THEN 3408 GEN_TAC THEN REWRITE_TAC[dist] THEN STRIP_TAC THEN 3409 ASM_SIMP_TAC std_ss [ABS_MUL, GSYM REAL_LT_RDIV_EQ, GSYM ABS_NZ, REAL_SUB_0, 3410 ABS_NEG, REAL_ARITH 3411 ``((&1 - y') * a + y' * b) - ((&1 - x') * a + x' * b):real = 3412 -((y' - x') * (a - b))``], 3413 RULE_ASSUM_TAC(SIMP_RULE std_ss [EXTENSION, IN_INTER, GSPECIFICATION, 3414 SUBSET_DEF, IN_UNION, NOT_IN_EMPTY]) THEN 3415 METIS_TAC[REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS]]); 3416 3417val CONNECTED_UNIV = store_thm ("CONNECTED_UNIV", 3418 ``connected univ(:real)``, 3419 ONCE_REWRITE_TAC[CONNECTED_IFF_CONNECTABLE_POINTS] THEN 3420 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN 3421 REWRITE_TAC[IN_UNIV, SUBSET_UNIV] THEN 3422 EXISTS_TAC ``segment[a:real,b]`` THEN 3423 ASM_SIMP_TAC std_ss [CONNECTED_SEGMENT, ENDS_IN_SEGMENT]); 3424 3425val CLOPEN = store_thm ("CLOPEN", 3426 ``!s. closed s /\ open s <=> (s = {}) \/ (s = univ(:real))``, 3427 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN 3428 ASM_REWRITE_TAC[CLOSED_EMPTY, OPEN_EMPTY, CLOSED_UNIV, OPEN_UNIV] THEN 3429 MATCH_MP_TAC(REWRITE_RULE[CONNECTED_CLOPEN] CONNECTED_UNIV) THEN 3430 ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV, GSYM OPEN_IN, GSYM CLOSED_IN]); 3431 3432val CONNECTED_BIGUNION = store_thm ("CONNECTED_BIGUNION", 3433 ``!P:(real->bool)->bool. 3434 (!s. s IN P ==> connected s) /\ ~(BIGINTER P = {}) 3435 ==> connected(BIGUNION P)``, 3436 GEN_TAC THEN REWRITE_TAC[connected] THEN STRIP_TAC THEN 3437 CCONTR_TAC THEN POP_ASSUM (MP_TAC o REWRITE_RULE [REAL_NEG_NEG]) THEN 3438 STRIP_TAC THEN UNDISCH_TAC ``~(BIGINTER P :real->bool = {})`` THEN 3439 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_BIGINTER] THEN 3440 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 3441 SUBGOAL_THEN ``(a:real) IN e1 \/ a IN e2`` STRIP_ASSUME_TAC THENL 3442 [ASM_SET_TAC[], 3443 UNDISCH_TAC ``~(e2 INTER BIGUNION P:real->bool = {})``, 3444 UNDISCH_TAC ``~(e1 INTER BIGUNION P:real->bool = {})``] THEN 3445 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER, IN_BIGUNION] THEN 3446 DISCH_THEN(X_CHOOSE_THEN ``b:real`` 3447 (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 3448 DISCH_THEN(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN 3449 UNDISCH_TAC ``!t:real->bool. t IN P ==> a IN t`` THEN 3450 DISCH_THEN(MP_TAC o SPEC ``s:real->bool``) THEN 3451 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 3452 FIRST_X_ASSUM(MP_TAC o SPEC ``s:real->bool``) THEN 3453 ASM_REWRITE_TAC[] THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 3454 POP_ASSUM (MP_TAC o SPECL [``e1:real->bool``, ``e2:real->bool``]) THEN 3455 ASM_SET_TAC[]); 3456 3457val CONNECTED_UNION = store_thm ("CONNECTED_UNION", 3458 ``!s t:real->bool. 3459 connected s /\ connected t /\ ~(s INTER t = {}) 3460 ==> connected (s UNION t)``, 3461 REWRITE_TAC[GSYM BIGUNION_2, GSYM BIGINTER_2] THEN 3462 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_BIGUNION THEN 3463 ASM_SET_TAC[]); 3464 3465val CONNECTED_DIFF_OPEN_FROM_CLOSED = store_thm ("CONNECTED_DIFF_OPEN_FROM_CLOSED", 3466 ``!s t u:real->bool. 3467 s SUBSET t /\ t SUBSET u /\ 3468 open s /\ closed t /\ connected u /\ connected(t DIFF s) 3469 ==> connected(u DIFF s)``, 3470 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [connected, NOT_EXISTS_THM] THEN 3471 MAP_EVERY X_GEN_TAC [``v:real->bool``, ``w:real->bool``] THEN 3472 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 3473 UNDISCH_TAC ``connected(t DIFF s:real->bool)`` THEN SIMP_TAC std_ss [connected] THEN 3474 MAP_EVERY EXISTS_TAC [``v:real->bool``, ``w:real->bool``] THEN 3475 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN 3476 CONJ_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN 3477 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 3478 MAP_EVERY (fn t => SPEC_TAC(t,t)) [``v:real->bool``, ``w:real->bool``] THEN 3479 KNOW_TAC ``(!v:real->bool w:real->bool. 3480 ~(w INTER (u DIFF s) = {}) /\ ~(v INTER (u DIFF s) = {}) /\ 3481 (v INTER w INTER (u DIFF s) = {}) /\ u DIFF s SUBSET v UNION w /\ 3482 open w /\ open v /\ connected u /\ closed t /\ open s /\ 3483 t SUBSET u /\ s SUBSET t 3484 ==> ~(v INTER (u DIFF s) = {}) /\ ~(w INTER (u DIFF s) = {}) /\ 3485 (w INTER v INTER (u DIFF s) = {}) /\ u DIFF s SUBSET w UNION v /\ 3486 open v /\ open w /\ connected u /\ closed t /\ open s /\ 3487 t SUBSET u /\ s SUBSET t) /\ 3488 (!w v. (~(w INTER (u DIFF s) = {}) /\ ~(v INTER (u DIFF s) = {}) /\ 3489 (v INTER w INTER (u DIFF s) = {}) /\ u DIFF s SUBSET v UNION w /\ 3490 open w /\ open v /\ connected u /\ closed t /\ open s /\ 3491 t SUBSET u /\ s SUBSET t) /\ (w INTER (t DIFF s) = {}) 3492 ==> F)`` THENL 3493 [CONJ_TAC THENL [SIMP_TAC std_ss [CONJ_ACI, INTER_ACI, UNION_ACI], ALL_TAC] THEN 3494 REPEAT STRIP_TAC THEN UNDISCH_TAC ``connected u`` THEN 3495 GEN_REWR_TAC LAND_CONV [connected] THEN SIMP_TAC std_ss [] THEN 3496 MAP_EVERY EXISTS_TAC [``v UNION s:real->bool``, ``w DIFF t:real->bool``] THEN 3497 ASM_SIMP_TAC std_ss [OPEN_UNION, OPEN_DIFF] THEN ASM_SET_TAC[], METIS_TAC []]); 3498 3499val CONNECTED_DISJOINT_BIGUNION_OPEN_UNIQUE = store_thm 3500 ("CONNECTED_DISJOINT_BIGUNION_OPEN_UNIQUE", 3501 ``!f:(real->bool)->bool f'. 3502 pairwise DISJOINT f /\ pairwise DISJOINT f' /\ 3503 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 3504 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 3505 (BIGUNION f = BIGUNION f') 3506 ==> (f = f')``, 3507 GEN_REWR_TAC (funpow 2 BINDER_CONV o RAND_CONV) [EXTENSION] THEN 3508 KNOW_TAC ``(!f f'. 3509 pairwise DISJOINT f /\ pairwise DISJOINT f' /\ 3510 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 3511 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 3512 (BIGUNION f = BIGUNION f') 3513 ==> pairwise DISJOINT f' /\ pairwise DISJOINT f /\ 3514 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 3515 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 3516 (BIGUNION f' = BIGUNION f)) /\ 3517 (!f f' x. (pairwise DISJOINT f /\ pairwise DISJOINT f' /\ 3518 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 3519 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 3520 (BIGUNION f = BIGUNION f')) /\ x IN f ==> x IN f')`` THENL 3521 [ALL_TAC, METIS_TAC []] THEN 3522 CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN 3523 GEN_TAC THEN GEN_TAC THEN X_GEN_TAC ``s:real->bool`` THEN STRIP_TAC THEN 3524 SUBGOAL_THEN 3525 ``?t a:real. t IN f' /\ a IN s /\ a IN t`` STRIP_ASSUME_TAC 3526 THENL [ASM_SET_TAC[], ALL_TAC] THEN 3527 SUBGOAL_THEN ``s:real->bool = t`` (fn th => ASM_REWRITE_TAC[th]) THEN 3528 REWRITE_TAC[EXTENSION] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 3529 MAP_EVERY (fn t => SPEC_TAC(t,t)) 3530 [``s:real->bool``, ``t:real->bool``, 3531 ``f:(real->bool)->bool``, ``f':(real->bool)->bool``] THEN 3532 KNOW_TAC ``(!f f' s t. 3533 a IN t /\ a IN s /\ t IN f' /\ s IN f /\ 3534 (BIGUNION f = BIGUNION f') /\ 3535 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 3536 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 3537 pairwise DISJOINT f' /\ pairwise DISJOINT f 3538 ==> a IN s /\ a IN t /\ s IN f /\ t IN f' /\ 3539 (BIGUNION f' = BIGUNION f) /\ 3540 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 3541 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 3542 pairwise DISJOINT f /\ pairwise DISJOINT f') /\ 3543 (!f f' s t x. 3544 (a IN t /\ a IN s /\ t IN f' /\ s IN f /\ 3545 (BIGUNION f = BIGUNION f') /\ 3546 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 3547 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 3548 pairwise DISJOINT f' /\ pairwise DISJOINT f) /\ 3549 x IN s ==> x IN t)`` THENL 3550 [ALL_TAC, METIS_TAC []] THEN 3551 CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN 3552 GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN 3553 X_GEN_TAC ``b:real`` THEN STRIP_TAC THEN 3554 UNDISCH_TAC 3555 ``!s:real->bool. s IN f ==> open s /\ connected s /\ ~(s = {})`` THEN 3556 DISCH_THEN(MP_TAC o SPEC ``s:real->bool``) THEN ASM_REWRITE_TAC[] THEN 3557 STRIP_TAC THEN ASM_CASES_TAC ``(b:real) IN t`` THEN 3558 ASM_REWRITE_TAC[] THEN 3559 UNDISCH_TAC ``connected(s:real->bool)`` THEN 3560 REWRITE_TAC[connected] THEN 3561 MAP_EVERY EXISTS_TAC 3562 [``t:real->bool``, ``BIGUNION(f' DELETE (t:real->bool))``] THEN 3563 REPEAT STRIP_TAC THENL 3564 [ASM_SIMP_TAC std_ss [], 3565 MATCH_MP_TAC OPEN_BIGUNION THEN ASM_SIMP_TAC std_ss [IN_DELETE], 3566 REWRITE_TAC[GSYM BIGUNION_INSERT] THEN ASM_SET_TAC[], 3567 MATCH_MP_TAC(SET_RULE ``(t INTER u = {}) ==> (t INTER u INTER s = {})``) THEN 3568 SIMP_TAC std_ss [INTER_BIGUNION, EMPTY_BIGUNION, FORALL_IN_GSPEC] THEN 3569 REWRITE_TAC [IN_DELETE, GSYM DISJOINT_DEF] THEN ASM_MESON_TAC[pairwise], 3570 ASM_SET_TAC[], ASM_SET_TAC[]]); 3571 3572val CONNECTED_FROM_CLOSED_UNION_AND_INTER = store_thm ("CONNECTED_FROM_CLOSED_UNION_AND_INTER", 3573 ``!s t:real->bool. 3574 closed s /\ closed t /\ connected(s UNION t) /\ connected(s INTER t) 3575 ==> connected s /\ connected t``, 3576 KNOW_TAC ``(!s t. closed s /\ closed t /\ 3577 connected (s UNION t) /\ connected (s INTER t) 3578 ==> closed t /\ closed s /\ connected (t UNION s) /\ 3579 connected (t INTER s)) /\ 3580 (!s t. closed s /\ closed t /\ connected (s UNION t) /\ 3581 connected (s INTER t) ==> connected s)`` THENL 3582 [ALL_TAC, MESON_TAC []] THEN 3583 CONJ_TAC THENL [SIMP_TAC std_ss [UNION_COMM, INTER_COMM], REPEAT STRIP_TAC] THEN 3584 ASM_SIMP_TAC std_ss [CONNECTED_CLOSED_SET] THEN 3585 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 3586 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 3587 ASM_CASES_TAC 3588 ``~(s INTER t SUBSET (u:real->bool)) /\ ~(s INTER t SUBSET v)`` 3589 THENL 3590 [UNDISCH_TAC ``connected(s INTER t:real->bool)`` THEN 3591 ASM_SIMP_TAC std_ss [CONNECTED_CLOSED] THEN 3592 MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN 3593 ASM_REWRITE_TAC[] THEN ASM_SET_TAC [], 3594 POP_ASSUM (MP_TAC o REWRITE_RULE [DE_MORGAN_THM]) THEN 3595 STRIP_TAC THEN UNDISCH_TAC ``connected(s UNION t:real->bool)`` THEN 3596 ASM_SIMP_TAC std_ss [CONNECTED_CLOSED] THENL 3597 [MAP_EVERY EXISTS_TAC [``t UNION u:real->bool``, ``v:real->bool``] THEN 3598 ASM_SIMP_TAC std_ss [CLOSED_UNION] THEN ASM_SET_TAC[], 3599 MAP_EVERY EXISTS_TAC [``t UNION v:real->bool``, ``u:real->bool``] THEN 3600 ASM_SIMP_TAC std_ss [CLOSED_UNION] THEN ASM_SET_TAC[]]]); 3601 3602val CONNECTED_FROM_OPEN_UNION_AND_INTER = store_thm ("CONNECTED_FROM_OPEN_UNION_AND_INTER", 3603 ``!s t:real->bool. 3604 open s /\ open t /\ connected(s UNION t) /\ connected(s INTER t) 3605 ==> connected s /\ connected t``, 3606 3607 KNOW_TAC ``(!s t. 3608 open s /\ open t /\ connected (s UNION t) /\ connected (s INTER t) 3609 ==> open t /\ open s /\ connected (t UNION s) /\ connected (t INTER s)) /\ 3610 (!s t. 3611 open s /\ open t /\ connected (s UNION t) /\ connected (s INTER t) 3612 ==> connected s)`` THENL 3613 [ALL_TAC, MESON_TAC []] THEN 3614 CONJ_TAC THENL [SIMP_TAC std_ss [UNION_COMM, INTER_COMM], REPEAT STRIP_TAC] THEN 3615 ASM_SIMP_TAC std_ss [CONNECTED_OPEN_SET] THEN 3616 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 3617 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN ASM_CASES_TAC 3618 ``~(s INTER t SUBSET (u:real->bool)) /\ ~(s INTER t SUBSET v)`` 3619 THENL 3620 [UNDISCH_TAC ``connected(s INTER t:real->bool)`` THEN 3621 ASM_SIMP_TAC std_ss [connected] THEN 3622 MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN 3623 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[], 3624 POP_ASSUM (MP_TAC o REWRITE_RULE [DE_MORGAN_THM]) THEN 3625 STRIP_TAC THEN UNDISCH_TAC ``connected(s UNION t:real->bool)`` THEN 3626 ASM_SIMP_TAC std_ss [connected] THENL 3627 [MAP_EVERY EXISTS_TAC [``t UNION u:real->bool``, ``v:real->bool``] THEN 3628 ASM_SIMP_TAC std_ss [OPEN_UNION] THEN ASM_SET_TAC[], 3629 MAP_EVERY EXISTS_TAC [``t UNION v:real->bool``, ``u:real->bool``] THEN 3630 ASM_SIMP_TAC std_ss [OPEN_UNION] THEN ASM_SET_TAC[]]]); 3631 3632(* ------------------------------------------------------------------------- *) 3633(* Sort of induction principle for connected sets. *) 3634(* ------------------------------------------------------------------------- *) 3635 3636val CONNECTED_INDUCTION = store_thm ("CONNECTED_INDUCTION", 3637 ``!P Q s:real->bool. connected s /\ 3638 (!t a. open_in (subtopology euclidean s) t /\ a IN t 3639 ==> ?z. z IN t /\ P z) /\ (!a. a IN s 3640 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ 3641 !x y. x IN t /\ y IN t /\ P x /\ P y /\ Q x ==> Q y) 3642 ==> !a b. a IN s /\ b IN s /\ P a /\ P b /\ Q a ==> Q b``, 3643 REPEAT STRIP_TAC THEN 3644 GEN_REWR_TAC I [TAUT `p <=> ~ ~p`] THEN DISCH_TAC THEN 3645 UNDISCH_TAC ``connected s`` THEN GEN_REWR_TAC LAND_CONV [CONNECTED_OPEN_IN] THEN 3646 REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC 3647 [``{b:real | ?t. open_in (subtopology euclidean s) t /\ 3648 b IN t /\ !x. x IN t /\ P x ==> Q x}``, 3649 ``{b:real | ?t. open_in (subtopology euclidean s) t /\ 3650 b IN t /\ !x. x IN t /\ P x ==> ~(Q x)}``] THEN 3651 REPEAT CONJ_TAC THENL 3652 [ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN 3653 X_GEN_TAC ``c:real`` THEN SIMP_TAC std_ss [GSPECIFICATION] THEN 3654 ASM_SET_TAC[], 3655 ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN 3656 X_GEN_TAC ``c:real`` THEN SIMP_TAC std_ss [GSPECIFICATION] THEN 3657 ASM_SET_TAC[], 3658 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNION] THEN 3659 X_GEN_TAC ``c:real`` THEN DISCH_TAC THEN 3660 FIRST_X_ASSUM(MP_TAC o SPEC ``c:real``) THEN ASM_SET_TAC[], 3661 KNOW_TAC ``!x. ~((?t. open_in (subtopology euclidean s) t /\ 3662 x IN t /\ (!x. x IN t /\ P x ==> Q x)) /\ 3663 (?t. open_in (subtopology euclidean s) t /\ x IN t /\ 3664 (!x. x IN t /\ P x ==> ~Q x)))`` THENL 3665 [ALL_TAC, SIMP_TAC std_ss [EXTENSION, IN_INTER, NOT_IN_EMPTY, GSPECIFICATION]] THEN 3666 X_GEN_TAC ``c:real`` THEN DISCH_THEN(CONJUNCTS_THEN2 3667 (X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) 3668 (X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC)) THEN 3669 FIRST_X_ASSUM(MP_TAC o SPECL [``t INTER u:real->bool``, ``c:real``]) THEN 3670 ASM_SIMP_TAC std_ss [OPEN_IN_INTER] THEN ASM_SET_TAC[], 3671 ASM_SET_TAC[], ASM_SET_TAC[]]); 3672 3673val CONNECTED_EQUIVALENCE_RELATION_GEN = store_thm ("CONNECTED_EQUIVALENCE_RELATION_GEN", 3674 ``!P R s:real->bool. connected s /\ (!x y. R x y ==> R y x) /\ 3675 (!x y z. R x y /\ R y z ==> R x z) /\ 3676 (!t a. open_in (subtopology euclidean s) t /\ a IN t 3677 ==> ?z. z IN t /\ P z) /\ (!a. a IN s 3678 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ 3679 !x y. x IN t /\ y IN t /\ P x /\ P y ==> R x y) 3680 ==> !a b. a IN s /\ b IN s /\ P a /\ P b ==> R a b``, 3681 REPEAT GEN_TAC THEN STRIP_TAC THEN 3682 SUBGOAL_THEN 3683 ``!a:real. a IN s /\ P a 3684 ==> !b c. b IN s /\ c IN s /\ P b /\ P c /\ R a b ==> R a c`` 3685 MP_TAC THENL [ALL_TAC, ASM_MESON_TAC[]] THEN 3686 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION THEN 3687 ASM_REWRITE_TAC [] THEN 3688 X_GEN_TAC ``b:real`` THEN POP_ASSUM MP_TAC THEN 3689 POP_ASSUM (MP_TAC o Q.SPEC `b:real`) THEN 3690 METIS_TAC[]); 3691 3692val CONNECTED_INDUCTION_SIMPLE = store_thm ("CONNECTED_INDUCTION_SIMPLE", 3693 ``!P s:real->bool. connected s /\ 3694 (!a. a IN s 3695 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ 3696 !x y. x IN t /\ y IN t /\ P x ==> P y) 3697 ==> !a b. a IN s /\ b IN s /\ P a ==> P b``, 3698 MP_TAC(ISPEC ``\x:real. T`` CONNECTED_INDUCTION) THEN 3699 REWRITE_TAC[] THEN STRIP_TAC THEN 3700 MAP_EVERY X_GEN_TAC [``Q:real->bool``, ``s:real->bool``] THEN 3701 POP_ASSUM (MP_TAC o Q.SPECL [`Q:real->bool`, `s:real->bool`]) THEN 3702 METIS_TAC[]); 3703 3704val CONNECTED_EQUIVALENCE_RELATION = store_thm ("CONNECTED_EQUIVALENCE_RELATION", 3705 ``!R s:real->bool. connected s /\ 3706 (!x y. R x y ==> R y x) /\ 3707 (!x y z. R x y /\ R y z ==> R x z) /\ 3708 (!a. a IN s 3709 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ 3710 !x. x IN t ==> R a x) 3711 ==> !a b. a IN s /\ b IN s ==> R a b``, 3712 REPEAT GEN_TAC THEN STRIP_TAC THEN 3713 SUBGOAL_THEN 3714 ``!a:real. a IN s ==> !b c. b IN s /\ c IN s /\ R a b ==> R a c`` 3715 MP_TAC THENL [ALL_TAC, ASM_MESON_TAC[]] THEN 3716 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION_SIMPLE THEN 3717 ASM_MESON_TAC[]); 3718 3719(* ------------------------------------------------------------------------- *) 3720(* Limit points. *) 3721(* ------------------------------------------------------------------------- *) 3722 3723val _ = set_fixity "limit_point_of" (Infix(NONASSOC, 450)); 3724 3725val limit_point_of = new_definition ("limit_point_of", 3726 ``x limit_point_of s <=> 3727 !t. x IN t /\ open t ==> ?y. ~(y = x) /\ y IN s /\ y IN t``); 3728 3729val LIMPT_SUBSET = store_thm ("LIMPT_SUBSET", 3730 ``!x s t. x limit_point_of s /\ s SUBSET t ==> x limit_point_of t``, 3731 REWRITE_TAC[limit_point_of, SUBSET_DEF] THEN MESON_TAC[]); 3732 3733val LIMPT_APPROACHABLE = store_thm ("LIMPT_APPROACHABLE", 3734 ``!x s. x limit_point_of s <=> 3735 !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) < e``, 3736 REPEAT GEN_TAC THEN REWRITE_TAC[limit_point_of] THEN 3737 MESON_TAC[open_def, DIST_SYM, OPEN_BALL, CENTRE_IN_BALL, IN_BALL]); 3738 3739val lemma = prove ( 3740 ``&0 < d:real ==> x <= d / &2 ==> x < d``, 3741 SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_LT] THEN REAL_ARITH_TAC); 3742 3743val APPROACHABLE_LT_LE = store_thm ("APPROACHABLE_LT_LE", 3744 ``!P f. (?d:real. &0 < d /\ !x. f(x) < d ==> P x) = 3745 (?d:real. &0 < d /\ !x. f(x) <= d ==> P x)``, 3746 MESON_TAC[REAL_LT_IMP_LE, lemma, REAL_LT_HALF1]); 3747 3748val LIMPT_APPROACHABLE_LE = store_thm ("LIMPT_APPROACHABLE_LE", 3749 ``!x s. x limit_point_of s <=> 3750 !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) <= e``, 3751 REPEAT GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN 3752 MATCH_MP_TAC(TAUT `(~a <=> ~b) ==> (a <=> b)`) THEN 3753 KNOW_TAC ``!e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e) <=> 3754 (\e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e)) e`` THENL 3755 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 3756 KNOW_TAC ``!e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) <= e) <=> 3757 (\e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) <= e)) e `` THENL 3758 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 3759 REWRITE_TAC [NOT_FORALL_THM] THEN BETA_TAC THEN REWRITE_TAC [NOT_IMP] THEN 3760 KNOW_TAC ``!x'' x'. ( x'' IN s /\ x'' <> x /\ dist (x'',x) < x') <=> 3761 (\x''. x'' IN s /\ x'' <> x /\ dist (x'',x) < x') x''`` THENL 3762 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 3763 KNOW_TAC ``!x'' x'. ( x'' IN s /\ x'' <> x /\ dist (x'',x) <= x') <=> 3764 (\x''. x'' IN s /\ x'' <> x /\ dist (x'',x) <= x') x''`` THENL 3765 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 3766 REWRITE_TAC [NOT_EXISTS_THM] THEN BETA_TAC THEN 3767 SIMP_TAC std_ss [TAUT `~(a /\ b /\ c) <=> c ==> ~(a /\ b)`, APPROACHABLE_LT_LE]); 3768 3769val REAL_CHOOSE_SIZE = store_thm ("REAL_CHOOSE_SIZE", 3770 ``!c. &0 <= c ==> (?x. abs x = c:real)``, 3771 METIS_TAC [ABS_REFL]); 3772 3773val LIMPT_UNIV = store_thm ("LIMPT_UNIV", 3774 ``!x:real. x limit_point_of UNIV``, 3775 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE, IN_UNIV] THEN 3776 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 3777 SUBGOAL_THEN ``?c:real. abs(c) = e / &2`` CHOOSE_TAC THENL 3778 [ASM_SIMP_TAC std_ss [REAL_CHOOSE_SIZE, REAL_LT_HALF1, REAL_LT_IMP_LE], 3779 ALL_TAC] THEN 3780 EXISTS_TAC ``x + c:real`` THEN 3781 REWRITE_TAC[dist, REAL_ADD_RID_UNIQ] THEN ASM_REWRITE_TAC[REAL_ADD_SUB] THEN 3782 ASM_REWRITE_TAC [REAL_LT_HALF2] THEN KNOW_TAC ``0 < abs c:real`` THENL 3783 [ASM_SIMP_TAC std_ss [REAL_LT_HALF1], METIS_TAC [ABS_NZ]]); 3784 3785val CLOSED_LIMPT = store_thm ("CLOSED_LIMPT", 3786 ``!s. closed s <=> !x. x limit_point_of s ==> x IN s``, 3787 REWRITE_TAC[closed_def] THEN ONCE_REWRITE_TAC[OPEN_SUB_OPEN] THEN 3788 REWRITE_TAC[limit_point_of, IN_DIFF, IN_UNIV, SUBSET_DEF] THEN MESON_TAC[]); 3789 3790val LIMPT_EMPTY = store_thm ("LIMPT_EMPTY", 3791 ``!x. ~(x limit_point_of {})``, 3792 REWRITE_TAC[LIMPT_APPROACHABLE, NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]); 3793 3794val NO_LIMIT_POINT_IMP_CLOSED = store_thm ("NO_LIMIT_POINT_IMP_CLOSED", 3795 ``!s. ~(?x. x limit_point_of s) ==> closed s``, 3796 MESON_TAC[CLOSED_LIMPT]); 3797 3798val CLOSED_POSITIVE_ORTHANT = store_thm ("CLOSED_POSITIVE_ORTHANT", 3799 ``closed {x:real | &0 <= x}``, 3800 REWRITE_TAC[CLOSED_LIMPT, LIMPT_APPROACHABLE] THEN 3801 SIMP_TAC std_ss [GSPECIFICATION] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 3802 REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN 3803 FIRST_X_ASSUM(MP_TAC o SPEC ``-(x:real)``) THEN 3804 ASM_SIMP_TAC std_ss [REAL_LT_RNEG, REAL_ADD_LID, NOT_EXISTS_THM] THEN 3805 X_GEN_TAC ``y:real`` THEN ONCE_REWRITE_TAC [METIS []``(a = b) <=> ~(a <> b:real)``] THEN 3806 REWRITE_TAC [GSYM DE_MORGAN_THM] THEN 3807 MATCH_MP_TAC(TAUT `(a ==> ~c) ==> ~(a /\ b /\ c)`) THEN DISCH_TAC THEN 3808 MATCH_MP_TAC(REAL_ARITH ``!b. abs x <= b /\ b <= a ==> ~(a + x < &0:real)``) THEN 3809 EXISTS_TAC ``abs(y - x :real)`` THEN ASM_SIMP_TAC std_ss [dist, REAL_LE_REFL] THEN 3810 ASM_SIMP_TAC std_ss [REAL_ARITH ``x < &0 /\ &0 <= y:real ==> abs(x) <= abs(y - x)``]); 3811 3812val FINITE_SET_AVOID = store_thm ("FINITE_SET_AVOID", 3813 ``!a:real s. FINITE s 3814 ==> ?d. &0 < d /\ !x. x IN s /\ ~(x = a) ==> d <= dist(a,x)``, 3815 GEN_TAC THEN 3816 KNOW_TAC ``!s. (?d. 0 < d /\ !x:real. x IN s /\ x <> a ==> d <= dist (a,x)) <=> 3817 (\s. ?d. 0 < d /\ !x:real. x IN s /\ x <> a ==> d <= dist (a,x)) s `` THENL 3818 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 3819 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 3820 REWRITE_TAC[NOT_IN_EMPTY] THEN 3821 CONJ_TAC THENL [MESON_TAC[REAL_LT_01], ALL_TAC] THEN 3822 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 3823 MAP_EVERY X_GEN_TAC [``s:real->bool``, ``x:real``] THEN 3824 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN DISCH_TAC THEN 3825 FIRST_X_ASSUM(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 3826 ASM_CASES_TAC ``x:real = a`` THEN REWRITE_TAC[IN_INSERT] THENL 3827 [ASM_MESON_TAC[], ALL_TAC] THEN 3828 EXISTS_TAC ``min d (dist(a:real,x))`` THEN 3829 ASM_REWRITE_TAC[REAL_LT_MIN, GSYM DIST_NZ, REAL_MIN_LE] THEN 3830 ASM_MESON_TAC[REAL_LE_REFL]); 3831 3832val LIMIT_POINT_FINITE = store_thm ("LIMIT_POINT_FINITE", 3833 ``!s a. FINITE s ==> ~(a limit_point_of s)``, 3834 REWRITE_TAC[LIMPT_APPROACHABLE, GSYM REAL_NOT_LE] THEN 3835 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM, REAL_NOT_LE, 3836 REAL_NOT_LT, TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN 3837 MESON_TAC[FINITE_SET_AVOID, DIST_SYM]); 3838 3839val LIMPT_SING = store_thm ("LIMPT_SING", 3840 ``!x y:real. ~(x limit_point_of {y})``, 3841 SIMP_TAC std_ss [LIMIT_POINT_FINITE, FINITE_SING]); 3842 3843val LIMIT_POINT_UNION = store_thm ("LIMIT_POINT_UNION", 3844 ``!s t x:real. x limit_point_of (s UNION t) <=> 3845 x limit_point_of s \/ x limit_point_of t``, 3846 REPEAT GEN_TAC THEN EQ_TAC THENL 3847 [ALL_TAC, MESON_TAC[LIMPT_SUBSET, SUBSET_UNION]] THEN 3848 REWRITE_TAC[LIMPT_APPROACHABLE, IN_UNION] THEN DISCH_TAC THEN 3849 MATCH_MP_TAC(TAUT `(~a ==> b) ==> a \/ b`) THEN 3850 KNOW_TAC ``!e. &0 < e /\ ~(?x'. x' IN s /\ ~(x' = x) /\ dist (x',x) < e) 3851 ==> (!e. &0 < e ==> (?x'. x' IN t /\ ~(x' = x) /\ dist (x',x) < e))`` THENL 3852 [ALL_TAC, SIMP_TAC std_ss [NOT_FORALL_THM, LEFT_IMP_EXISTS_THM, NOT_IMP]] THEN 3853 X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN 3854 FIRST_X_ASSUM(MP_TAC o SPEC ``min d e:real``) THEN ASM_MESON_TAC[REAL_LT_MIN]); 3855 3856val LIMPT_INSERT = store_thm ("LIMPT_INSERT", 3857 ``!s x y:real. x limit_point_of (y INSERT s) <=> x limit_point_of s``, 3858 ONCE_REWRITE_TAC[SET_RULE ``y:real INSERT s = {y} UNION s``] THEN 3859 REWRITE_TAC[LIMIT_POINT_UNION] THEN 3860 SIMP_TAC std_ss [FINITE_SING, LIMIT_POINT_FINITE]); 3861 3862val LIMPT_OF_LIMPTS = store_thm ("LIMPT_OF_LIMPTS", 3863 ``!x:real s. x limit_point_of {y | y limit_point_of s} 3864 ==> x limit_point_of s``, 3865 SIMP_TAC std_ss [LIMPT_APPROACHABLE, GSPECIFICATION] THEN REPEAT GEN_TAC THEN 3866 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 3867 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN 3868 DISCH_THEN (X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN 3869 FIRST_X_ASSUM(MP_TAC o SPEC ``dist(y:real,x)``) THEN 3870 ASM_SIMP_TAC std_ss [DIST_POS_LT] THEN 3871 DISCH_THEN (X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN 3872 EXISTS_TAC ``z:real`` THEN 3873 ASM_REWRITE_TAC[] THEN 3874 CONJ_TAC THENL 3875 [FIRST_ASSUM MP_TAC THEN GEN_REWR_TAC (LAND_CONV o LAND_CONV) [DIST_SYM] THEN 3876 REWRITE_TAC [dist] THEN REAL_ARITH_TAC, ALL_TAC] THEN 3877 FULL_SIMP_TAC std_ss [dist, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 3878 ASM_REAL_ARITH_TAC); 3879 3880val CLOSED_LIMPTS = store_thm ("CLOSED_LIMPTS", 3881 ``!s. closed {x:real | x limit_point_of s}``, 3882 SIMP_TAC std_ss [CLOSED_LIMPT, GSPECIFICATION, LIMPT_OF_LIMPTS]); 3883 3884val DISCRETE_IMP_CLOSED = store_thm ("DISCRETE_IMP_CLOSED", 3885 ``!s:real->bool e. &0 < e /\ 3886 (!x y. x IN s /\ y IN s /\ abs(y - x) < e ==> (y = x)) 3887 ==> closed s``, 3888 REPEAT STRIP_TAC THEN 3889 SUBGOAL_THEN ``!x:real. ~(x limit_point_of s)`` 3890 (fn th => MESON_TAC[th, CLOSED_LIMPT]) THEN 3891 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN DISCH_TAC THEN 3892 FIRST_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 3893 REWRITE_TAC[REAL_LT_HALF1, ASSUME ``&0 < e:real``] THEN 3894 DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN 3895 FIRST_X_ASSUM(MP_TAC o SPEC ``min (e / &2) (dist(x:real,y))``) THEN 3896 ASM_REWRITE_TAC [REAL_LT_MIN, REAL_LT_HALF1] THEN 3897 KNOW_TAC ``0 < dist(x,y:real)`` THENL 3898 [ASM_SIMP_TAC std_ss [DIST_POS_LT], ALL_TAC] THEN 3899 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 3900 DISCH_THEN(X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN 3901 FIRST_X_ASSUM(MP_TAC o SPECL [``y:real``, ``z:real``]) THEN 3902 ASM_SIMP_TAC arith_ss [GSYM dist] THEN CONJ_TAC THENL 3903 [MATCH_MP_TAC REAL_LET_TRANS THEN 3904 EXISTS_TAC ``dist(z,x) + dist(x,y:real)`` THEN 3905 METIS_TAC [DIST_TRIANGLE, GSYM REAL_HALF_DOUBLE, REAL_LT_ADD2, DIST_SYM], 3906 REPEAT (POP_ASSUM MP_TAC) THEN REWRITE_TAC [dist, DIST_NZ] THEN 3907 REAL_ARITH_TAC]); 3908 3909val LIMPT_OF_UNIV = store_thm ("LIMPT_OF_UNIV", 3910 ``!x. x limit_point_of univ(:real)``, 3911 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE, IN_UNIV] THEN 3912 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 3913 MP_TAC(ISPECL [``x:real``, ``e / &2:real``] REAL_CHOOSE_DIST) THEN 3914 KNOW_TAC ``0 <= e / 2:real`` THENL 3915 [METIS_TAC [REAL_LT_HALF1, REAL_LE_LT], ALL_TAC] THEN DISCH_TAC THEN 3916 ASM_REWRITE_TAC [] THEN STRIP_TAC THEN EXISTS_TAC ``y:real`` THEN 3917 CONJ_TAC THENL [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN 3918 ASM_REWRITE_TAC [DIST_NZ, REAL_LT_HALF1], MATCH_MP_TAC REAL_LET_TRANS THEN 3919 EXISTS_TAC ``e / 2:real`` THEN METIS_TAC [REAL_LT_HALF2, REAL_LE_LT, DIST_SYM]]); 3920 3921val LIMPT_OF_OPEN_IN = store_thm ("LIMPT_OF_OPEN_IN", 3922 ``!s t x:real. open_in (subtopology euclidean s) t /\ 3923 x limit_point_of s /\ x IN t 3924 ==> x limit_point_of t``, 3925 REWRITE_TAC[open_in, SUBSET_DEF, LIMPT_APPROACHABLE] THEN 3926 REPEAT GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 3927 UNDISCH_TAC ``!x. x IN t ==> 3928 ?e. 0 < e /\ !x'. x' IN s /\ dist (x',x) < e ==> x' IN t`` THEN DISCH_TAC THEN 3929 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 3930 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 3931 UNDISCH_TAC ``!e. 0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e`` THEN 3932 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``min d e / &2:real``) THEN 3933 KNOW_TAC ``0 < min d e / 2:real`` THENL [REWRITE_TAC [min_def] THEN 3934 METIS_TAC [REAL_LT_HALF1], ALL_TAC] THEN DISCH_TAC THEN 3935 ASM_REWRITE_TAC [] THEN STRIP_TAC THEN EXISTS_TAC ``x':real`` THEN 3936 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN TRY (FIRST_X_ASSUM MATCH_MP_TAC) THEN 3937 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_TRANS THEN 3938 EXISTS_TAC ``min d e / 2:real`` THEN ASM_REWRITE_TAC [] THEN 3939 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d e:real`` THEN 3940 METIS_TAC [REAL_MIN_LE1, min_def, REAL_LT_HALF2]); 3941 3942val LIMPT_OF_OPEN = store_thm ("LIMPT_OF_OPEN", 3943 ``!s x:real. open s /\ x IN s ==> x limit_point_of s``, 3944 REWRITE_TAC[OPEN_IN] THEN ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN 3945 MESON_TAC[LIMPT_OF_OPEN_IN, LIMPT_OF_UNIV]); 3946 3947val OPEN_IN_SING = store_thm ("OPEN_IN_SING", 3948 ``!s a. open_in (subtopology euclidean s) {a} <=> 3949 a IN s /\ ~(a limit_point_of s)``, 3950 REWRITE_TAC[open_in, LIMPT_APPROACHABLE, SING_SUBSET, IN_SING] THEN 3951 METIS_TAC[]); 3952 3953(* ------------------------------------------------------------------------- *) 3954(* Interior of a set. *) 3955(* ------------------------------------------------------------------------- *) 3956 3957val interior = new_definition ("interior", 3958 ``interior s = {x | ?t. open t /\ x IN t /\ t SUBSET s}``); 3959 3960val INTERIOR_EQ = store_thm ("INTERIOR_EQ", 3961 ``!s. (interior s = s) <=> open s``, 3962 GEN_TAC THEN REWRITE_TAC[EXTENSION, interior] THEN 3963 SIMP_TAC std_ss [GSPECIFICATION] THEN GEN_REWR_TAC RAND_CONV [OPEN_SUB_OPEN] 3964 THEN MESON_TAC[SUBSET_DEF]); 3965 3966val INTERIOR_OPEN = store_thm ("INTERIOR_OPEN", 3967 ``!s. open s ==> (interior s = s)``, 3968 MESON_TAC[INTERIOR_EQ]); 3969 3970val INTERIOR_EMPTY = store_thm ("INTERIOR_EMPTY", 3971 ``interior {} = {}``, 3972 SIMP_TAC std_ss [INTERIOR_OPEN, OPEN_EMPTY]); 3973 3974val INTERIOR_UNIV = store_thm ("INTERIOR_UNIV", 3975 ``interior univ(:real) = univ(:real)``, 3976 SIMP_TAC std_ss [INTERIOR_OPEN, OPEN_UNIV]); 3977 3978val OPEN_INTERIOR = store_thm ("OPEN_INTERIOR", 3979 ``!s. open(interior s)``, 3980 GEN_TAC THEN REWRITE_TAC[interior] THEN GEN_REWR_TAC I [OPEN_SUB_OPEN] THEN 3981 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN MESON_TAC[]); 3982 3983val INTERIOR_INTERIOR = store_thm ("INTERIOR_INTERIOR", 3984 ``!s. interior(interior s) = interior s``, 3985 MESON_TAC[INTERIOR_EQ, OPEN_INTERIOR]); 3986 3987val INTERIOR_SUBSET = store_thm ("INTERIOR_SUBSET", 3988 ``!s. (interior s) SUBSET s``, 3989 SIMP_TAC std_ss [SUBSET_DEF, interior, GSPECIFICATION] THEN MESON_TAC[]); 3990 3991val SUBSET_INTERIOR_EQ = store_thm ("SUBSET_INTERIOR_EQ", 3992 ``!s:real->bool. s SUBSET interior s <=> open s``, 3993 REWRITE_TAC[GSYM INTERIOR_EQ, 3994 SET_RULE ``!(s:real->bool) t. (s = t) <=> s SUBSET t /\ t SUBSET s``, 3995 INTERIOR_SUBSET]); 3996 3997val SUBSET_INTERIOR = store_thm ("SUBSET_INTERIOR", 3998 ``!s t. s SUBSET t ==> (interior s) SUBSET (interior t)``, 3999 SIMP_TAC std_ss [interior, SUBSET_DEF, GSPECIFICATION] THEN MESON_TAC[]); 4000 4001val INTERIOR_MAXIMAL = store_thm ("INTERIOR_MAXIMAL", 4002 ``!s t. t SUBSET s /\ open t ==> t SUBSET (interior s)``, 4003 SIMP_TAC std_ss[interior, SUBSET_DEF, GSPECIFICATION] THEN MESON_TAC[]); 4004 4005val INTERIOR_MAXIMAL_EQ = store_thm ("INTERIOR_MAXIMAL_EQ", 4006 ``!s t:real->bool. open s ==> (s SUBSET interior t <=> s SUBSET t)``, 4007 MESON_TAC[INTERIOR_MAXIMAL, SUBSET_TRANS, INTERIOR_SUBSET]); 4008 4009val INTERIOR_UNIQUE = store_thm ("INTERIOR_UNIQUE", 4010 ``!s t. t SUBSET s /\ open t /\ (!t'. t' SUBSET s /\ open t' ==> t' SUBSET t) 4011 ==> (interior s = t)``, 4012 MESON_TAC[SUBSET_ANTISYM, INTERIOR_MAXIMAL, INTERIOR_SUBSET, OPEN_INTERIOR]); 4013 4014val IN_INTERIOR = store_thm ("IN_INTERIOR", 4015 ``!x s. x IN interior s <=> ?e. &0 < e /\ ball(x,e) SUBSET s``, 4016 SIMP_TAC std_ss [interior, GSPECIFICATION] THEN 4017 MESON_TAC[OPEN_CONTAINS_BALL, SUBSET_TRANS, CENTRE_IN_BALL, OPEN_BALL]); 4018 4019val OPEN_SUBSET_INTERIOR = store_thm ("OPEN_SUBSET_INTERIOR", 4020 ``!s t. open s ==> (s SUBSET interior t <=> s SUBSET t)``, 4021 MESON_TAC[INTERIOR_MAXIMAL, INTERIOR_SUBSET, SUBSET_TRANS]); 4022 4023val INTERIOR_INTER = store_thm ("INTERIOR_INTER", 4024 ``!s t:real->bool. interior(s INTER t) = interior s INTER interior t``, 4025 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 4026 [REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THEN 4027 MATCH_MP_TAC SUBSET_INTERIOR THEN REWRITE_TAC[INTER_SUBSET], 4028 MATCH_MP_TAC INTERIOR_MAXIMAL THEN SIMP_TAC std_ss [OPEN_INTER, OPEN_INTERIOR] THEN 4029 MATCH_MP_TAC(SET_RULE 4030 ``s SUBSET s' /\ t SUBSET t' ==> s INTER t SUBSET s' INTER t'``) THEN 4031 REWRITE_TAC[INTERIOR_SUBSET]]); 4032 4033val INTERIOR_FINITE_BIGINTER = store_thm ("INTERIOR_FINITE_BIGINTER", 4034 ``!s:(real->bool)->bool. 4035 FINITE s ==> (interior(BIGINTER s) = BIGINTER(IMAGE interior s))``, 4036 GEN_TAC THEN KNOW_TAC ``(interior (BIGINTER s) = BIGINTER (IMAGE interior s)) = 4037 (\s:(real->bool)->bool. (interior (BIGINTER s) = BIGINTER (IMAGE interior s))) s`` THENL 4038 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 4039 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 4040 REWRITE_TAC[BIGINTER_EMPTY, BIGINTER_INSERT, INTERIOR_UNIV, IMAGE_EMPTY, 4041 IMAGE_INSERT] THEN SIMP_TAC std_ss [INTERIOR_INTER]); 4042 4043val INTERIOR_BIGINTER_SUBSET = store_thm ("INTERIOR_BIGINTER_SUBSET", 4044 ``!f. interior(BIGINTER f) SUBSET BIGINTER (IMAGE interior f)``, 4045 REWRITE_TAC[SUBSET_DEF, IN_INTERIOR, IN_BIGINTER, FORALL_IN_IMAGE] THEN 4046 MESON_TAC[]); 4047 4048val UNION_INTERIOR_SUBSET = store_thm ("UNION_INTERIOR_SUBSET", 4049 ``!s t:real->bool. 4050 interior s UNION interior t SUBSET interior(s UNION t)``, 4051 SIMP_TAC std_ss [INTERIOR_MAXIMAL_EQ, OPEN_UNION, OPEN_INTERIOR] THEN 4052 REPEAT GEN_TAC THEN MATCH_MP_TAC(SET_RULE 4053 ``s SUBSET s' /\ t SUBSET t' ==> (s UNION t) SUBSET (s' UNION t')``) THEN 4054 REWRITE_TAC[INTERIOR_SUBSET]); 4055 4056val INTERIOR_EQ_EMPTY = store_thm ("INTERIOR_EQ_EMPTY", 4057 ``!s:real->bool. (interior s = {}) <=> !t. open t /\ t SUBSET s ==> (t = {})``, 4058 MESON_TAC[INTERIOR_MAXIMAL_EQ, SUBSET_EMPTY, 4059 OPEN_INTERIOR, INTERIOR_SUBSET]); 4060 4061val INTERIOR_EQ_EMPTY_ALT = store_thm ("INTERIOR_EQ_EMPTY_ALT", 4062 ``!s:real->bool. (interior s = {}) <=> 4063 !t. open t /\ ~(t = {}) ==> ~(t DIFF s = {})``, 4064 GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY] THEN SET_TAC[]); 4065 4066val INTERIOR_LIMIT_POINT = store_thm ("INTERIOR_LIMIT_POINT", 4067 ``!s x:real. x IN interior s ==> x limit_point_of s``, 4068 REPEAT GEN_TAC THEN 4069 SIMP_TAC std_ss [IN_INTERIOR, GSPECIFICATION, SUBSET_DEF, IN_BALL] THEN 4070 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 4071 REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC ``d:real`` THEN 4072 DISCH_TAC THEN 4073 MP_TAC(ISPECL [``x:real``, ``min d e / &2:real``] REAL_CHOOSE_DIST) THEN 4074 KNOW_TAC ``0 <= min d e / 2:real`` THENL 4075 [METIS_TAC [min_def, REAL_LE_LT, REAL_LT_HALF1], ALL_TAC] THEN 4076 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN 4077 EXISTS_TAC ``y:real`` THEN REPEAT CONJ_TAC THENL 4078 [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [] THEN 4079 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d e:real`` THEN 4080 METIS_TAC [REAL_MIN_LE1, min_def, REAL_LT_HALF2], 4081 CONV_TAC (RAND_CONV SYM_CONV) THEN REWRITE_TAC[DIST_NZ] THEN 4082 ASM_REWRITE_TAC [] THEN METIS_TAC [min_def, REAL_LE_LT, REAL_LT_HALF1], 4083 ONCE_REWRITE_TAC[DIST_SYM] THEN ASM_REWRITE_TAC [] THEN 4084 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d e:real`` THEN 4085 METIS_TAC [REAL_MIN_LE1, min_def, REAL_LT_HALF2]]); 4086 4087val INTERIOR_SING = store_thm ("INTERIOR_SING", 4088 ``!a:real. interior {a} = {}``, 4089 REWRITE_TAC[EXTENSION, NOT_IN_EMPTY] THEN 4090 MESON_TAC[INTERIOR_LIMIT_POINT, LIMPT_SING]); 4091 4092val INTERIOR_CLOSED_UNION_EMPTY_INTERIOR = store_thm ("INTERIOR_CLOSED_UNION_EMPTY_INTERIOR", 4093 ``!s t:real->bool. closed(s) /\ (interior(t) = {}) 4094 ==> (interior(s UNION t) = interior(s))``, 4095 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 4096 SIMP_TAC std_ss [SUBSET_INTERIOR, SUBSET_UNION] THEN 4097 REWRITE_TAC[SUBSET_DEF, IN_INTERIOR, IN_INTER, IN_UNION] THEN 4098 X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN 4099 ASM_REWRITE_TAC[] THEN X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 4100 SUBGOAL_THEN ``(y:real) limit_point_of s`` 4101 (fn th => ASM_MESON_TAC[CLOSED_LIMPT, th]) THEN 4102 REWRITE_TAC[IN_INTERIOR, NOT_IN_EMPTY, LIMPT_APPROACHABLE] THEN 4103 X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN 4104 SUBGOAL_THEN 4105 ``?z:real. ~(z IN t) /\ ~(z = y) /\ dist(z,y) < d /\ dist(x,z) < e`` 4106 (fn th => ASM_MESON_TAC[th, IN_BALL]) THEN 4107 UNDISCH_TAC ``y IN ball (x,e)`` THEN REWRITE_TAC [IN_BALL] THEN 4108 DISCH_TAC THEN UNDISCH_TAC ``interior t = {}`` THEN 4109 GEN_REWR_TAC LAND_CONV [EXTENSION] THEN 4110 KNOW_TAC ``(!x e. ~(&0 < e /\ ball (x,e) SUBSET t)) 4111 ==> (?z. ~(z IN t) /\ ~(z = y) /\ dist (z,y) < d /\ dist (x,z) < e)`` THENL 4112 [ALL_TAC, SIMP_TAC std_ss [IN_INTERIOR, NOT_IN_EMPTY, NOT_EXISTS_THM]] THEN 4113 ABBREV_TAC ``k = min d (e - dist(x:real,y))`` THEN 4114 SUBGOAL_THEN ``&0 < k:real`` ASSUME_TAC THENL 4115 [METIS_TAC [min_def, REAL_SUB_LT], ALL_TAC] THEN 4116 SUBGOAL_THEN ``?w:real. dist(y,w) = k / &2`` CHOOSE_TAC THENL 4117 [ASM_SIMP_TAC std_ss [REAL_CHOOSE_DIST, REAL_HALF, REAL_LT_IMP_LE], ALL_TAC] THEN 4118 DISCH_THEN(MP_TAC o SPECL [``w:real``, ``k / &4:real``]) THEN 4119 ASM_SIMP_TAC arith_ss [SUBSET_DEF, NOT_FORALL_THM, REAL_LT_DIV, REAL_LT, 4120 NOT_IMP, IN_BALL] THEN DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN 4121 EXISTS_TAC ``z:real`` THEN POP_ASSUM MP_TAC THEN 4122 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN ASM_REWRITE_TAC[] THEN 4123 DISCH_TAC THEN REPEAT CONJ_TAC THENL 4124 [CCONTR_TAC THEN FULL_SIMP_TAC std_ss [DIST_SYM] THEN 4125 UNDISCH_TAC `` dist (w,y) < k / 4`` THEN ASM_REWRITE_TAC [REAL_NOT_LT, REAL_LE_LT] THEN 4126 DISJ1_TAC THEN KNOW_TAC ``k < k / 2 * 4:real`` THENL 4127 [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN 4128 REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN 4129 SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN 4130 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN 4131 ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN 4132 GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD], 4133 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``dist (z, w) + dist (w, y:real)`` THEN 4134 REWRITE_TAC [DIST_TRIANGLE] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN 4135 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d (e - dist (x,y))`` THEN 4136 ASM_REWRITE_TAC [REAL_MIN_LE1] THEN 4137 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN REWRITE_TAC [REAL_LT_RADD] THEN 4138 MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC ``k / 4:real`` THEN 4139 ASM_REWRITE_TAC [] THEN KNOW_TAC ``k < k / 2 * 4:real`` THENL 4140 [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN 4141 REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN 4142 SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN 4143 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN 4144 ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN 4145 GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD], 4146 Cases_on `d <= (e - dist (x,y))` THENL 4147 [ALL_TAC, FULL_SIMP_TAC std_ss [min_def] THEN 4148 FULL_SIMP_TAC std_ss [REAL_ARITH ``(a - b = c) = (a = c + b:real)``] THEN 4149 ONCE_REWRITE_TAC [REAL_ADD_SYM] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 4150 EXISTS_TAC ``dist (x, y) + dist (y, z:real)`` THEN 4151 REWRITE_TAC [DIST_TRIANGLE, REAL_LT_LADD] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 4152 EXISTS_TAC ``dist (y,w) + dist (w, z:real)`` THEN ASM_REWRITE_TAC [DIST_TRIANGLE] THEN 4153 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN REWRITE_TAC [REAL_LT_LADD] THEN 4154 MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC ``k / 4:real`` THEN 4155 ASM_REWRITE_TAC [] THEN KNOW_TAC ``k < k / 2 * 4:real`` THENL 4156 [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN 4157 REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN 4158 SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN 4159 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN 4160 ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN 4161 GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD]] THEN 4162 FULL_SIMP_TAC std_ss [min_def, REAL_LE_SUB_LADD] THEN 4163 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``d + dist (x,y)`` THEN 4164 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ADD_SYM] THEN 4165 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``dist (x, y) + dist (y, z:real)`` THEN 4166 REWRITE_TAC [DIST_TRIANGLE, REAL_LT_LADD] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 4167 EXISTS_TAC ``dist (y,w) + dist (w, z:real)`` THEN REWRITE_TAC [DIST_TRIANGLE] THEN 4168 ASM_REWRITE_TAC [] THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 4169 ASM_REWRITE_TAC [REAL_LT_LADD] THEN MATCH_MP_TAC REAL_LT_TRANS THEN 4170 EXISTS_TAC ``k / 4:real`` THEN ASM_REWRITE_TAC [] THEN 4171 KNOW_TAC ``k < k / 2 * 4:real`` THENL 4172 [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN 4173 REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN 4174 SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN 4175 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN 4176 ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN 4177 GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD]]); 4178 4179val INTERIOR_UNION_EQ_EMPTY = store_thm ("INTERIOR_UNION_EQ_EMPTY", 4180 ``!s t:real->bool. closed s \/ closed t 4181 ==> ((interior(s UNION t) = {}) <=> 4182 (interior s = {}) /\ (interior t = {}))``, 4183REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THENL 4184[ASM_MESON_TAC[SUBSET_UNION, SUBSET_INTERIOR, SUBSET_EMPTY], 4185 ASM_MESON_TAC[UNION_COMM, INTERIOR_CLOSED_UNION_EMPTY_INTERIOR]]); 4186 4187val INTERIOR_UNIONS_OPEN_SUBSETS = store_thm ("INTERIOR_UNIONS_OPEN_SUBSETS", 4188 ``!s:real->bool. BIGUNION {t | open t /\ t SUBSET s} = interior s``, 4189 GEN_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN 4190 SIMP_TAC std_ss [OPEN_BIGUNION, GSPECIFICATION] THEN SET_TAC[]); 4191 4192(* ------------------------------------------------------------------------- *) 4193(* More variants of the Archimedian property and useful consequences. *) 4194(* ------------------------------------------------------------------------- *) 4195 4196val REAL_ARCH_INV = store_thm ("REAL_ARCH_INV", 4197 ``!e. &0 < e <=> ?n. ~(n = 0) /\ &0:real < inv(&n) /\ inv(&n) < e:real``, 4198 GEN_TAC THEN EQ_TAC THENL [ALL_TAC, MESON_TAC[REAL_LT_TRANS]] THEN 4199 DISCH_TAC THEN MP_TAC(SPEC ``inv(e:real)`` REAL_BIGNUM) THEN 4200 STRIP_TAC THEN EXISTS_TAC ``n:num`` THEN 4201 ASM_MESON_TAC[REAL_LT_INV, REAL_INV_INV, REAL_LT_INV_EQ, REAL_LT_TRANS, 4202 REAL_LT_ANTISYM]); 4203 4204val REAL_POW_LBOUND = store_thm ("REAL_POW_LBOUND", 4205 ``!x:real n. &0 <= x ==> &1 + &n * x <= (&1 + x) pow n``, 4206 GEN_TAC THEN SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN DISCH_TAC THEN 4207 INDUCT_TAC THEN 4208 REWRITE_TAC[pow, REAL_MUL_LZERO, REAL_ADD_RID, REAL_LE_REFL] THEN 4209 REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN 4210 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``(&1 + x) * (&1 + &n * x:real)`` THEN 4211 ASM_SIMP_TAC std_ss [REAL_LE_LMUL, REAL_ARITH ``&0 <= x:real ==> &0 <= &1 + x``, 4212 REAL_LE_MUL, REAL_LE_LMUL_IMP, REAL_POS, pow, REAL_ARITH 4213 ``&1 + (n + &1) * x:real <= (&1 + x) * (&1 + n * x) <=> &0 <= n * x * x``]); 4214 4215val REAL_ARCH_POW = store_thm ("REAL_ARCH_POW", 4216 ``!x:real y. &1 < x ==> ?n. y < x pow n``, 4217 REPEAT STRIP_TAC THEN 4218 MP_TAC(SPEC ``x:real - &1`` REAL_ARCH) THEN ASM_REWRITE_TAC[REAL_SUB_LT] THEN 4219 DISCH_THEN(MP_TAC o SPEC ``y:real``) THEN STRIP_TAC THEN 4220 EXISTS_TAC ``n:num`` THEN MATCH_MP_TAC REAL_LTE_TRANS THEN 4221 EXISTS_TAC ``&1 + &n * (x:real - &1)`` THEN 4222 ASM_SIMP_TAC std_ss [REAL_ARITH ``x:real < y ==> x < &1 + y``] THEN 4223 ASM_MESON_TAC[REAL_POW_LBOUND, REAL_SUB_ADD2, REAL_ARITH 4224 ``&1 < x:real ==> &0 <= x - &1``]); 4225 4226val REAL_ARCH_POW2 = store_thm ("REAL_ARCH_POW2", 4227 ``!x:real. ?n. x < &2:real pow n``, 4228 SIMP_TAC std_ss [REAL_ARCH_POW, REAL_ARITH ``1 < 2:real``]); 4229 4230val REAL_ARCH_POW_INV = store_thm ("REAL_ARCH_POW_INV", 4231 ``!x:real y. &0 < y /\ x < &1 ==> ?n. x pow n < y``, 4232 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``&0 < x:real`` THENL 4233 [ALL_TAC, ASM_MESON_TAC[POW_1, REAL_LET_TRANS, REAL_NOT_LT]] THEN 4234 SUBGOAL_THEN ``inv(&1) < inv(x:real)`` MP_TAC THENL 4235 [ASM_SIMP_TAC std_ss [REAL_LT_INV], REWRITE_TAC[REAL_INV1]] THEN 4236 DISCH_THEN(MP_TAC o SPEC ``inv(y:real)`` o MATCH_MP REAL_ARCH_POW) THEN 4237 STRIP_TAC THEN EXISTS_TAC ``n:num`` THEN 4238 GEN_REWR_TAC BINOP_CONV [GSYM REAL_INV_INV] THEN 4239 ASM_SIMP_TAC std_ss [GSYM REAL_POW_INV, REAL_LT_INV_EQ, REAL_LT_INV]); 4240 4241val FORALL_POS_MONO = store_thm ("FORALL_POS_MONO", 4242 ``!P. (!d e:real. d < e /\ P d ==> P e) /\ (!n. ~(n = 0) ==> P(inv(&n))) 4243 ==> !e. &0 < e ==> P e``, 4244 MESON_TAC[REAL_ARCH_INV, REAL_LT_TRANS]); 4245 4246val FORALL_SUC = store_thm ("FORALL_SUC", 4247 ``(!n. n <> 0 ==> P n) <=> !n. P (SUC n)``, 4248 EQ_TAC THENL [RW_TAC arith_ss [SUC_NOT, REAL_OF_NUM_EQ], 4249 METIS_TAC [REAL_NZ_IMP_LT, SUC_PRE, REAL_LT, REAL_OF_NUM_EQ]]); 4250 4251val LT_NZ = store_thm ("LT_NZ", 4252 ``!n:num. 0 < n <=> ~(n = 0)``, 4253 INDUCT_TAC THEN ASM_SIMP_TAC std_ss [NOT_SUC, LT, EQ_SYM_EQ] THEN 4254 TAUT_TAC); 4255 4256val REAL_ARCH_RDIV_EQ_0 = store_thm ("REAL_ARCH_RDIV_EQ_0", 4257 ``!x c:real. &0 <= x /\ &0 <= c /\ (!m. 0 < m ==> &m * x <= c) ==> (x = &0)``, 4258 SIMP_TAC std_ss [GSYM REAL_LE_ANTISYM, GSYM REAL_NOT_LT] THEN REPEAT STRIP_TAC THEN 4259 POP_ASSUM (STRIP_ASSUME_TAC o SPEC ``c:real`` o MATCH_MP REAL_ARCH) THEN 4260 ASM_CASES_TAC ``n=0:num`` THENL 4261 [POP_ASSUM SUBST_ALL_TAC THEN 4262 RULE_ASSUM_TAC (REWRITE_RULE [REAL_MUL_LZERO]) THEN 4263 ASM_MESON_TAC [REAL_LET_ANTISYM], 4264 ASM_MESON_TAC [REAL_LET_ANTISYM, REAL_MUL_SYM, LT_NZ]]); 4265 4266(* ------------------------------------------------------------------------- *) 4267(* Closure of a set. *) 4268(* ------------------------------------------------------------------------- *) 4269 4270val closure = new_definition ("closure", 4271 ``closure s = s UNION {x | x limit_point_of s}``); 4272 4273val CLOSURE_APPROACHABLE = store_thm ("CLOSURE_APPROACHABLE", 4274 ``!x s. x IN closure(s) <=> !e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e``, 4275 SIMP_TAC std_ss [closure, LIMPT_APPROACHABLE, IN_UNION, GSPECIFICATION] THEN 4276 MESON_TAC[DIST_REFL]); 4277 4278val CLOSURE_NONEMPTY_OPEN_INTER = store_thm ("CLOSURE_NONEMPTY_OPEN_INTER", 4279 ``!s x:real. x IN closure s <=> !t. x IN t /\ open t ==> ~(s INTER t = {})``, 4280 REPEAT GEN_TAC THEN SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION] THEN 4281 REWRITE_TAC[limit_point_of] THEN SET_TAC[]); 4282 4283val CLOSURE_INTERIOR = store_thm ("CLOSURE_INTERIOR", 4284 ``!s:real->bool. closure s = UNIV DIFF (interior (UNIV DIFF s))``, 4285 SIMP_TAC std_ss [EXTENSION, closure, IN_UNION, IN_DIFF, IN_UNIV, interior, 4286 GSPECIFICATION, limit_point_of, SUBSET_DEF] THEN 4287 MESON_TAC[]); 4288 4289val INTERIOR_CLOSURE = store_thm ("INTERIOR_CLOSURE", 4290 ``!s:real->bool. interior s = UNIV DIFF (closure (UNIV DIFF s))``, 4291 REWRITE_TAC[CLOSURE_INTERIOR, SET_RULE ``!s t. UNIV DIFF (UNIV DIFF t) = t``]); 4292 4293val CLOSED_CLOSURE = store_thm ("CLOSED_CLOSURE", 4294 ``!s. closed(closure s)``, 4295 REWRITE_TAC[closed_def, CLOSURE_INTERIOR, SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``, 4296 OPEN_INTERIOR]); 4297 4298val CLOSURE_HULL = store_thm ("CLOSURE_HULL", 4299 ``!s. closure s = closed hull s``, 4300 GEN_TAC THEN MATCH_MP_TAC(GSYM HULL_UNIQUE) THEN 4301 REWRITE_TAC[CLOSED_CLOSURE, SUBSET_DEF] THEN 4302 SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION, CLOSED_LIMPT] THEN 4303 MESON_TAC[limit_point_of]); 4304 4305val CLOSURE_EQ = store_thm ("CLOSURE_EQ", 4306 ``!s. (closure s = s) <=> closed s``, 4307 SIMP_TAC std_ss [CLOSURE_HULL, HULL_EQ, CLOSED_BIGINTER]); 4308 4309val CLOSURE_CLOSED = store_thm ("CLOSURE_CLOSED", 4310 ``!s. closed s ==> (closure s = s)``, 4311 MESON_TAC[CLOSURE_EQ]); 4312 4313val CLOSURE_CLOSURE = store_thm ("CLOSURE_CLOSURE", 4314 ``!s. closure(closure s) = closure s``, 4315 REWRITE_TAC[CLOSURE_HULL, HULL_HULL]); 4316 4317val CLOSURE_SUBSET = store_thm ("CLOSURE_SUBSET", 4318 ``!s. s SUBSET (closure s)``, 4319 REWRITE_TAC[CLOSURE_HULL, HULL_SUBSET]); 4320 4321val SUBSET_CLOSURE = store_thm ("SUBSET_CLOSURE", 4322 ``!s t. s SUBSET t ==> (closure s) SUBSET (closure t)``, 4323 REWRITE_TAC[CLOSURE_HULL, HULL_MONO]); 4324 4325val CLOSURE_UNION = store_thm ("CLOSURE_UNION", 4326 ``!s t:real->bool. closure(s UNION t) = closure s UNION closure t``, 4327 REWRITE_TAC[LIMIT_POINT_UNION, closure] THEN SET_TAC[]); 4328 4329val CLOSURE_INTER_SUBSET = store_thm ("CLOSURE_INTER_SUBSET", 4330 ``!s t. closure(s INTER t) SUBSET closure(s) INTER closure(t)``, 4331 REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET_INTER] THEN 4332 CONJ_TAC THEN MATCH_MP_TAC SUBSET_CLOSURE THEN SET_TAC[]); 4333 4334val CLOSURE_BIGINTER_SUBSET = store_thm ("CLOSURE_BIGINTER_SUBSET", 4335 ``!f. closure(BIGINTER f) SUBSET BIGINTER (IMAGE closure f)``, 4336 REWRITE_TAC[SET_RULE ``s SUBSET BIGINTER f <=> !t. t IN f ==> s SUBSET t``] THEN 4337 REWRITE_TAC[FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN 4338 MATCH_MP_TAC SUBSET_CLOSURE THEN ASM_SET_TAC[]); 4339 4340val CLOSURE_MINIMAL = store_thm ("CLOSURE_MINIMAL", 4341 ``!s t. s SUBSET t /\ closed t ==> (closure s) SUBSET t``, 4342 REWRITE_TAC[HULL_MINIMAL, CLOSURE_HULL]); 4343 4344val CLOSURE_MINIMAL_EQ = store_thm ("CLOSURE_MINIMAL_EQ", 4345 ``!s t:real->bool. closed t ==> (closure s SUBSET t <=> s SUBSET t)``, 4346 MESON_TAC[SUBSET_TRANS, CLOSURE_SUBSET, CLOSURE_MINIMAL]); 4347 4348val CLOSURE_UNIQUE = store_thm ("CLOSURE_UNIQUE", 4349 ``!s t. s SUBSET t /\ closed t /\ 4350 (!t'. s SUBSET t' /\ closed t' ==> t SUBSET t') 4351 ==> (closure s = t)``, 4352 REWRITE_TAC[CLOSURE_HULL, HULL_UNIQUE]); 4353 4354val CLOSURE_EMPTY = store_thm ("CLOSURE_EMPTY", 4355 ``closure {} = {}``, 4356 SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_EMPTY]); 4357 4358val CLOSURE_UNIV = store_thm ("CLOSURE_UNIV", 4359 ``closure univ(:real) = univ(:real)``, 4360 SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_UNIV]); 4361 4362val CLOSURE_BIGUNION = store_thm ("CLOSURE_BIGUNION", 4363 ``!f. FINITE f ==> (closure(BIGUNION f) = BIGUNION {closure s | s IN f})``, 4364 KNOW_TAC ``!f. (closure(BIGUNION f) = BIGUNION {closure s | s IN f}) = 4365 (\f. closure(BIGUNION f) = BIGUNION {closure s | s IN f}) f`` THENL 4366 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 4367 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 4368 SIMP_TAC std_ss [BIGUNION_EMPTY, BIGUNION_INSERT, SET_RULE ``{f x | x IN {}} = {}``, 4369 SET_RULE ``{f x | x IN a INSERT s} = (f a) INSERT {f x | x IN s}``] THEN 4370 SIMP_TAC std_ss [CLOSURE_EMPTY, CLOSURE_UNION]); 4371 4372val CLOSURE_EQ_EMPTY = store_thm ("CLOSURE_EQ_EMPTY", 4373 ``!s. (closure s = {}) <=> (s = {})``, 4374 GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CLOSURE_EMPTY] THEN 4375 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (t = {}) ==> (s = {})``) THEN 4376 REWRITE_TAC[CLOSURE_SUBSET]); 4377 4378val CLOSURE_SUBSET_EQ = store_thm ("CLOSURE_SUBSET_EQ", 4379 ``!s:real->bool. closure s SUBSET s <=> closed s``, 4380 GEN_TAC THEN REWRITE_TAC[GSYM CLOSURE_EQ] THEN 4381 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN SET_TAC[]); 4382 4383val OPEN_INTER_CLOSURE_EQ_EMPTY = store_thm ("OPEN_INTER_CLOSURE_EQ_EMPTY", 4384 ``!s t:real->bool. 4385 open s ==> ((s INTER (closure t) = {}) <=> (s INTER t = {}))``, 4386 REPEAT STRIP_TAC THEN EQ_TAC THENL 4387 [MP_TAC(ISPEC ``t:real->bool`` CLOSURE_SUBSET) THEN SET_TAC[], ALL_TAC] THEN 4388 DISCH_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN 4389 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (s INTER (UNIV DIFF t) = {})``) THEN 4390 ASM_SIMP_TAC std_ss [OPEN_SUBSET_INTERIOR] THEN 4391 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 4392 4393val CLOSURE_OPEN_IN_INTER_CLOSURE = store_thm ("CLOSURE_OPEN_IN_INTER_CLOSURE", 4394 ``!s t u:real->bool. 4395 open_in (subtopology euclidean u) s /\ t SUBSET u 4396 ==> (closure(s INTER closure t) = closure(s INTER t))``, 4397 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 4398 SIMP_TAC std_ss [CLOSURE_SUBSET, SUBSET_CLOSURE, SET_RULE 4399 ``t SUBSET u ==> s INTER t SUBSET s INTER u``] THEN 4400 REWRITE_TAC[SUBSET_DEF, CLOSURE_APPROACHABLE] THEN 4401 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 4402 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 4403 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 4404 ASM_REWRITE_TAC[REAL_LT_HALF1, IN_INTER, CLOSURE_APPROACHABLE] THEN 4405 DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN 4406 UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN 4407 REWRITE_TAC [open_in] THEN REWRITE_TAC[SUBSET_DEF] THEN 4408 DISCH_THEN(CONJUNCTS_THEN(MP_TAC o SPEC ``y:real``)) THEN 4409 ASM_REWRITE_TAC[] THEN 4410 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN DISCH_TAC THEN 4411 UNDISCH_TAC ``!e. 0 < e ==> ?y'. y' IN t /\ dist (y',y) < e`` THEN 4412 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``min d (e / &2:real)``) THEN 4413 ASM_REWRITE_TAC[REAL_LT_HALF1, REAL_LT_MIN] THEN 4414 DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN 4415 POP_ASSUM MP_TAC THEN 4416 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF]) THEN ASM_SIMP_TAC std_ss [] THEN 4417 STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 4418 EXISTS_TAC ``dist(z,y) + dist(y,x)`` THEN REWRITE_TAC [DIST_TRIANGLE] THEN 4419 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 4420 MATCH_MP_TAC REAL_LT_ADD2 THEN ASM_REWRITE_TAC []); 4421 4422val CLOSURE_OPEN_INTER_CLOSURE = store_thm ("CLOSURE_OPEN_INTER_CLOSURE", 4423 ``!s t:real->bool. 4424 open s ==> (closure(s INTER closure t) = closure(s INTER t))``, 4425 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_OPEN_IN_INTER_CLOSURE THEN 4426 EXISTS_TAC ``univ(:real)`` THEN 4427 ASM_REWRITE_TAC[SUBSET_UNIV, GSYM OPEN_IN, SUBTOPOLOGY_UNIV]); 4428 4429val OPEN_INTER_CLOSURE_SUBSET = store_thm ("OPEN_INTER_CLOSURE_SUBSET", 4430 ``!s t:real->bool. 4431 open s ==> (s INTER (closure t)) SUBSET closure(s INTER t)``, 4432 REPEAT STRIP_TAC THEN 4433 SIMP_TAC std_ss [SUBSET_DEF, IN_INTER, closure, IN_UNION, GSPECIFICATION] THEN 4434 X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 4435 DISJ2_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN 4436 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 4437 UNDISCH_TAC ``open s`` THEN REWRITE_TAC [open_def] THEN 4438 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 4439 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 4440 UNDISCH_TAC ``x limit_point_of t`` THEN REWRITE_TAC [LIMPT_APPROACHABLE] THEN 4441 DISCH_THEN(MP_TAC o SPEC ``min d e:real``) THEN 4442 ASM_REWRITE_TAC[REAL_LT_MIN, IN_INTER] THEN STRIP_TAC THEN 4443 EXISTS_TAC ``x':real`` THEN ASM_MESON_TAC[]); 4444 4445val CLOSURE_OPEN_INTER_SUPERSET = store_thm ("CLOSURE_OPEN_INTER_SUPERSET", 4446 ``!s t:real->bool. 4447 open s /\ s SUBSET closure t ==> (closure(s INTER t) = closure s)``, 4448 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 4449 SIMP_TAC std_ss [SUBSET_CLOSURE, INTER_SUBSET] THEN 4450 MATCH_MP_TAC CLOSURE_MINIMAL THEN REWRITE_TAC[CLOSED_CLOSURE] THEN 4451 W(MP_TAC o PART_MATCH (rand o rand) OPEN_INTER_CLOSURE_SUBSET o rand o snd) THEN 4452 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] SUBSET_TRANS) THEN 4453 ASM_SET_TAC[]); 4454 4455val CLOSURE_COMPLEMENT = store_thm ("CLOSURE_COMPLEMENT", 4456 ``!s:real->bool. closure(UNIV DIFF s) = UNIV DIFF interior(s)``, 4457 REWRITE_TAC[SET_RULE ``(s = UNIV DIFF t) <=> (UNIV DIFF s = t)``] THEN 4458 REWRITE_TAC[GSYM INTERIOR_CLOSURE]); 4459 4460val INTERIOR_COMPLEMENT = store_thm ("INTERIOR_COMPLEMENT", 4461 ``!s:real->bool. interior(UNIV DIFF s) = UNIV DIFF closure(s)``, 4462 REWRITE_TAC[SET_RULE ``(s = UNIV DIFF t) <=> (UNIV DIFF s = t)``] THEN 4463 REWRITE_TAC[GSYM CLOSURE_INTERIOR]); 4464 4465val CONNECTED_INTERMEDIATE_CLOSURE = store_thm ("CONNECTED_INTERMEDIATE_CLOSURE", 4466 ``!s t:real->bool. 4467 connected s /\ s SUBSET t /\ t SUBSET closure s ==> connected t``, 4468 REPEAT GEN_TAC THEN 4469 KNOW_TAC ``(!e1 e2. 4470 ~(open e1 /\ open e2 /\ 4471 s SUBSET e1 UNION e2 /\ (e1 INTER e2 INTER s = {}) /\ 4472 ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))) /\ 4473 s SUBSET t /\ t SUBSET closure s 4474 ==> (!e1 e2. 4475 ~(open e1 /\ open e2 /\ 4476 t SUBSET e1 UNION e2 /\ (e1 INTER e2 INTER t = {}) /\ 4477 ~(e1 INTER t = {}) /\ ~(e2 INTER t = {})))`` THENL 4478 [ALL_TAC, SIMP_TAC std_ss [connected, NOT_EXISTS_THM]] THEN 4479 STRIP_TAC THEN MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 4480 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL [``u:real->bool``, ``v:real->bool``]) THEN 4481 ASM_REWRITE_TAC[] THEN ASSUME_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN 4482 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 4483 REWRITE_TAC[GSYM DE_MORGAN_THM] THEN STRIP_TAC THENL 4484 [SUBGOAL_THEN ``(closure s) SUBSET (univ(:real) DIFF u)`` MP_TAC THENL 4485 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED], ALL_TAC], 4486 SUBGOAL_THEN ``(closure s) SUBSET (univ(:real) DIFF v)`` MP_TAC THENL 4487 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED], 4488 ALL_TAC]] THEN ASM_SET_TAC[]); 4489 4490val CONNECTED_CLOSURE = store_thm ("CONNECTED_CLOSURE", 4491 ``!s:real->bool. connected s ==> connected(closure s)``, 4492 MESON_TAC[CONNECTED_INTERMEDIATE_CLOSURE, CLOSURE_SUBSET, SUBSET_REFL]); 4493 4494val CONNECTED_UNION_STRONG = store_thm ("CONNECTED_UNION_STRONG", 4495 ``!s t:real->bool. 4496 connected s /\ connected t /\ ~(closure s INTER t = {}) 4497 ==> connected(s UNION t)``, 4498 REPEAT STRIP_TAC THEN 4499 POP_ASSUM (MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 4500 DISCH_THEN(X_CHOOSE_TAC ``p:real``) THEN 4501 SUBGOAL_THEN ``s UNION t = ((p:real) INSERT s) UNION t`` SUBST1_TAC THENL 4502 [ASM_SET_TAC[], ALL_TAC] THEN 4503 MATCH_MP_TAC CONNECTED_UNION THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL 4504 [MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN 4505 EXISTS_TAC ``s:real->bool`` THEN ASM_REWRITE_TAC[] THEN 4506 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[], 4507 ASM_SET_TAC[]]); 4508 4509val INTERIOR_DIFF = store_thm ("INTERIOR_DIFF", 4510 ``!s t. interior(s DIFF t) = interior(s) DIFF closure(t)``, 4511 ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN 4512 REWRITE_TAC[INTERIOR_INTER, CLOSURE_INTERIOR] THEN SET_TAC[]); 4513 4514val LIMPT_OF_CLOSURE = store_thm ("LIMPT_OF_CLOSURE", 4515 ``!x:real s. x limit_point_of closure s <=> x limit_point_of s``, 4516 SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION, LIMIT_POINT_UNION] THEN 4517 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT `(q ==> p) ==> (p \/ q <=> p)`) THEN 4518 REWRITE_TAC[LIMPT_OF_LIMPTS]); 4519 4520val CLOSED_IN_LIMPT = store_thm ("CLOSED_IN_LIMPT", 4521 ``!s t. closed_in (subtopology euclidean t) s <=> 4522 s SUBSET t /\ !x:real. x limit_point_of s /\ x IN t ==> x IN s``, 4523 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN EQ_TAC THENL 4524 [DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 4525 ASM_SIMP_TAC std_ss [IN_INTER] THEN 4526 ASM_MESON_TAC[CLOSED_LIMPT, LIMPT_SUBSET, INTER_SUBSET], 4527 STRIP_TAC THEN EXISTS_TAC ``closure s :real->bool`` THEN 4528 REWRITE_TAC[CLOSED_CLOSURE] THEN REWRITE_TAC[closure] THEN 4529 ASM_SET_TAC[]]); 4530 4531val CLOSED_IN_INTER_CLOSURE = store_thm ("CLOSED_IN_INTER_CLOSURE", 4532 ``!s t:real->bool. 4533 closed_in (subtopology euclidean s) t <=> (s INTER closure t = t)``, 4534 REWRITE_TAC[closure, CLOSED_IN_LIMPT] THEN SET_TAC[]); 4535 4536val INTERIOR_CLOSURE_IDEMP = store_thm ("INTERIOR_CLOSURE_IDEMP", 4537 ``!s:real->bool. 4538 interior(closure(interior(closure s))) = interior(closure s)``, 4539 GEN_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN 4540 ASM_MESON_TAC[OPEN_INTERIOR, CLOSURE_SUBSET, CLOSURE_CLOSURE, SUBSET_TRANS, 4541 OPEN_SUBSET_INTERIOR, SUBSET_CLOSURE, INTERIOR_SUBSET]); 4542 4543val CLOSURE_INTERIOR_IDEMP = store_thm ("CLOSURE_INTERIOR_IDEMP", 4544 ``!s:real->bool. 4545 closure(interior(closure(interior s))) = closure(interior s)``, 4546 GEN_TAC THEN 4547 ONCE_REWRITE_TAC[SET_RULE ``(s = t) <=> (UNIV DIFF s = UNIV DIFF t)``] THEN 4548 REWRITE_TAC[GSYM INTERIOR_COMPLEMENT, GSYM CLOSURE_COMPLEMENT] THEN 4549 REWRITE_TAC[INTERIOR_CLOSURE_IDEMP]); 4550 4551val NOWHERE_DENSE_UNION = store_thm ("NOWHERE_DENSE_UNION", 4552 ``!s t:real->bool. 4553 (interior(closure(s UNION t)) = {}) <=> 4554 (interior(closure s) = {}) /\ (interior(closure t) = {})``, 4555 SIMP_TAC std_ss [CLOSURE_UNION, INTERIOR_UNION_EQ_EMPTY, CLOSED_CLOSURE]); 4556 4557val NOWHERE_DENSE = store_thm ("NOWHERE_DENSE", 4558 ``!s:real->bool. (interior(closure s) = {}) <=> 4559 !t. open t /\ ~(t = {}) 4560 ==> ?u. open u /\ ~(u = {}) /\ u SUBSET t /\ (u INTER s = {})``, 4561 GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY_ALT] THEN EQ_TAC THEN 4562 DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN STRIP_TAC THENL 4563 [EXISTS_TAC ``t DIFF closure s:real->bool`` THEN 4564 ASM_SIMP_TAC std_ss [OPEN_DIFF, CLOSED_CLOSURE] THEN 4565 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN SET_TAC[], 4566 FIRST_X_ASSUM(MP_TAC o SPEC ``t:real->bool``) THEN ASM_REWRITE_TAC[] THEN 4567 DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 4568 MP_TAC(ISPECL [``u:real->bool``, ``s:real->bool``] 4569 OPEN_INTER_CLOSURE_EQ_EMPTY) THEN ASM_SET_TAC[]]); 4570 4571val INTERIOR_CLOSURE_INTER_OPEN = store_thm ("INTERIOR_CLOSURE_INTER_OPEN", 4572 ``!s t:real->bool. open s /\ open t 4573 ==> (interior(closure(s INTER t)) = 4574 interior(closure s) INTER interior(closure t))``, 4575 REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE 4576 ``(u = s INTER t) <=> s INTER t SUBSET u /\ u SUBSET s /\ u SUBSET t``] THEN 4577 SIMP_TAC std_ss [SUBSET_INTERIOR, SUBSET_CLOSURE, INTER_SUBSET] THEN 4578 MATCH_MP_TAC INTERIOR_MAXIMAL THEN SIMP_TAC std_ss [OPEN_INTER, OPEN_INTERIOR] THEN 4579 REWRITE_TAC[SET_RULE ``s SUBSET t <=> (s INTER (UNIV DIFF t) = {})``, 4580 GSYM INTERIOR_COMPLEMENT] THEN 4581 REWRITE_TAC[GSYM INTERIOR_INTER] THEN 4582 REWRITE_TAC[INTERIOR_EQ_EMPTY] THEN 4583 X_GEN_TAC ``u:real->bool`` THEN STRIP_TAC THEN 4584 MP_TAC(ISPECL [``u INTER s:real->bool``, ``t:real->bool``] 4585 OPEN_INTER_CLOSURE_EQ_EMPTY) THEN 4586 MP_TAC(ISPECL [``u:real->bool``, ``s:real->bool``] 4587 OPEN_INTER_CLOSURE_EQ_EMPTY) THEN 4588 ASM_SIMP_TAC std_ss [OPEN_INTER] THEN ASM_SET_TAC[]); 4589 4590val CLOSURE_INTERIOR_UNION_CLOSED = store_thm ("CLOSURE_INTERIOR_UNION_CLOSED", 4591 ``!s t:real->bool. closed s /\ closed t 4592 ==> (closure (interior (s UNION t)) = 4593 closure (interior s) UNION closure(interior t))``, 4594 REPEAT GEN_TAC THEN REWRITE_TAC[closed_def] THEN 4595 DISCH_THEN(MP_TAC o MATCH_MP INTERIOR_CLOSURE_INTER_OPEN) THEN 4596 REWRITE_TAC[CLOSURE_COMPLEMENT, INTERIOR_COMPLEMENT, 4597 SET_RULE ``(UNIV DIFF s) INTER (UNIV DIFF t) = UNIV DIFF (s UNION t)``] THEN 4598 SET_TAC[]); 4599 4600val REGULAR_OPEN_INTER = store_thm ("REGULAR_OPEN_INTER", 4601 ``!s t:real->bool. 4602 (interior(closure s) = s) /\ (interior(closure t) = t) 4603 ==> (interior(closure(s INTER t)) = s INTER t)``, 4604 MESON_TAC[INTERIOR_CLOSURE_INTER_OPEN, OPEN_INTERIOR]); 4605 4606val REGULAR_CLOSED_UNION = store_thm ("REGULAR_CLOSED_UNION", 4607 ``!s t:real->bool. 4608 (closure(interior s) = s) /\ (closure(interior t) = t) 4609 ==> (closure(interior(s UNION t)) = s UNION t)``, 4610 MESON_TAC[CLOSURE_INTERIOR_UNION_CLOSED, CLOSED_CLOSURE]); 4611 4612val REGULAR_CLOSED_BIGUNION = store_thm ("REGULAR_CLOSED_BIGUNION", 4613 ``!f:(real->bool)->bool. 4614 FINITE f /\ (!t. t IN f ==> (closure(interior t) = t)) 4615 ==> (closure(interior(BIGUNION f)) = BIGUNION f)``, 4616 REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 4617 KNOW_TAC ``!f. ((!t. t IN f ==> (closure(interior t) = t)) 4618 ==> (closure(interior(BIGUNION f)) = BIGUNION f)) = 4619 (\f. (!t. t IN f ==> (closure(interior t) = t)) 4620 ==> (closure(interior(BIGUNION f)) = BIGUNION f)) f`` THENL 4621 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 4622 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 4623 REWRITE_TAC[BIGUNION_INSERT, BIGUNION_EMPTY, INTERIOR_EMPTY, CLOSURE_EMPTY] THEN 4624 SIMP_TAC std_ss [FORALL_IN_INSERT, REGULAR_CLOSED_UNION]); 4625 4626val DIFF_CLOSURE_SUBSET = store_thm ("DIFF_CLOSURE_SUBSET", 4627 ``!s t:real->bool. closure(s) DIFF closure t SUBSET closure(s DIFF t)``, 4628 REPEAT GEN_TAC THEN 4629 MP_TAC(ISPECL [``univ(:real) DIFF closure t``, ``s:real->bool``] 4630 OPEN_INTER_CLOSURE_SUBSET) THEN 4631 REWRITE_TAC[SET_RULE ``(UNIV DIFF t) INTER s = s DIFF t``] THEN 4632 REWRITE_TAC[GSYM closed_def, CLOSED_CLOSURE] THEN 4633 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS) THEN 4634 MATCH_MP_TAC SUBSET_CLOSURE THEN 4635 MATCH_MP_TAC(SET_RULE ``t SUBSET u ==> s DIFF u SUBSET s DIFF t``) THEN 4636 REWRITE_TAC[CLOSURE_SUBSET]); 4637 4638val DENSE_OPEN_INTER = store_thm ("DENSE_OPEN_INTER", 4639 ``!s t u:real->bool. 4640 (open_in (subtopology euclidean u) s /\ t SUBSET u \/ 4641 open_in (subtopology euclidean u) t /\ s SUBSET u) 4642 ==> (u SUBSET closure (s INTER t) <=> 4643 u SUBSET closure s /\ u SUBSET closure t)``, 4644 KNOW_TAC ``((!s t u. 4645 (u SUBSET closure (s INTER t) <=> 4646 u SUBSET closure s /\ u SUBSET closure t) 4647 ==> (u SUBSET closure (t INTER s) <=> 4648 u SUBSET closure t /\ u SUBSET closure s)) /\ 4649 (!s t u. 4650 open_in (subtopology euclidean u) s /\ t SUBSET u 4651 ==> (u SUBSET closure (s INTER t) <=> 4652 u SUBSET closure s /\ u SUBSET closure t)))`` THENL 4653 [ALL_TAC, METIS_TAC []] THEN CONJ_TAC THENL 4654 [SIMP_TAC std_ss [INTER_COMM, CONJ_ACI], ALL_TAC] THEN 4655 REPEAT GEN_TAC THEN STRIP_TAC THEN EQ_TAC THENL 4656 [ASM_MESON_TAC[SUBSET_TRANS, SUBSET_CLOSURE, INTER_SUBSET], ALL_TAC] THEN 4657 REWRITE_TAC[SUBSET_DEF, CLOSURE_APPROACHABLE] THEN DISCH_TAC THEN 4658 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 4659 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 4660 FIRST_X_ASSUM(CONJUNCTS_THEN2 (MP_TAC o SPEC ``x:real``) ASSUME_TAC) THEN 4661 ASM_REWRITE_TAC[] THEN 4662 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN 4663 DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN 4664 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN 4665 UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN REWRITE_TAC [open_in] THEN 4666 REWRITE_TAC[SUBSET_DEF, IN_INTER] THEN 4667 DISCH_THEN(CONJUNCTS_THEN (MP_TAC o SPEC ``y:real``)) THEN 4668 ASM_REWRITE_TAC[] THEN 4669 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN DISCH_TAC THEN 4670 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min d (e / &2):real``) THEN 4671 ASM_REWRITE_TAC[REAL_HALF, REAL_LT_MIN] THEN 4672 DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN 4673 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF]) THEN ASM_SIMP_TAC std_ss [] THEN 4674 POP_ASSUM MP_TAC THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 4675 EXISTS_TAC ``dist(z,y) + dist(y,x)`` THEN REWRITE_TAC [DIST_TRIANGLE] THEN 4676 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 4677 MATCH_MP_TAC REAL_LT_ADD2 THEN ASM_REWRITE_TAC []); 4678 4679(* ------------------------------------------------------------------------- *) 4680(* Frontier (aka boundary). *) 4681(* ------------------------------------------------------------------------- *) 4682 4683val frontier = new_definition ("frontier", 4684 ``frontier s = (closure s) DIFF (interior s)``); 4685 4686val FRONTIER_CLOSED = store_thm ("FRONTIER_CLOSED", 4687 ``!s. closed(frontier s)``, 4688 SIMP_TAC std_ss [frontier, CLOSED_DIFF, CLOSED_CLOSURE, OPEN_INTERIOR]); 4689 4690val FRONTIER_CLOSURES = store_thm ("FRONTIER_CLOSURES", 4691 ``!s:real->bool. frontier s = (closure s) INTER (closure(UNIV DIFF s))``, 4692 REWRITE_TAC[frontier, INTERIOR_CLOSURE, 4693 SET_RULE ``s DIFF (UNIV DIFF t) = s INTER t``]); 4694 4695val FRONTIER_STRADDLE = store_thm ("FRONTIER_STRADDLE", 4696 ``!a:real s. 4697 a IN frontier s <=> !e. &0 < e ==> (?x. x IN s /\ dist(a,x) < e) /\ 4698 (?x. ~(x IN s) /\ dist(a,x) < e)``, 4699 REPEAT GEN_TAC THEN REWRITE_TAC[FRONTIER_CLOSURES, IN_INTER] THEN 4700 SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION, limit_point_of, 4701 IN_UNIV, IN_DIFF] THEN 4702 ASM_MESON_TAC[IN_BALL, SUBSET_DEF, OPEN_CONTAINS_BALL, 4703 CENTRE_IN_BALL, OPEN_BALL, DIST_REFL]); 4704 4705val FRONTIER_SUBSET_CLOSED = store_thm ("FRONTIER_SUBSET_CLOSED", 4706 ``!s. closed s ==> (frontier s) SUBSET s``, 4707 METIS_TAC[frontier, CLOSURE_CLOSED, DIFF_SUBSET]); 4708 4709val FRONTIER_EMPTY = store_thm ("FRONTIER_EMPTY", 4710 ``frontier {} = {}``, 4711 REWRITE_TAC[frontier, CLOSURE_EMPTY, EMPTY_DIFF]); 4712 4713val FRONTIER_UNIV = store_thm ("FRONTIER_UNIV", 4714 ``frontier univ(:real) = {}``, 4715 REWRITE_TAC[frontier, CLOSURE_UNIV, INTERIOR_UNIV] THEN SET_TAC[]); 4716 4717val FRONTIER_SUBSET_EQ = store_thm ("FRONTIER_SUBSET_EQ", 4718 ``!s:real->bool. (frontier s) SUBSET s <=> closed s``, 4719 GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [FRONTIER_SUBSET_CLOSED] THEN 4720 REWRITE_TAC[frontier] THEN 4721 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE 4722 ``s DIFF t SUBSET u ==> t SUBSET u ==> s SUBSET u``)) THEN 4723 REWRITE_TAC[INTERIOR_SUBSET, CLOSURE_SUBSET_EQ]); 4724 4725val FRONTIER_COMPLEMENT = store_thm ("FRONTIER_COMPLEMENT", 4726 ``!s:real->bool. frontier(UNIV DIFF s) = frontier s``, 4727 REWRITE_TAC[frontier, CLOSURE_COMPLEMENT, INTERIOR_COMPLEMENT] THEN 4728 SET_TAC[]); 4729 4730val FRONTIER_DISJOINT_EQ = store_thm ("FRONTIER_DISJOINT_EQ", 4731 ``!s. ((frontier s) INTER s = {}) <=> open s``, 4732 ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT, OPEN_CLOSED] THEN 4733 REWRITE_TAC[GSYM FRONTIER_SUBSET_EQ] THEN SET_TAC[]); 4734 4735val FRONTIER_INTER_SUBSET = store_thm ("FRONTIER_INTER_SUBSET", 4736 ``!s t. frontier(s INTER t) SUBSET frontier(s) UNION frontier(t)``, 4737 REPEAT GEN_TAC THEN REWRITE_TAC[frontier, INTERIOR_INTER] THEN 4738 MATCH_MP_TAC(SET_RULE ``cst SUBSET cs INTER ct 4739 ==> cst DIFF (s INTER t) SUBSET (cs DIFF s) UNION (ct DIFF t)``) THEN 4740 REWRITE_TAC[CLOSURE_INTER_SUBSET]); 4741 4742val FRONTIER_UNION_SUBSET = store_thm ("FRONTIER_UNION_SUBSET", 4743 ``!s t:real->bool. frontier(s UNION t) SUBSET frontier s UNION frontier t``, 4744 ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN 4745 REWRITE_TAC[SET_RULE ``u DIFF (s UNION t) = (u DIFF s) INTER (u DIFF t)``] THEN 4746 REWRITE_TAC[FRONTIER_INTER_SUBSET]); 4747 4748val FRONTIER_INTERIORS = store_thm ("FRONTIER_INTERIORS", 4749 ``!s. frontier s = univ(:real) DIFF interior(s) DIFF interior(univ(:real) DIFF s)``, 4750 REWRITE_TAC[frontier, CLOSURE_INTERIOR] THEN SET_TAC[]); 4751 4752val FRONTIER_FRONTIER_SUBSET = store_thm ("FRONTIER_FRONTIER_SUBSET", 4753 ``!s:real->bool. frontier(frontier s) SUBSET frontier s``, 4754 GEN_TAC THEN GEN_REWR_TAC LAND_CONV [frontier] THEN 4755 SIMP_TAC std_ss [CLOSURE_CLOSED, FRONTIER_CLOSED] THEN SET_TAC[]); 4756 4757val INTERIOR_FRONTIER = store_thm ("INTERIOR_FRONTIER", 4758 ``!s:real->bool. 4759 interior(frontier s) = interior(closure s) DIFF closure(interior s)``, 4760 ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN 4761 REWRITE_TAC[GSYM INTERIOR_COMPLEMENT, GSYM INTERIOR_INTER, frontier] THEN 4762 GEN_TAC THEN AP_TERM_TAC THEN SET_TAC[]); 4763 4764val INTERIOR_FRONTIER_EMPTY = store_thm ("INTERIOR_FRONTIER_EMPTY", 4765 ``!s:real->bool. open s \/ closed s ==> (interior(frontier s) = {})``, 4766 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[INTERIOR_FRONTIER] THEN 4767 ASM_SIMP_TAC std_ss [CLOSURE_CLOSED, INTERIOR_OPEN] THEN 4768 REWRITE_TAC[SET_RULE ``(s DIFF t = {}) <=> s SUBSET t``] THEN 4769 REWRITE_TAC[INTERIOR_SUBSET, CLOSURE_SUBSET]); 4770 4771val FRONTIER_FRONTIER = store_thm ("FRONTIER_FRONTIER", 4772 ``!s:real->bool. open s \/ closed s ==> (frontier(frontier s) = frontier s)``, 4773 GEN_TAC THEN GEN_REWR_TAC (RAND_CONV o LAND_CONV) [frontier] THEN STRIP_TAC THEN 4774 ASM_SIMP_TAC std_ss [INTERIOR_FRONTIER_EMPTY, CLOSURE_CLOSED, FRONTIER_CLOSED] THEN 4775 REWRITE_TAC[DIFF_EMPTY]); 4776 4777val FRONTIER_FRONTIER_FRONTIER = store_thm ("FRONTIER_FRONTIER_FRONTIER", 4778 ``!s:real->bool. frontier(frontier(frontier s)) = frontier(frontier s)``, 4779 SIMP_TAC std_ss [FRONTIER_FRONTIER, FRONTIER_CLOSED]); 4780 4781val lemma = prove ( 4782 ``!s t x. x IN frontier s /\ x IN interior t ==> x IN frontier(s INTER t)``, 4783 REWRITE_TAC[FRONTIER_STRADDLE, IN_INTER, IN_INTERIOR, SUBSET_DEF, IN_BALL] THEN 4784 REPEAT GEN_TAC THEN 4785 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_TAC ``d:real``)) THEN 4786 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 4787 FIRST_X_ASSUM(MP_TAC o SPEC ``min d e:real``) THEN 4788 ASM_REWRITE_TAC[REAL_LT_MIN] THEN ASM_MESON_TAC[]); 4789 4790val UNION_FRONTIER = store_thm ("UNION_FRONTIER", 4791 ``!s t:real->bool. frontier(s) UNION frontier(t) = 4792 frontier(s UNION t) UNION frontier(s INTER t) UNION 4793 frontier(s) INTER frontier(t)``, 4794 REWRITE_TAC[SET_EQ_SUBSET, UNION_SUBSET, 4795 FRONTIER_UNION_SUBSET, FRONTIER_INTER_SUBSET, 4796 SET_RULE ``s INTER t SUBSET s UNION t``] THEN 4797 REWRITE_TAC[GSYM UNION_SUBSET] THEN REWRITE_TAC[SUBSET_DEF, IN_UNION] THEN 4798 KNOW_TAC ``((!s t x. x IN frontier s 4799 ==> x IN frontier (s UNION t) \/ 4800 x IN frontier (s INTER t) \/ 4801 x IN frontier s INTER frontier t) /\ 4802 (!s t x. 4803 x IN frontier (s UNION t) \/ 4804 x IN frontier (s INTER t) \/ 4805 x IN frontier s INTER frontier t <=> 4806 x IN frontier (t UNION s) \/ 4807 x IN frontier (t INTER s) \/ 4808 x IN frontier t INTER frontier s))`` THENL 4809 [ALL_TAC, METIS_TAC []] THEN CONJ_TAC THENL 4810 [REPEAT STRIP_TAC, SIMP_TAC std_ss [UNION_COMM, INTER_COMM]] THEN 4811 ASM_CASES_TAC ``(x:real) IN frontier t`` THEN ASM_REWRITE_TAC[IN_INTER] THEN 4812 POP_ASSUM MP_TAC THEN GEN_REWR_TAC (LAND_CONV o RAND_CONV o RAND_CONV) 4813 [FRONTIER_INTERIORS] THEN 4814 REWRITE_TAC[DE_MORGAN_THM, IN_DIFF, IN_UNIV] THEN 4815 GEN_REWR_TAC RAND_CONV [DISJ_SYM] THEN MATCH_MP_TAC MONO_OR THEN 4816 ASM_SIMP_TAC std_ss [lemma] THEN 4817 POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN 4818 SIMP_TAC std_ss [lemma, SET_RULE 4819 ``UNIV DIFF (s UNION t) = (UNIV DIFF s) INTER (UNIV DIFF t)``]); 4820 4821val CONNECTED_INTER_FRONTIER = store_thm ("CONNECTED_INTER_FRONTIER", 4822 ``!s t:real->bool. 4823 connected s /\ ~(s INTER t = {}) /\ ~(s DIFF t = {}) 4824 ==> ~(s INTER frontier t = {})``, 4825 REWRITE_TAC[FRONTIER_INTERIORS] THEN REPEAT STRIP_TAC THEN 4826 UNDISCH_TAC ``connected s`` THEN REWRITE_TAC [CONNECTED_OPEN_IN] THEN 4827 MAP_EVERY EXISTS_TAC 4828 [``s INTER interior t:real->bool``, 4829 ``s INTER (interior(univ(:real) DIFF t))``] THEN 4830 SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_INTERIOR] THEN 4831 MAP_EVERY (MP_TAC o C ISPEC INTERIOR_SUBSET) 4832 [``t:real->bool``, ``univ(:real) DIFF t``] THEN 4833 ASM_SET_TAC[]); 4834 4835val INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER = store_thm ("INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER", 4836 ``!s:real->bool. closed s /\ (interior s = {}) <=> 4837 ?t. open t /\ (s = frontier t)``, 4838 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL 4839 [EXISTS_TAC ``univ(:real) DIFF s`` THEN 4840 ASM_SIMP_TAC std_ss [OPEN_DIFF, OPEN_UNIV, FRONTIER_COMPLEMENT] THEN 4841 ASM_SIMP_TAC std_ss [frontier, CLOSURE_CLOSED, DIFF_EMPTY], 4842 ASM_SIMP_TAC std_ss [FRONTIER_CLOSED, INTERIOR_FRONTIER_EMPTY]]); 4843 4844val FRONTIER_UNION = store_thm ("FRONTIER_UNION", 4845 ``!s t:real->bool. (closure s INTER closure t = {}) 4846 ==> (frontier(s UNION t) = frontier(s) UNION frontier(t))``, 4847 REPEAT STRIP_TAC THEN 4848 MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[FRONTIER_UNION_SUBSET] THEN 4849 GEN_REWR_TAC RAND_CONV [frontier] THEN 4850 REWRITE_TAC[CLOSURE_UNION] THEN MATCH_MP_TAC(SET_RULE 4851 ``(fs SUBSET cs /\ ft SUBSET ct) /\ (k INTER fs = {}) /\ (k INTER ft = {}) 4852 ==> (fs UNION ft) SUBSET (cs UNION ct) DIFF k``) THEN 4853 CONJ_TAC THENL [REWRITE_TAC[frontier] THEN SET_TAC[], ALL_TAC] THEN 4854 CONJ_TAC THENL [ALL_TAC, 4855 ONCE_REWRITE_TAC[UNION_COMM] THEN 4856 RULE_ASSUM_TAC(ONCE_REWRITE_RULE[INTER_COMM])] THEN 4857 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE 4858 ``(s INTER t = {}) ==> s' SUBSET s /\ (s' INTER u INTER (UNIV DIFF t) = {}) 4859 ==> (u INTER s' = {})``)) THEN 4860 REWRITE_TAC[frontier, DIFF_SUBSET, GSYM INTERIOR_COMPLEMENT] THENL 4861 [KNOW_TAC ``(closure s DIFF interior s) INTER 4862 interior (s UNION t) INTER 4863 interior (univ(:real) DIFF t) = 4864 (closure s DIFF interior s) INTER 4865 interior ((s UNION t) INTER (univ(:real) DIFF t))`` THENL 4866 [METIS_TAC [INTERIOR_INTER, INTER_ASSOC], ALL_TAC] THEN DISC_RW_KILL, 4867 KNOW_TAC ``(closure t DIFF interior t) INTER 4868 interior (t UNION s) INTER 4869 interior (univ(:real) DIFF s) = 4870 (closure t DIFF interior t) INTER 4871 interior ((t UNION s) INTER (univ(:real) DIFF s))`` THENL 4872 [METIS_TAC [INTERIOR_INTER, INTER_ASSOC], ALL_TAC] THEN DISC_RW_KILL] THEN 4873 REWRITE_TAC[SET_RULE ``(s UNION t) INTER (UNIV DIFF t) = s DIFF t``] THEN 4874 MATCH_MP_TAC(SET_RULE 4875 ``ti SUBSET si ==> ((c DIFF si) INTER ti = {})``) THEN 4876 SIMP_TAC std_ss [SUBSET_INTERIOR, DIFF_SUBSET]); 4877 4878val CLOSURE_UNION_FRONTIER = store_thm ("CLOSURE_UNION_FRONTIER", 4879 ``!s:real->bool. closure s = s UNION frontier s``, 4880 GEN_TAC THEN REWRITE_TAC[frontier] THEN 4881 MP_TAC(ISPEC ``s:real->bool`` INTERIOR_SUBSET) THEN 4882 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN 4883 SET_TAC[]); 4884 4885val FRONTIER_INTERIOR_SUBSET = store_thm ("FRONTIER_INTERIOR_SUBSET", 4886 ``!s:real->bool. frontier(interior s) SUBSET frontier s``, 4887 GEN_TAC THEN REWRITE_TAC[frontier, INTERIOR_INTERIOR] THEN 4888 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> s DIFF u SUBSET t DIFF u``) THEN 4889 SIMP_TAC std_ss [SUBSET_CLOSURE, INTERIOR_SUBSET]); 4890 4891val FRONTIER_CLOSURE_SUBSET = store_thm ("FRONTIER_CLOSURE_SUBSET", 4892 ``!s:real->bool. frontier(closure s) SUBSET frontier s``, 4893 GEN_TAC THEN REWRITE_TAC[frontier, CLOSURE_CLOSURE] THEN 4894 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> u DIFF t SUBSET u DIFF s``) THEN 4895 SIMP_TAC std_ss [SUBSET_INTERIOR, CLOSURE_SUBSET]); 4896 4897val SET_DIFF_FRONTIER = store_thm ("SET_DIFF_FRONTIER", 4898 ``!s:real->bool. s DIFF frontier s = interior s``, 4899 GEN_TAC THEN REWRITE_TAC[frontier] THEN 4900 MP_TAC(ISPEC ``s:real->bool`` INTERIOR_SUBSET) THEN 4901 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN 4902 SET_TAC[]); 4903 4904val FRONTIER_INTER_SUBSET_INTER = store_thm ("FRONTIER_INTER_SUBSET_INTER", 4905 ``!s t:real->bool. 4906 frontier(s INTER t) SUBSET closure s INTER frontier t UNION 4907 frontier s INTER closure t``, 4908 REPEAT GEN_TAC THEN REWRITE_TAC[frontier, INTERIOR_INTER] THEN 4909 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] 4910 CLOSURE_INTER_SUBSET) THEN SET_TAC[]); 4911 4912(* ------------------------------------------------------------------------- *) 4913(* A variant of nets (slightly non-standard but good for our purposes). *) 4914(* ------------------------------------------------------------------------- *) 4915 4916val isnet = new_definition("isnet", 4917 ``!g. isnet g = !x y. (!z. g z x ==> g z y) \/ 4918 (!z. g z y ==> g z x)``); 4919 4920val net_tydef = new_type_definition 4921 ("net", 4922 prove (``?(g:'a->'a->bool). isnet g``, 4923 EXISTS_TAC ``\x:'a y:'a. F`` THEN REWRITE_TAC[isnet])); 4924 4925val net_ty_bij = define_new_type_bijections 4926 {name="net_tybij", 4927 ABS="mk_net", REP="netord",tyax=net_tydef}; 4928 4929val net_tybij = store_thm ("net_tybij", 4930 ``(!a. mk_net (netord a) = a) /\ 4931 (!r. (!x y. (!z. r z x ==> r z y) \/ (!z. r z y ==> r z x)) <=> 4932 (netord (mk_net r) = r))``, 4933 SIMP_TAC std_ss [net_ty_bij, GSYM isnet]); 4934 4935val NET = store_thm ("NET", 4936 ``!n x y. (!z. netord n z x ==> netord n z y) \/ 4937 (!z. netord n z y ==> netord n z x)``, 4938 REWRITE_TAC[net_tybij, ETA_AX]); 4939 4940val OLDNET = store_thm ("OLDNET", 4941 ``!n x y. netord n x x /\ netord n y y 4942 ==> ?z. netord n z z /\ 4943 !w. netord n w z ==> netord n w x /\ netord n w y``, 4944 MESON_TAC[NET]); 4945 4946val NET_DILEMMA = store_thm ("NET_DILEMMA", 4947 ``!net. (?a. (?x. netord net x a) /\ (!x. netord net x a ==> P x)) /\ 4948 (?b. (?x. netord net x b) /\ (!x. netord net x b ==> Q x)) 4949 ==> ?c. (?x. netord net x c) /\ (!x. netord net x c ==> P x /\ Q x)``, 4950 MESON_TAC[NET]); 4951 4952(* ------------------------------------------------------------------------- *) 4953(* Common nets and the "within" modifier for nets. *) 4954(* ------------------------------------------------------------------------- *) 4955 4956val _ = set_fixity "within" (Infix(NONASSOC, 450)); 4957val _ = set_fixity "in_direction" (Infix(NONASSOC, 450)); 4958 4959val at = new_definition ("at", 4960 ``at a = mk_net(\x y. &0 < dist(x,a) /\ dist(x,a) <= dist(y,a))``); 4961 4962val at_infinity = new_definition ("at_infinity", 4963 ``at_infinity = mk_net(\x y. abs(x) >= abs(y))``); 4964 4965val at_posinfinity = new_definition ("at_posinfinity", 4966 ``at_posinfinity = mk_net(\x y:real. x >= y)``); 4967 4968val at_neginfinity = new_definition ("at_neginfinity", 4969 ``at_neginfinity = mk_net(\x y:real. x <= y)``); 4970 4971val sequentially = new_definition ("sequentially", 4972 ``sequentially = mk_net(\m:num n. m >= n)``); 4973 4974val within = new_definition ("within", 4975 ``(net within s) = mk_net(\x y. netord net x y /\ x IN s)``); 4976 4977val in_direction = new_definition ("in_direction", 4978 ``(a in_direction v) = ((at a) within {b | ?c. &0 <= c /\ (b - a = c * v)})``); 4979 4980(* ------------------------------------------------------------------------- *) 4981(* Prove that they are all nets. *) 4982(* ------------------------------------------------------------------------- *) 4983 4984fun NET_PROVE_TAC [def] = 4985 SIMP_TAC std_ss [GSYM FUN_EQ_THM, def] THEN 4986 REWRITE_TAC [ETA_AX] THEN 4987 ASM_SIMP_TAC std_ss [GSYM(CONJUNCT2 net_tybij)]; 4988 4989val AT = store_thm ("AT", 4990 ``!a:real x y. 4991 netord(at a) x y <=> &0 < dist(x,a) /\ dist(x,a) <= dist(y,a)``, 4992 GEN_TAC THEN NET_PROVE_TAC[at] THEN 4993 METIS_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS, REAL_LET_TRANS]); 4994 4995val AT_INFINITY = store_thm ("AT_INFINITY", 4996 ``!x y. netord at_infinity x y <=> abs(x) >= abs(y)``, 4997 NET_PROVE_TAC[at_infinity] THEN 4998 REWRITE_TAC[real_ge, REAL_LE_REFL] THEN 4999 MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]); 5000 5001val AT_POSINFINITY = store_thm ("AT_POSINFINITY", 5002 ``!x y. netord at_posinfinity x y <=> x >= y``, 5003 NET_PROVE_TAC[at_posinfinity] THEN 5004 REWRITE_TAC[real_ge, REAL_LE_REFL] THEN 5005 MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]); 5006 5007val AT_NEGINFINITY = store_thm ("AT_NEGINFINITY", 5008 ``!x y. netord at_neginfinity x y <=> x <= y``, 5009 NET_PROVE_TAC[at_neginfinity] THEN 5010 REWRITE_TAC[real_ge, REAL_LE_REFL] THEN 5011 MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]); 5012 5013val SEQUENTIALLY = store_thm ("SEQUENTIALLY", 5014 ``!m n. netord sequentially m n <=> m >= n``, 5015 NET_PROVE_TAC[sequentially] THEN REWRITE_TAC[GREATER_EQ, LESS_EQ_REFL] THEN 5016 MESON_TAC[LESS_EQ_CASES, LESS_EQ_REFL, LESS_EQ_TRANS]); 5017 5018val WITHIN = store_thm ("WITHIN", 5019 ``!n s x y. netord(n within s) x y <=> netord n x y /\ x IN s``, 5020 GEN_TAC THEN GEN_TAC THEN SIMP_TAC std_ss [within, GSYM FUN_EQ_THM] THEN 5021 REWRITE_TAC[GSYM(CONJUNCT2 net_tybij), ETA_AX] THEN 5022 METIS_TAC[NET]); 5023 5024val IN_DIRECTION = store_thm ("IN_DIRECTION", 5025 ``!a v x y. netord(a in_direction v) x y <=> 5026 &0 < dist(x,a) /\ dist(x,a) <= dist(y,a) /\ 5027 ?c. &0 <= c /\ (x - a = c * v)``, 5028 SIMP_TAC std_ss [WITHIN, AT, in_direction, GSPECIFICATION] THEN METIS_TAC []); 5029 5030val WITHIN_UNIV = store_thm ("WITHIN_UNIV", 5031 ``!x:real. (at x within UNIV) = at x``, 5032 REWRITE_TAC[within, at, IN_UNIV] THEN REWRITE_TAC[ETA_AX, net_tybij]); 5033 5034val WITHIN_WITHIN = store_thm ("WITHIN_WITHIN", 5035 ``!net s t. ((net within s) within t) = (net within (s INTER t))``, 5036 ONCE_REWRITE_TAC[within] THEN 5037 REWRITE_TAC[WITHIN, IN_INTER, GSYM CONJ_ASSOC]); 5038 5039(* ------------------------------------------------------------------------- *) 5040(* Identify trivial limits, where we can't approach arbitrarily closely. *) 5041(* ------------------------------------------------------------------------- *) 5042 5043val trivial_limit = new_definition ("trivial_limit", 5044 ``trivial_limit net <=> 5045 (!a:'a b. a = b) \/ 5046 ?a:'a b. ~(a = b) /\ !x. ~(netord(net) x a) /\ ~(netord(net) x b)``); 5047 5048val TRIVIAL_LIMIT_WITHIN = store_thm ("TRIVIAL_LIMIT_WITHIN", 5049 ``!a:real. trivial_limit (at a within s) <=> ~(a limit_point_of s)``, 5050 REWRITE_TAC[trivial_limit, LIMPT_APPROACHABLE_LE, WITHIN, AT, DIST_NZ] THEN 5051 REPEAT GEN_TAC THEN EQ_TAC THENL 5052 [DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL 5053 [MESON_TAC[REAL_LT_01, REAL_LT_REFL, REAL_CHOOSE_DIST, 5054 DIST_REFL, REAL_LT_IMP_LE], 5055 DISCH_THEN(X_CHOOSE_THEN ``b:real`` (X_CHOOSE_THEN ``c:real`` 5056 STRIP_ASSUME_TAC)) THEN 5057 SUBGOAL_THEN ``&0 < dist(a,b:real) \/ &0 < dist(a,c:real)`` MP_TAC THEN 5058 ASM_MESON_TAC[DIST_TRIANGLE, DIST_SYM, GSYM DIST_NZ, GSYM DIST_EQ_0, 5059 REAL_ARITH ``x:real <= &0 + &0 ==> ~(&0 < x)``]], 5060 KNOW_TAC ``!e. (0 < e ==> ?x'. x' IN s /\ 0 < dist (x',a) /\ dist (x',a) <= e) = 5061 (\e. 0 < e ==> ?x'. x' IN s /\ 0 < dist (x',a) /\ dist (x',a) <= e) e`` THENL 5062 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 5063 REWRITE_TAC[NOT_FORALL_THM] THEN BETA_TAC THEN REWRITE_TAC [NOT_IMP] THEN 5064 SIMP_TAC std_ss [GSYM LEFT_EXISTS_IMP_THM] THEN 5065 STRIP_TAC THEN DISJ2_TAC THEN 5066 EXISTS_TAC ``a:real`` THEN 5067 SUBGOAL_THEN ``?b:real. dist(a,b) = x`` MP_TAC THENL 5068 [ASM_SIMP_TAC std_ss [REAL_CHOOSE_DIST, REAL_LT_IMP_LE], ALL_TAC] THEN 5069 STRIP_TAC THEN EXISTS_TAC ``b:real`` THEN POP_ASSUM MP_TAC THEN 5070 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN 5071 ASM_MESON_TAC[REAL_NOT_LE, DIST_REFL, DIST_NZ, DIST_SYM]]); 5072 5073val TRIVIAL_LIMIT_AT = store_thm ("TRIVIAL_LIMIT_AT", 5074 ``!a. ~(trivial_limit (at a))``, 5075 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 5076 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN, LIMPT_UNIV]); 5077 5078val TRIVIAL_LIMIT_AT_INFINITY = store_thm ("TRIVIAL_LIMIT_AT_INFINITY", 5079 ``~(trivial_limit at_infinity)``, 5080 REWRITE_TAC[trivial_limit, AT_INFINITY, real_ge] THEN 5081 MESON_TAC[REAL_LE_REFL, REAL_CHOOSE_SIZE, REAL_LT_01, REAL_LT_LE]); 5082 5083val TRIVIAL_LIMIT_AT_POSINFINITY = store_thm ("TRIVIAL_LIMIT_AT_POSINFINITY", 5084 ``~(trivial_limit at_posinfinity)``, 5085 REWRITE_TAC[trivial_limit, AT_POSINFINITY, DE_MORGAN_THM] THEN 5086 CONJ_TAC THENL 5087 [DISCH_THEN(MP_TAC o SPECL [``&0:real``, ``&1:real``]) THEN REAL_ARITH_TAC, ALL_TAC] THEN 5088 REWRITE_TAC[DE_MORGAN_THM, NOT_EXISTS_THM, real_ge, REAL_NOT_LE] THEN 5089 MESON_TAC[REAL_LT_TOTAL, REAL_LT_ANTISYM]); 5090 5091val TRIVIAL_LIMIT_AT_NEGINFINITY = store_thm ("TRIVIAL_LIMIT_AT_NEGINFINITY", 5092 ``~(trivial_limit at_neginfinity)``, 5093 REWRITE_TAC[trivial_limit, AT_NEGINFINITY, DE_MORGAN_THM] THEN 5094 CONJ_TAC THENL 5095 [DISCH_THEN(MP_TAC o SPECL [``&0:real``, ``&1:real``]) THEN REAL_ARITH_TAC, ALL_TAC] THEN 5096 REWRITE_TAC[DE_MORGAN_THM, NOT_EXISTS_THM, real_ge, REAL_NOT_LE] THEN 5097 MESON_TAC[REAL_LT_TOTAL, REAL_LT_ANTISYM]); 5098 5099val TRIVIAL_LIMIT_SEQUENTIALLY = store_thm ("TRIVIAL_LIMIT_SEQUENTIALLY", 5100 ``~(trivial_limit sequentially)``, 5101 REWRITE_TAC[trivial_limit, SEQUENTIALLY] THEN 5102 MESON_TAC[GREATER_EQ, LESS_EQ_REFL, SUC_NOT]); 5103 5104val LIM_WITHIN_CLOSED_TRIVIAL = store_thm ("LIM_WITHIN_CLOSED_TRIVIAL", 5105 ``!a s. closed s /\ ~(a IN s) ==> trivial_limit (at a within s)``, 5106 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN MESON_TAC[CLOSED_LIMPT]); 5107 5108val NONTRIVIAL_LIMIT_WITHIN = store_thm ("NONTRIVIAL_LIMIT_WITHIN", 5109 ``!net s. trivial_limit net ==> trivial_limit(net within s)``, 5110 REWRITE_TAC[trivial_limit, WITHIN] THEN MESON_TAC[]); 5111 5112(* ------------------------------------------------------------------------- *) 5113(* Some property holds "sufficiently close" to the limit point. *) 5114(* ------------------------------------------------------------------------- *) 5115 5116val eventually = new_definition ("eventually", 5117 ``eventually p net <=> 5118 trivial_limit net \/ 5119 ?y. (?x. netord net x y) /\ (!x. netord net x y ==> p x)``); 5120 5121val EVENTUALLY_HAPPENS = store_thm ("EVENTUALLY_HAPPENS", 5122 ``!net p. eventually p net ==> trivial_limit net \/ ?x. p x``, 5123 REWRITE_TAC[eventually] THEN MESON_TAC[]); 5124 5125val EVENTUALLY_WITHIN_LE = store_thm ("EVENTUALLY_WITHIN_LE", 5126 ``!s a:real p. 5127 eventually p (at a within s) <=> 5128 ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d ==> p(x)``, 5129 REWRITE_TAC[eventually, AT, WITHIN, TRIVIAL_LIMIT_WITHIN] THEN 5130 REWRITE_TAC[LIMPT_APPROACHABLE_LE, DIST_NZ] THEN 5131 REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LTE_TRANS], ALL_TAC] THEN 5132 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 5133 MATCH_MP_TAC(TAUT `(a ==> b) ==> ~a \/ b`) THEN DISCH_TAC THEN 5134 SUBGOAL_THEN ``?b:real. dist(a,b) = d`` MP_TAC THENL 5135 [ASM_SIMP_TAC std_ss [REAL_CHOOSE_DIST, REAL_LT_IMP_LE], ALL_TAC] THEN 5136 STRIP_TAC THEN EXISTS_TAC ``b:real`` THEN POP_ASSUM MP_TAC THEN 5137 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN 5138 ASM_MESON_TAC[REAL_NOT_LE, DIST_REFL, DIST_NZ, DIST_SYM]); 5139 5140val EVENTUALLY_WITHIN = store_thm ("EVENTUALLY_WITHIN", 5141 ``!s a:real p. 5142 eventually p (at a within s) <=> 5143 ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)``, 5144 REWRITE_TAC[EVENTUALLY_WITHIN_LE] THEN 5145 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN 5146 SIMP_TAC std_ss [APPROACHABLE_LT_LE]); 5147 5148val EVENTUALLY_AT = store_thm ("EVENTUALLY_AT", 5149 ``!a p. eventually p (at a) <=> 5150 ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)``, 5151 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 5152 REWRITE_TAC[EVENTUALLY_WITHIN, IN_UNIV]); 5153 5154val EVENTUALLY_SEQUENTIALLY = store_thm ("EVENTUALLY_SEQUENTIALLY", 5155 ``!p. eventually p sequentially <=> ?N. !n. N <= n ==> p n``, 5156 REWRITE_TAC[eventually, SEQUENTIALLY, GREATER_EQ, LESS_EQ_REFL, 5157 TRIVIAL_LIMIT_SEQUENTIALLY] THEN MESON_TAC[LESS_EQ_REFL]); 5158 5159val EVENTUALLY_AT_INFINITY = store_thm ("EVENTUALLY_AT_INFINITY", 5160 ``!p. eventually p at_infinity <=> ?b. !x. abs(x) >= b ==> p x``, 5161 SIMP_TAC std_ss [eventually, AT_INFINITY, TRIVIAL_LIMIT_AT_INFINITY] THEN 5162 REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LE_REFL], ALL_TAC] THEN 5163 MESON_TAC[real_ge, REAL_LE_REFL, REAL_CHOOSE_SIZE, 5164 REAL_ARITH ``&0 <= b:real \/ (!x. x >= &0 ==> x >= b)``]); 5165 5166val EVENTUALLY_AT_POSINFINITY = store_thm ("EVENTUALLY_AT_POSINFINITY", 5167 ``!p. eventually p at_posinfinity <=> ?b. !x. x >= b ==> p x``, 5168 REWRITE_TAC[eventually, TRIVIAL_LIMIT_AT_POSINFINITY, AT_POSINFINITY] THEN 5169 MESON_TAC[REAL_ARITH ``x >= x``]); 5170 5171val EVENTUALLY_AT_NEGINFINITY = store_thm ("EVENTUALLY_AT_NEGINFINITY", 5172 ``!p. eventually p at_neginfinity <=> ?b. !x. x <= b ==> p x``, 5173 REWRITE_TAC[eventually, TRIVIAL_LIMIT_AT_NEGINFINITY, AT_NEGINFINITY] THEN 5174 MESON_TAC[REAL_LE_REFL]); 5175 5176val EVENTUALLY_AT_INFINITY_POS = store_thm ("EVENTUALLY_AT_INFINITY_POS", 5177 ``!p:real->bool. 5178 eventually p at_infinity <=> ?b. &0 < b /\ !x. abs x >= b ==> p x``, 5179 GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT_INFINITY, real_ge] THEN 5180 MESON_TAC[REAL_ARITH ``&0 < abs b + &1 /\ (abs b + &1 <= x ==> b <= x:real)``]); 5181 5182val ALWAYS_EVENTUALLY = store_thm ("ALWAYS_EVENTUALLY", 5183 ``(!x. p x) ==> eventually p net``, 5184 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[eventually, trivial_limit] THEN 5185 MESON_TAC[]); 5186 5187(* ------------------------------------------------------------------------- *) 5188(* Combining theorems for "eventually". *) 5189(* ------------------------------------------------------------------------- *) 5190 5191val EVENTUALLY_AND = store_thm ("EVENTUALLY_AND", 5192 ``!net:('a net) p q. 5193 eventually (\x. p x /\ q x) net <=> 5194 eventually p net /\ eventually q net``, 5195 REPEAT GEN_TAC THEN REWRITE_TAC[eventually] THEN 5196 ASM_CASES_TAC ``trivial_limit(net:('a net))`` THEN ASM_REWRITE_TAC[] THEN 5197 EQ_TAC THEN SIMP_TAC std_ss [NET_DILEMMA] THENL [MESON_TAC [], ALL_TAC] THEN 5198 DISCH_TAC THEN MATCH_MP_TAC NET_DILEMMA THEN METIS_TAC []); 5199 5200val EVENTUALLY_MONO = store_thm ("EVENTUALLY_MONO", 5201 ``!net:('a net) p q. 5202 (!x. p x ==> q x) /\ eventually p net 5203 ==> eventually q net``, 5204 REWRITE_TAC[eventually] THEN MESON_TAC[]); 5205 5206val EVENTUALLY_MP = store_thm ("EVENTUALLY_MP", 5207 ``!net:('a net) p q. 5208 eventually (\x. p x ==> q x) net /\ eventually p net 5209 ==> eventually q net``, 5210 REWRITE_TAC[GSYM EVENTUALLY_AND] THEN 5211 REWRITE_TAC[eventually] THEN MESON_TAC[]); 5212 5213val EVENTUALLY_FALSE = store_thm ("EVENTUALLY_FALSE", 5214 ``!net. eventually (\x. F) net <=> trivial_limit net``, 5215 REWRITE_TAC[eventually] THEN MESON_TAC[]); 5216 5217val EVENTUALLY_TRUE = store_thm ("EVENTUALLY_TRUE", 5218 ``!net. eventually (\x. T) net <=> T``, 5219 REWRITE_TAC[eventually, trivial_limit] THEN MESON_TAC[]); 5220 5221val NOT_EVENTUALLY = store_thm ("NOT_EVENTUALLY", 5222 ``!net p. (!x. ~(p x)) /\ ~(trivial_limit net) ==> ~(eventually p net)``, 5223 REWRITE_TAC[eventually] THEN MESON_TAC[]); 5224 5225val EVENTUALLY_FORALL = store_thm ("EVENTUALLY_FORALL", 5226 ``!net:('a net) p s:'b->bool. 5227 FINITE s /\ ~(s = {}) 5228 ==> (eventually (\x. !a. a IN s ==> p a x) net <=> 5229 !a. a IN s ==> eventually (p a) net)``, 5230 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 5231 KNOW_TAC ``!s:'b->bool. (s <> ({} :'b -> bool) ==> 5232 (eventually (\(x :'a). !(a :'b). a IN s ==> (p :'b -> 'a -> bool) a x) 5233 (net :'a net) <=> !(a :'b). a IN s ==> eventually (p a) net)) = 5234 (\s. s <> ({} :'b -> bool) ==> 5235 (eventually (\(x :'a). !(a :'b). a IN s ==> (p :'b -> 'a -> bool) a x) 5236 (net :'a net) <=> !(a :'b). a IN s ==> eventually (p a) net)) s`` THENL 5237 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 5238 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 5239 SIMP_TAC std_ss [FORALL_IN_INSERT, EVENTUALLY_AND, ETA_AX] THEN 5240 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 5241 MAP_EVERY X_GEN_TAC [``t:'b->bool``, ``b:'b``] THEN 5242 ASM_CASES_TAC ``t:'b->bool = {}`` THEN 5243 ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, EVENTUALLY_TRUE] THEN METIS_TAC []); 5244 5245val FORALL_EVENTUALLY = store_thm ("FORALL_EVENTUALLY", 5246 ``!net:('a net) p s:'b->bool. 5247 FINITE s /\ ~(s = {}) 5248 ==> ((!a. a IN s ==> eventually (p a) net) <=> 5249 eventually (\x. !a. a IN s ==> p a x) net)``, 5250 SIMP_TAC std_ss [EVENTUALLY_FORALL]); 5251 5252(* ------------------------------------------------------------------------- *) 5253(* Limits, defined as vacuously true when the limit is trivial. *) 5254(* ------------------------------------------------------------------------- *) 5255 5256val _ = hide "-->"; 5257 5258val tendsto = new_infixr_definition("tendsto", 5259 ``$--> f l net = !e. &0 < e ==> eventually (\x. dist(f(x),l) < e) net``,750); 5260 5261(* LONG RIGHTWARDS ARROW *) 5262val _ = Unicode.unicode_version {u = UTF8.chr 0x27F6, tmnm = "-->"}; 5263val _ = TeX_notation {hol = UTF8.chr 0x27F6, TeX = ("\\HOLTokenLongmap{}", 1)}; 5264val _ = TeX_notation {hol = "-->", TeX = ("\\HOLTokenLongmap{}", 1)}; 5265 5266val lim_def = new_definition ("lim_def", 5267 ``lim_def net f = @l. (f --> l) net``); 5268 5269val _ = overload_on ("lim",``lim_def``); 5270 5271val LIM = store_thm ("LIM", 5272 ``(f --> l) net <=> 5273 trivial_limit net \/ 5274 !e. &0 < e ==> ?y. (?x. netord(net) x y) /\ 5275 !x. netord(net) x y ==> dist(f(x),l) < e``, 5276 REWRITE_TAC[tendsto, eventually] THEN MESON_TAC[]); 5277 5278(* ------------------------------------------------------------------------- *) 5279(* Show that they yield usual definitions in the various cases. *) 5280(* ------------------------------------------------------------------------- *) 5281 5282val LIM_WITHIN_LE = store_thm ("LIM_WITHIN_LE", 5283 ``!f:real->real l a s. 5284 (f --> l)(at a within s) <=> 5285 !e. &0 < e ==> ?d. &0 < d /\ 5286 !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d 5287 ==> dist(f(x),l) < e``, 5288 SIMP_TAC std_ss [tendsto, EVENTUALLY_WITHIN_LE]); 5289 5290val LIM_WITHIN = store_thm ("LIM_WITHIN", 5291 ``!f:real->real l a s. 5292 (f --> l) (at a within s) <=> 5293 !e. &0 < e 5294 ==> ?d. &0 < d /\ 5295 !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d 5296 ==> dist(f(x),l) < e``, 5297 SIMP_TAC std_ss [tendsto, EVENTUALLY_WITHIN] THEN MESON_TAC[]); 5298 5299val LIM_AT_LE = store_thm ("LIM_AT_LE", 5300 ``!f l a. (f --> l) (at a) <=> 5301 !e. &0 < e 5302 ==> ?d. &0 < d /\ 5303 !x. &0 < dist(x,a) /\ dist(x,a) <= d 5304 ==> dist (f x,l) < e``, 5305 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 5306 REWRITE_TAC[LIM_WITHIN_LE, IN_UNIV]); 5307 5308val LIM_AT = store_thm ("LIM_AT", 5309 ``!f l:real a:real. 5310 (f --> l) (at a) <=> 5311 !e. &0 < e 5312 ==> ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d 5313 ==> dist(f(x),l) < e``, 5314 REWRITE_TAC[tendsto, EVENTUALLY_AT] THEN MESON_TAC[]); 5315 5316val LIM_AT_INFINITY = store_thm ("LIM_AT_INFINITY", 5317 ``!f l. (f --> l) at_infinity <=> 5318 !e. &0 < e ==> ?b. !x. abs(x) >= b ==> dist(f(x),l) < e``, 5319 SIMP_TAC std_ss [tendsto, EVENTUALLY_AT_INFINITY] THEN MESON_TAC[]); 5320 5321val LIM_AT_INFINITY_POS = store_thm ("LIM_AT_INFINITY_POS", 5322 ``!f l. (f --> l) at_infinity <=> 5323 !e. &0 < e ==> ?b. &0 < b /\ !x. abs x >= b ==> dist(f x,l) < e``, 5324 REPEAT GEN_TAC THEN SIMP_TAC std_ss [LIM_AT_INFINITY] THEN 5325 METIS_TAC[REAL_ARITH ``&0 < abs b + &1 /\ (x >= abs b + &1 ==> x >= b)``]); 5326 5327val LIM_AT_POSINFINITY = store_thm ("LIM_AT_POSINFINITY", 5328 ``!f l. (f --> l) at_posinfinity <=> 5329 !e. &0 < e ==> ?b. !x. x >= b ==> dist(f(x),l) < e``, 5330 REWRITE_TAC[tendsto, EVENTUALLY_AT_POSINFINITY] THEN MESON_TAC[]); 5331 5332val LIM_AT_NEGINFINITY = store_thm ("LIM_AT_NEGINFINITY", 5333 ``!f l. (f --> l) at_neginfinity <=> 5334 !e. &0 < e ==> ?b. !x. x <= b ==> dist(f(x),l) < e``, 5335 REWRITE_TAC[tendsto, EVENTUALLY_AT_NEGINFINITY] THEN MESON_TAC[]); 5336 5337val LIM_SEQUENTIALLY = store_thm ("LIM_SEQUENTIALLY", 5338 ``!s l. (s --> l) sequentially <=> 5339 !e. &0 < e ==> ?N. !n. N <= n ==> dist(s(n),l) < e``, 5340 REWRITE_TAC[tendsto, EVENTUALLY_SEQUENTIALLY] THEN MESON_TAC[]); 5341 5342val LIM_EVENTUALLY = store_thm ("LIM_EVENTUALLY", 5343 ``!net f l. eventually (\x. f x = l) net ==> (f --> l) net``, 5344 REWRITE_TAC[eventually, LIM] THEN MESON_TAC[DIST_REFL]); 5345 5346val LIM_POSINFINITY_SEQUENTIALLY = store_thm ("LIM_POSINFINITY_SEQUENTIALLY", 5347 ``!f l. (f --> l) at_posinfinity ==> ((\n. f(&n)) --> l) sequentially``, 5348 REPEAT GEN_TAC THEN 5349 REWRITE_TAC[LIM_AT_POSINFINITY, LIM_SEQUENTIALLY] THEN 5350 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 5351 FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN 5352 DISCH_THEN(X_CHOOSE_TAC ``B:real``) THEN 5353 MP_TAC(ISPEC ``B:real`` SIMP_REAL_ARCH) THEN 5354 DISCH_THEN(X_CHOOSE_THEN ``N:num`` STRIP_ASSUME_TAC) THEN 5355 EXISTS_TAC ``N:num`` THEN POP_ASSUM MP_TAC THEN 5356 REPEAT STRIP_TAC THEN BETA_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 5357 RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN 5358 METIS_TAC [real_ge, REAL_LE_TRANS]); 5359 5360val LIM_INFINITY_POSINFINITY = store_thm ("LIM_INFINITY_POSINFINITY", 5361 ``!f l:real. (f --> l) at_infinity ==> (f --> l) at_posinfinity``, 5362 SIMP_TAC std_ss [LIM_AT_INFINITY, LIM_AT_POSINFINITY, o_THM] THEN 5363 METIS_TAC[dist, REAL_ARITH ``x >= b ==> abs(x) >= b:real``]); 5364 5365(* ------------------------------------------------------------------------- *) 5366(* The expected monotonicity property. *) 5367(* ------------------------------------------------------------------------- *) 5368 5369val LIM_WITHIN_EMPTY = store_thm ("LIM_WITHIN_EMPTY", 5370 ``!f l x. (f --> l) (at x within {})``, 5371 REWRITE_TAC[LIM_WITHIN, NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]); 5372 5373val LIM_WITHIN_SUBSET = store_thm ("LIM_WITHIN_SUBSET", 5374 ``!f l a s. 5375 (f --> l) (at a within s) /\ t SUBSET s ==> (f --> l) (at a within t)``, 5376 REWRITE_TAC[LIM_WITHIN, SUBSET_DEF] THEN MESON_TAC[]); 5377 5378val LIM_UNION = store_thm ("LIM_UNION", 5379 ``!f x l s t. 5380 (f --> l) (at x within s) /\ (f --> l) (at x within t) 5381 ==> (f --> l) (at x within (s UNION t))``, 5382 REPEAT GEN_TAC THEN REWRITE_TAC[LIM_WITHIN, IN_UNION] THEN 5383 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN STRIP_TAC THEN 5384 X_GEN_TAC ``e:real`` THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 5385 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN 5386 DISCH_THEN(CONJUNCTS_THEN2 5387 (X_CHOOSE_TAC ``d1:real``) (X_CHOOSE_TAC ``d2:real``)) THEN 5388 EXISTS_TAC ``min d1 d2:real`` THEN ASM_MESON_TAC[REAL_LT_MIN]); 5389 5390val LIM_UNION_UNIV = store_thm ("LIM_UNION_UNIV", 5391 ``!f x l s t. 5392 (f --> l) (at x within s) /\ (f --> l) (at x within t) /\ 5393 (s UNION t = univ(:real)) ==> (f --> l) (at x)``, 5394 MESON_TAC[LIM_UNION, WITHIN_UNIV]); 5395 5396(* ------------------------------------------------------------------------- *) 5397(* Composition of limits. *) 5398(* ------------------------------------------------------------------------- *) 5399 5400val LIM_COMPOSE_WITHIN = store_thm ("LIM_COMPOSE_WITHIN", 5401 ``!net f:'a->real g:real->real s y z. 5402 (f --> y) net /\ 5403 eventually (\w. f w IN s /\ ((f w = y) ==> (g y = z))) net /\ 5404 (g --> z) (at y within s) 5405 ==> ((g o f) --> z) net``, 5406 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto, CONJ_ASSOC] THEN 5407 KNOW_TAC ``(!e. (&0 < e ==> eventually (\x. dist ((f:'a->real) x,y) < e) net) /\ 5408 eventually (\w. f w IN s /\ ((f w = y) ==> ((g:real->real) y = z))) net) /\ 5409 (!e. &0 < e ==> eventually (\x. dist (g x,z) < e) (at y within s)) 5410 ==> (!e. &0 < e ==> eventually (\x. dist ((g o f) x,z) < e) net)`` THENL 5411 [ALL_TAC, SIMP_TAC std_ss [LEFT_AND_FORALL_THM]] THEN 5412 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 5413 STRIP_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 5414 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN 5415 REWRITE_TAC[EVENTUALLY_WITHIN, GSYM DIST_NZ, o_DEF] THEN 5416 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 5417 UNDISCH_TAC ``!e. (0 < e ==> eventually (\x. dist (f x,y) < e) net) /\ 5418 eventually (\w. f w IN s /\ ((f:'a->real w = y) ==> (g:real->real y = z))) net`` THEN 5419 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``d:real``) THEN 5420 ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN BETA_TAC THEN 5421 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 5422 ASM_MESON_TAC[DIST_REFL]); 5423 5424val LIM_COMPOSE_AT = store_thm ("LIM_COMPOSE_AT", 5425 ``!net f:'a->real g:real->real y z. 5426 (f --> y) net /\ 5427 eventually (\w. (f w = y) ==> (g y = z)) net /\ 5428 (g --> z) (at y) 5429 ==> ((g o f) --> z) net``, 5430 REPEAT STRIP_TAC THEN 5431 MP_TAC(ISPECL [``net:('a)net``, ``f:'a->real``, ``g:real->real``, 5432 ``univ(:real)``, ``y:real``, ``z:real``] 5433 LIM_COMPOSE_WITHIN) THEN 5434 ASM_REWRITE_TAC[IN_UNIV, WITHIN_UNIV]); 5435 5436(* ------------------------------------------------------------------------- *) 5437(* Interrelations between restricted and unrestricted limits. *) 5438(* ------------------------------------------------------------------------- *) 5439 5440val LIM_AT_WITHIN = store_thm ("LIM_AT_WITHIN", 5441 ``!f l a s. (f --> l)(at a) ==> (f --> l)(at a within s)``, 5442 REWRITE_TAC[LIM_AT, LIM_WITHIN] THEN MESON_TAC[]); 5443 5444val LIM_WITHIN_OPEN = store_thm ("LIM_WITHIN_OPEN", 5445 ``!f l a:real s. 5446 a IN s /\ open s ==> ((f --> l)(at a within s) <=> (f --> l)(at a))``, 5447 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [LIM_AT_WITHIN] THEN 5448 REWRITE_TAC[LIM_AT, LIM_WITHIN] THEN 5449 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 5450 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN 5451 DISCH_THEN(X_CHOOSE_THEN ``d1:real`` STRIP_ASSUME_TAC) THEN 5452 UNDISCH_TAC ``open s`` THEN GEN_REWR_TAC LAND_CONV [open_def] THEN 5453 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``a:real``) THEN 5454 ASM_REWRITE_TAC[] THEN 5455 DISCH_THEN(X_CHOOSE_THEN ``d2:real`` STRIP_ASSUME_TAC) THEN 5456 MP_TAC(SPECL [``d1:real``, ``d2:real``] REAL_DOWN2) THEN ASM_REWRITE_TAC[] THEN 5457 ASM_MESON_TAC[REAL_LT_TRANS]); 5458 5459(* ------------------------------------------------------------------------- *) 5460(* Segment of natural numbers starting at a specific number. *) 5461(* ------------------------------------------------------------------------- *) 5462 5463val from_def = Define 5464 `from n = {m:num | n <= m}`; 5465 5466val FROM_0 = store_thm ("FROM_0", 5467 ``from 0 = univ(:num)``, 5468 REWRITE_TAC [from_def, ZERO_LESS_EQ, GSPEC_T]); 5469 5470val IN_FROM = store_thm ("IN_FROM", 5471 ``!m n. m IN from n <=> n <= m``, 5472 SIMP_TAC std_ss [from_def, GSPECIFICATION]); 5473 5474val DISJOINT_COUNT_FROM = store_thm 5475 ("DISJOINT_COUNT_FROM", ``!n. DISJOINT (count n) (from n)``, 5476 RW_TAC arith_ss [from_def, count_def, DISJOINT_DEF, Once EXTENSION, NOT_IN_EMPTY, 5477 GSPECIFICATION, IN_INTER]); 5478 5479val DISJOINT_FROM_COUNT = store_thm 5480 ("DISJOINT_FROM_COUNT", ``!n. DISJOINT (from n) (count n)``, 5481 RW_TAC std_ss [Once DISJOINT_SYM, DISJOINT_COUNT_FROM]); 5482 5483val UNION_COUNT_FROM = store_thm 5484 ("UNION_COUNT_FROM", ``!n. (count n) UNION (from n) = UNIV``, 5485 RW_TAC arith_ss [from_def, count_def, Once EXTENSION, NOT_IN_EMPTY, 5486 GSPECIFICATION, IN_UNION, IN_UNIV]); 5487 5488val UNION_FROM_COUNT = store_thm 5489 ("UNION_FROM_COUNT", ``!n. (from n) UNION (count n) = UNIV``, 5490 RW_TAC std_ss [Once UNION_COMM, UNION_COUNT_FROM]); 5491 5492Theorem FROM_NOT_EMPTY : 5493 !n. from n <> {} 5494Proof 5495 RW_TAC std_ss [GSYM MEMBER_NOT_EMPTY, from_def, GSPECIFICATION] 5496 >> Q.EXISTS_TAC `n` >> REWRITE_TAC [LESS_EQ_REFL] 5497QED 5498 5499Theorem COUNTABLE_FROM : 5500 !n. COUNTABLE (from n) 5501Proof 5502 PROVE_TAC [COUNTABLE_NUM] 5503QED 5504 5505val FROM_INTER_NUMSEG_GEN = store_thm ("FROM_INTER_NUMSEG_GEN", 5506 ``!k m n. (from k) INTER (m..n) = (if m < k then k..n else m..n)``, 5507 REPEAT GEN_TAC THEN COND_CASES_TAC THEN POP_ASSUM MP_TAC THEN 5508 SIMP_TAC std_ss [from_def, GSPECIFICATION, IN_INTER, IN_NUMSEG, EXTENSION] THEN 5509 ARITH_TAC); 5510 5511val FROM_INTER_NUMSEG_MAX = store_thm ("FROM_INTER_NUMSEG_MAX", 5512 ``!m n p. from p INTER (m..n) = (MAX p m..n)``, 5513 SIMP_TAC arith_ss [EXTENSION, IN_INTER, IN_NUMSEG, IN_FROM] THEN ARITH_TAC); 5514 5515val FROM_INTER_NUMSEG = store_thm ("FROM_INTER_NUMSEG", 5516 ``!k n. (from k) INTER (0:num..n) = k..n``, 5517 SIMP_TAC std_ss [from_def, GSPECIFICATION, IN_INTER, IN_NUMSEG, EXTENSION] THEN 5518 ARITH_TAC); 5519 5520val INFINITE_FROM = store_thm ("INFINITE_FROM", 5521 ``!n. INFINITE(from n)``, 5522 GEN_TAC THEN KNOW_TAC ``from n = univ(:num) DIFF {i | i < n}`` THENL 5523 [SIMP_TAC std_ss [EXTENSION, from_def, IN_DIFF, IN_UNIV, GSPECIFICATION] THEN 5524 ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 5525 MATCH_MP_TAC INFINITE_DIFF_FINITE THEN 5526 REWRITE_TAC [FINITE_NUMSEG_LT, num_INFINITE]]); 5527 5528(* ------------------------------------------------------------------------- *) 5529(* More limit point characterizations. *) 5530(* ------------------------------------------------------------------------- *) 5531 5532val WLOG_LT = store_thm ("WLOG_LT", 5533 ``(!m:num. P m m) /\ (!m n. P m n <=> P n m) /\ (!m n. m < n ==> P m n) 5534 ==> !m y. P m y``, 5535 METIS_TAC[LESS_LESS_CASES]); 5536 5537val LT_EXISTS = store_thm ("LT_EXISTS", 5538 ``!m n. (m < n) <=> (?d. n = m + SUC d)``, 5539 GEN_TAC THEN INDUCT_TAC THEN SIMP_TAC std_ss [LESS_THM, ADD_CLAUSES, SUC_NOT] THEN 5540 ASM_REWRITE_TAC[INV_SUC_EQ] THEN EQ_TAC THENL 5541 [DISCH_THEN(DISJ_CASES_THEN2 SUBST1_TAC MP_TAC) THENL 5542 [EXISTS_TAC ``0:num`` THEN REWRITE_TAC[ADD_CLAUSES], 5543 DISCH_THEN(X_CHOOSE_THEN ``d:num`` SUBST1_TAC) THEN 5544 EXISTS_TAC ``SUC d`` THEN REWRITE_TAC[ADD_CLAUSES]], 5545 SIMP_TAC std_ss [LEFT_EXISTS_IMP_THM] THEN 5546 KNOW_TAC ``((?d. n = m + d) ==> (m = n) \/ ?d. n = m + SUC d) = 5547 (!d. (n = m + d) ==> (m = n) \/ ?d. n = m + SUC d)`` THENL 5548 [EQ_TAC THENL [SIMP_TAC std_ss [LEFT_EXISTS_IMP_THM], 5549 STRIP_TAC THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN 5550 POP_ASSUM (MP_TAC o Q.SPEC `d:num`) THEN FULL_SIMP_TAC std_ss []], 5551 ALL_TAC] THEN DISC_RW_KILL THEN 5552 INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES, INV_SUC_EQ] THEN 5553 DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[] THEN DISJ2_TAC THEN 5554 EXISTS_TAC ``d:num`` THEN METIS_TAC[INV_SUC_EQ, ADD_COMM]]); 5555 5556val TRANSITIVE_STEPWISE_LT_EQ = store_thm ("TRANSITIVE_STEPWISE_LT_EQ", 5557 ``!R. (!x y z. R x y /\ R y z ==> R x z) 5558 ==> ((!m n. m < n ==> R m n) <=> (!n. R n (SUC n)))``, 5559 REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC std_ss [LESS_THM] THEN 5560 DISCH_TAC THEN SIMP_TAC std_ss [LT_EXISTS] THEN 5561 KNOW_TAC ``(!m n. (?d. n = m + SUC d) ==> R m n) = 5562 (!m d n. (n = m + SUC d) ==> R m (m + SUC d))`` THENL 5563 [METIS_TAC [LEFT_EXISTS_IMP_THM, SWAP_FORALL_THM], ALL_TAC] THEN 5564 DISC_RW_KILL THEN GEN_TAC THEN 5565 SIMP_TAC std_ss [LEFT_FORALL_IMP_THM, EXISTS_REFL, ADD_CLAUSES] THEN 5566 INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES] THEN ASM_MESON_TAC[]); 5567 5568val TRANSITIVE_STEPWISE_LT = store_thm ("TRANSITIVE_STEPWISE_LT", 5569 ``!R. (!x y z. R x y /\ R y z ==> R x z) /\ (!n. R n (SUC n)) 5570 ==> !m n. m < n ==> R m n``, 5571 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT 5572 `(a ==> (c <=> b)) ==> a /\ b ==> c`) THEN 5573 MATCH_ACCEPT_TAC TRANSITIVE_STEPWISE_LT_EQ); 5574 5575val LIMPT_SEQUENTIAL_INJ = store_thm ("LIMPT_SEQUENTIAL_INJ", 5576 ``!x:real s. 5577 x limit_point_of s <=> 5578 ?f. (!n. f(n) IN (s DELETE x)) /\ 5579 (!m n. (f m = f n) <=> (m = n)) /\ 5580 (f --> x) sequentially``, 5581 REPEAT GEN_TAC THEN 5582 REWRITE_TAC[LIMPT_APPROACHABLE, LIM_SEQUENTIALLY, IN_DELETE] THEN 5583 EQ_TAC THENL [ALL_TAC, MESON_TAC[GREATER_EQ, LESS_EQ_REFL]] THEN 5584 KNOW_TAC ``(!e. 0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e) = 5585 (!e. ?x'. &0 < e ==> x' IN s /\ ~(x' = x) /\ dist (x',x) < e)`` THENL 5586 [SIMP_TAC std_ss [GSYM RIGHT_EXISTS_IMP_THM], ALL_TAC] THEN DISC_RW_KILL THEN 5587 SIMP_TAC std_ss [SKOLEM_THM] THEN STRIP_TAC THEN 5588 KNOW_TAC ``?z. (z 0 = f (&1)) /\ 5589 (!n. z (SUC n):real = f (min (inv(&2 pow (SUC n))) (dist(z n,x))))`` THENL 5590 [RW_TAC real_ss [num_Axiom], ALL_TAC] THEN STRIP_TAC THEN 5591 EXISTS_TAC ``z:num->real`` THEN 5592 SUBGOAL_THEN 5593 ``!n. z(n) IN s /\ ~(z n:real = x) /\ dist(z n,x) < inv(&2 pow n)`` 5594 ASSUME_TAC THENL 5595 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THENL [REWRITE_TAC [pow, REAL_INV1] THEN 5596 ASM_SIMP_TAC std_ss [REAL_LT_01], FIRST_X_ASSUM(MP_TAC o SPEC 5597 ``min (inv(&2 pow (SUC n))) (dist(z n:real,x))``) THEN 5598 ASM_SIMP_TAC std_ss [REAL_LT_MIN, REAL_LT_INV_EQ, REAL_POW_LT, DIST_POS_LT, 5599 REAL_ARITH ``0:real < 2``]], 5600 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL 5601 [KNOW_TAC ``!m:num n. (((z:num->real) m = z n) <=> (m = n)) = 5602 (\m n. ((z m = z n) <=> (m = n))) m n`` THENL 5603 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 5604 MATCH_MP_TAC WLOG_LT THEN BETA_TAC THEN SIMP_TAC std_ss [EQ_SYM_EQ] THEN 5605 SUBGOAL_THEN ``!m n:num. m < n ==> dist(z n:real,x) < dist(z m,x)`` 5606 (fn th => MESON_TAC[th, REAL_LT_REFL, LESS_REFL]) THEN 5607 KNOW_TAC ``!m n:num. (dist (z n,x) < dist (z m,x)) = 5608 (\m n. dist (z n,x) < dist (z m,x)) m n`` THENL 5609 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 5610 MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN BETA_TAC THEN 5611 CONJ_TAC THENL [REAL_ARITH_TAC, GEN_TAC THEN ASM_REWRITE_TAC[]] THEN 5612 FIRST_X_ASSUM(MP_TAC o SPEC 5613 ``min (inv(&2 pow (SUC n))) (dist(z n:real,x))``) THEN 5614 ASM_SIMP_TAC std_ss [REAL_LT_MIN, REAL_LT_INV_EQ, REAL_POW_LT, 5615 REAL_ARITH ``0:real < 2``, DIST_POS_LT], 5616 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 5617 MP_TAC(ISPECL [``inv(&2:real)``, ``e:real``] REAL_ARCH_POW_INV) THEN 5618 ASM_SIMP_TAC std_ss [REAL_INV_1OVER, REAL_HALF_BETWEEN] THEN 5619 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 5620 FULL_SIMP_TAC std_ss [GSYM REAL_INV_1OVER, REAL_POW_INV] THEN 5621 X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LT_TRANS THEN 5622 EXISTS_TAC ``inv (2:real pow N)`` THEN ASM_REWRITE_TAC [] THEN 5623 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``inv(&2:real pow n)`` THEN 5624 ASM_REWRITE_TAC [] THEN REWRITE_TAC [REAL_INV_1OVER] THEN 5625 SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_POW_LT, REAL_ARITH ``0 < 2:real``] THEN 5626 ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN 5627 REWRITE_TAC [GSYM REAL_INV_1OVER, GSYM real_div] THEN SIMP_TAC std_ss [REAL_LE_RDIV_EQ, 5628 REAL_POW_LT, REAL_MUL_LID, REAL_ARITH ``0 < 2:real``] THEN 5629 FULL_SIMP_TAC std_ss [REAL_LE_LT, LESS_OR_EQ] THEN DISJ1_TAC THEN 5630 MATCH_MP_TAC REAL_POW_MONO_LT THEN ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC]]); 5631 5632val LIMPT_SEQUENTIAL = store_thm ("LIMPT_SEQUENTIAL", 5633 ``!x:real s. 5634 x limit_point_of s <=> 5635 ?f. (!n. f(n) IN (s DELETE x)) /\ (f --> x) sequentially``, 5636 REPEAT GEN_TAC THEN EQ_TAC THENL 5637 [REWRITE_TAC[LIMPT_SEQUENTIAL_INJ] THEN MESON_TAC[], 5638 REWRITE_TAC[LIMPT_APPROACHABLE, LIM_SEQUENTIALLY, IN_DELETE] THEN 5639 MESON_TAC[GREATER_EQ, LESS_EQ_REFL]]); 5640 5641val INFINITE_SUPERSET = store_thm ("INFINITE_SUPERSET", 5642 ``!s t. INFINITE s /\ s SUBSET t ==> INFINITE t``, 5643 REWRITE_TAC[] THEN MESON_TAC[SUBSET_FINITE_I]); 5644 5645val LIMPT_INFINITE_OPEN_BALL_CBALL = store_thm ("LIMPT_INFINITE_OPEN_BALL_CBALL", 5646 ``(!s x:real. 5647 x limit_point_of s <=> !t. x IN t /\ open t ==> INFINITE(s INTER t)) /\ 5648 (!s x:real. 5649 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER ball(x,e))) /\ 5650 (!s x:real. 5651 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER cball(x,e)))``, 5652 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT 5653 `(q ==> p) /\ (r ==> s) /\ (s ==> q) /\ (p ==> r) 5654 ==> (p <=> q) /\ (p <=> r) /\ (p <=> s)`) THEN 5655 REPEAT CONJ_TAC THENL 5656 [REWRITE_TAC[limit_point_of, SET_RULE 5657 ``(?y. ~(y = x) /\ y IN s /\ y IN t) <=> ~(s INTER t SUBSET {x})``] THEN 5658 MESON_TAC[SUBSET_FINITE_I, FINITE_SING], 5659 MESON_TAC[INFINITE_SUPERSET, BALL_SUBSET_CBALL, 5660 SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``], 5661 MESON_TAC[INFINITE_SUPERSET, OPEN_CONTAINS_CBALL, 5662 SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``], 5663 REWRITE_TAC[LIMPT_SEQUENTIAL_INJ, IN_DELETE, FORALL_AND_THM] THEN 5664 DISCH_THEN(X_CHOOSE_THEN ``f:num->real`` STRIP_ASSUME_TAC) THEN 5665 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 5666 UNDISCH_TAC ``(f --> x) sequentially`` THEN 5667 GEN_REWR_TAC LAND_CONV [LIM_SEQUENTIALLY] THEN 5668 DISCH_THEN(MP_TAC o SPEC ``e:real``) THEN 5669 ASM_REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] IN_BALL)] THEN 5670 DISCH_THEN(X_CHOOSE_TAC ``N:num``) THEN 5671 MATCH_MP_TAC INFINITE_SUPERSET THEN 5672 EXISTS_TAC ``IMAGE (f:num->real) (from N)`` THEN 5673 ASM_SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE, IN_FROM, IN_INTER] THEN 5674 ASM_MESON_TAC[IMAGE_11_INFINITE, INFINITE_FROM]]); 5675 5676val LIMPT_INFINITE_OPEN = store_thm ("LIMPT_INFINITE_OPEN", 5677 ``(!s x:real. 5678 x limit_point_of s <=> !t. x IN t /\ open t ==> INFINITE(s INTER t))``, 5679 SIMP_TAC std_ss [LIMPT_INFINITE_OPEN_BALL_CBALL]); 5680 5681val LIMPT_INFINITE_BALL = store_thm ("LIMPT_INFINITE_BALL", 5682 ``(!s x:real. 5683 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER ball(x,e)))``, 5684 METIS_TAC [LIMPT_INFINITE_OPEN_BALL_CBALL]); 5685 5686val LIMPT_INFINITE_CBALL = store_thm ("LIMPT_INFINITE_CBALL", 5687 ``(!s x:real. 5688 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER cball(x,e)))``, 5689 METIS_TAC [LIMPT_INFINITE_OPEN_BALL_CBALL]); 5690 5691val INFINITE_OPEN_IN = store_thm ("INFINITE_OPEN_IN", 5692 ``!u s:real->bool. 5693 open_in (subtopology euclidean u) s /\ (?x. x IN s /\ x limit_point_of u) 5694 ==> INFINITE s``, 5695 REPEAT STRIP_TAC THEN 5696 UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN 5697 REWRITE_TAC [OPEN_IN_OPEN] THEN 5698 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 5699 UNDISCH_TAC ``x limit_point_of u`` THEN REWRITE_TAC [LIMPT_INFINITE_OPEN] THEN 5700 FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM_SET_TAC[]); 5701 5702(* ------------------------------------------------------------------------- *) 5703(* Condensation points. *) 5704(* ------------------------------------------------------------------------- *) 5705 5706val _ = set_fixity "condensation_point_of" (Infix(NONASSOC, 450)); 5707 5708val condensation_point_of = new_definition ("condensation_point_of", 5709 ``x condensation_point_of s <=> 5710 !t. x IN t /\ open t ==> ~COUNTABLE(s INTER t)``); 5711 5712val CONDENSATION_POINT_OF_SUBSET = store_thm ("CONDENSATION_POINT_OF_SUBSET", 5713 ``!x:real s t. 5714 x condensation_point_of s /\ s SUBSET t ==> x condensation_point_of t``, 5715 REPEAT GEN_TAC THEN 5716 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 5717 REWRITE_TAC[condensation_point_of] THEN 5718 DISCH_TAC THEN X_GEN_TAC ``t':real->bool`` THEN 5719 POP_ASSUM (MP_TAC o Q.SPEC `t':real->bool`) THEN 5720 MATCH_MP_TAC MONO_IMP THEN 5721 REWRITE_TAC[GSYM MONO_NOT_EQ] THEN 5722 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] COUNTABLE_SUBSET) THEN 5723 ASM_SET_TAC[]); 5724 5725val CONDENSATION_POINT_IMP_LIMPT = store_thm ("CONDENSATION_POINT_IMP_LIMPT", 5726 ``!x s. x condensation_point_of s ==> x limit_point_of s``, 5727 REWRITE_TAC[condensation_point_of, LIMPT_INFINITE_OPEN] THEN 5728 MESON_TAC[FINITE_IMP_COUNTABLE]); 5729 5730val CONDENSATION_POINT_INFINITE_BALL_CBALL = store_thm ("CONDENSATION_POINT_INFINITE_BALL_CBALL", 5731 ``(!s x:real. 5732 x condensation_point_of s <=> 5733 !e. &0 < e ==> ~COUNTABLE(s INTER ball(x,e))) /\ 5734 (!s x:real. 5735 x condensation_point_of s <=> 5736 !e. &0 < e ==> ~COUNTABLE(s INTER cball(x,e)))``, 5737 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT 5738 `(p ==> q) /\ (q ==> r) /\ (r ==> p) 5739 ==> (p <=> q) /\ (p <=> r)`) THEN 5740 REWRITE_TAC[condensation_point_of] THEN REPEAT CONJ_TAC THENL 5741 [MESON_TAC[OPEN_BALL, CENTRE_IN_BALL], 5742 MESON_TAC[BALL_SUBSET_CBALL, COUNTABLE_SUBSET, 5743 SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``], 5744 MESON_TAC[COUNTABLE_SUBSET, OPEN_CONTAINS_CBALL, 5745 SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``]]); 5746 5747val CONDENSATION_POINT_INFINITE_BALL = store_thm ("CONDENSATION_POINT_INFINITE_BALL", 5748 ``(!s x:real. 5749 x condensation_point_of s <=> 5750 !e. &0 < e ==> ~COUNTABLE(s INTER ball(x,e)))``, 5751 METIS_TAC [CONDENSATION_POINT_INFINITE_BALL_CBALL]); 5752 5753val CONDENSATION_POINT_INFINITE_CBALL = store_thm ("CONDENSATION_POINT_INFINITE_CBALL", 5754 ``(!s x:real. 5755 x condensation_point_of s <=> 5756 !e. &0 < e ==> ~COUNTABLE(s INTER cball(x,e)))``, 5757 METIS_TAC [CONDENSATION_POINT_INFINITE_BALL_CBALL]); 5758 5759(* ------------------------------------------------------------------------- *) 5760(* Basic arithmetical combining theorems for limits. *) 5761(* ------------------------------------------------------------------------- *) 5762 5763val LIM_LINEAR = store_thm ("LIM_LINEAR", 5764 ``!net:('a)net h f l. 5765 (f --> l) net /\ linear h ==> ((\x. h(f x)) --> h l) net``, 5766 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN 5767 ASM_CASES_TAC ``trivial_limit (net:('a)net)`` THEN ASM_REWRITE_TAC[] THEN 5768 STRIP_TAC THEN FIRST_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o 5769 MATCH_MP LINEAR_BOUNDED_POS) THEN 5770 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 5771 UNDISCH_TAC ``!e. 0 < e ==> ?y. (?x. netord net x y) /\ 5772 !x. netord net x y ==> dist (f x,l) < e`` THEN DISCH_TAC THEN 5773 FIRST_X_ASSUM(MP_TAC o SPEC ``e / B:real``) THEN 5774 ASM_SIMP_TAC std_ss [REAL_LT_DIV, dist, GSYM LINEAR_SUB, REAL_LT_RDIV_EQ] THEN 5775 ASM_MESON_TAC[REAL_LET_TRANS, REAL_MUL_SYM]); 5776 5777val LIM_CONST = store_thm ("LIM_CONST", 5778 ``!net a:real. ((\x. a) --> a) net``, 5779 SIMP_TAC std_ss [LIM, DIST_REFL, trivial_limit] THEN MESON_TAC[]); 5780 5781val LIM_CMUL = store_thm ("LIM_CMUL", 5782 ``!f l c. (f --> l) net ==> ((\x. c * f x) --> (c * l)) net``, 5783 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_LINEAR THEN 5784 ASM_SIMP_TAC std_ss [REWRITE_RULE[ETA_AX] 5785 (MATCH_MP LINEAR_COMPOSE_CMUL LINEAR_ID)] THEN 5786 REWRITE_TAC [linear] THEN REAL_ARITH_TAC); 5787 5788val LIM_CMUL_EQ = store_thm ("LIM_CMUL_EQ", 5789 ``!net f l c. 5790 ~(c = &0) ==> (((\x. c * f x) --> (c * l)) net <=> (f --> l) net)``, 5791 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [LIM_CMUL] THEN 5792 DISCH_THEN(MP_TAC o SPEC ``inv c:real`` o MATCH_MP LIM_CMUL) THEN 5793 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID, ETA_AX]); 5794 5795val LIM_NEG = store_thm ("LIM_NEG", 5796 ``!net f l:real. (f --> l) net ==> ((\x. -(f x)) --> -l) net``, 5797 REPEAT GEN_TAC THEN REWRITE_TAC[LIM, dist] THEN 5798 SIMP_TAC std_ss [REAL_ARITH ``-x - -y = -(x - y:real)``, ABS_NEG]); 5799 5800val LIM_NEG_EQ = store_thm ("LIM_NEG_EQ", 5801 ``!net f l:real. ((\x. -(f x)) --> -l) net <=> (f --> l) net``, 5802 REPEAT GEN_TAC THEN EQ_TAC THEN 5803 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN 5804 SIMP_TAC std_ss [REAL_NEG_NEG, ETA_AX]); 5805 5806val LIM_ADD = store_thm ("LIM_ADD", 5807 ``!net:('a)net f g l m. 5808 (f --> l) net /\ (g --> m) net ==> ((\x. f(x) + g(x)) --> (l + m)) net``, 5809 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN 5810 ASM_CASES_TAC ``trivial_limit (net:('a)net)`` THEN 5811 ASM_SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN 5812 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 5813 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN 5814 KNOW_TAC ``!x y. (dist(f x, l) < e / 2:real) = 5815 (\x. (dist(f x, l) < e / 2:real)) x`` THENL 5816 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 5817 KNOW_TAC ``!x y. (dist(g x, m) < e / 2:real) = 5818 (\x. (dist(g x, m) < e / 2:real)) x`` THENL 5819 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 5820 DISCH_THEN(MP_TAC o MATCH_MP NET_DILEMMA) THEN BETA_TAC THEN 5821 STRIP_TAC THEN EXISTS_TAC ``c:'a`` THEN CONJ_TAC THENL [METIS_TAC [], ALL_TAC] THEN 5822 GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN REPEAT STRIP_TAC THEN 5823 FULL_SIMP_TAC std_ss [] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 5824 EXISTS_TAC ``dist (f x', l) + dist (g x', m)`` THEN 5825 METIS_TAC[REAL_LT_HALF1, REAL_LT_ADD2, DIST_TRIANGLE_ADD, GSYM REAL_HALF_DOUBLE]); 5826 5827val lemma = prove ( 5828 ``abs(x - y) <= abs(a - b) ==> dist(a,b) < e ==> dist(x,y) < e``, 5829 REWRITE_TAC [dist] THEN REAL_ARITH_TAC); 5830 5831val LIM_ABS = store_thm ("LIM_ABS", 5832 ``!net:('a)net f:'a->real l. 5833 (f --> l) net 5834 ==> ((\x. abs(f(x))) --> (abs(l)):real) net``, 5835 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN 5836 ASM_CASES_TAC ``trivial_limit (net:('a)net)`` THEN ASM_REWRITE_TAC[] THEN 5837 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 5838 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN 5839 STRIP_TAC THEN EXISTS_TAC ``y:'a`` THEN POP_ASSUM MP_TAC THEN 5840 POP_ASSUM MP_TAC THEN REWRITE_TAC [AND_IMP_INTRO] THEN 5841 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN 5842 STRIP_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x:'a`` THEN ASM_REWRITE_TAC [], 5843 ALL_TAC] THEN DISCH_TAC THEN GEN_TAC THEN 5844 POP_ASSUM (MP_TAC o Q.SPEC `x:'a`) THEN 5845 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN 5846 MATCH_MP_TAC lemma THEN BETA_TAC THEN 5847 REAL_ARITH_TAC); 5848 5849val LIM_SUB = store_thm ("LIM_SUB", 5850 ``!net:('a)net f g l m. 5851 (f --> l) net /\ (g --> m) net ==> ((\x. f(x) - g(x)) --> (l - m)) net``, 5852 REWRITE_TAC[real_sub] THEN ASM_SIMP_TAC std_ss [LIM_ADD, LIM_NEG]); 5853 5854val LIM_MAX = store_thm ("LIM_MAX", 5855 ``!net:('a)net f g l:real m:real. 5856 (f --> l) net /\ (g --> m) net 5857 ==> ((\x. max (f(x)) (g(x))) 5858 --> (max (l) (m)):real) net``, 5859 REPEAT GEN_TAC THEN DISCH_TAC THEN 5860 FIRST_ASSUM(MP_TAC o MATCH_MP LIM_ADD) THEN 5861 FIRST_ASSUM(MP_TAC o MATCH_MP LIM_SUB) THEN 5862 DISCH_THEN(MP_TAC o MATCH_MP LIM_ABS) THEN 5863 REWRITE_TAC[AND_IMP_INTRO] THEN 5864 DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN 5865 DISCH_THEN(MP_TAC o SPEC ``inv(&2:real)`` o MATCH_MP LIM_CMUL) THEN 5866 MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN BINOP_TAC THEN 5867 SIMP_TAC std_ss [FUN_EQ_THM, max_def, abs] THEN 5868 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN ONCE_REWRITE_TAC [GSYM real_div] THEN 5869 SIMP_TAC arith_ss [REAL_EQ_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 5870 ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN (RW_TAC arith_ss [REAL_SUB_LE] THENL 5871 [REPEAT (POP_ASSUM MP_TAC) THEN RW_TAC std_ss [AND_IMP_INTRO, REAL_LE_ANTISYM, REAL_SUB_REFL, 5872 REAL_ADD_LID] THEN REWRITE_TAC [GSYM REAL_DOUBLE], 5873 REWRITE_TAC [REAL_ARITH ``a - b + (a + b) = a + a - b + b:real``, REAL_SUB_ADD, REAL_DOUBLE], 5874 REWRITE_TAC [REAL_ARITH ``-(a - b) + (a + b) = b + b - a + a:real``, 5875 REAL_SUB_ADD, REAL_DOUBLE], 5876 FULL_SIMP_TAC real_ss [REAL_NOT_LE] THEN METIS_TAC [REAL_LT_ANTISYM]])); 5877 5878val LIM_MIN = store_thm ("LIM_MIN", 5879 ``!net:('a)net f g l:real m:real. 5880 (f --> l) net /\ (g --> m) net 5881 ==> ((\x. min (f(x)) (g(x))) 5882 --> (min (l) (m)):real) net``, 5883 REPEAT GEN_TAC THEN 5884 DISCH_THEN(CONJUNCTS_THEN(MP_TAC o MATCH_MP LIM_NEG)) THEN 5885 REWRITE_TAC[AND_IMP_INTRO] THEN 5886 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG o MATCH_MP LIM_MAX) THEN 5887 MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN 5888 reverse BINOP_TAC >- PROVE_TAC [GSYM REAL_MIN_MAX, REAL_MIN_ACI] THEN 5889 SIMP_TAC std_ss [FUN_EQ_THM] THEN 5890 GEN_TAC >> PROVE_TAC [GSYM REAL_MIN_MAX, REAL_MIN_ACI]); 5891 5892val LIM_NULL = store_thm ("LIM_NULL", 5893 ``!net f l. (f --> l) net <=> ((\x. f(x) - l) --> 0) net``, 5894 SIMP_TAC arith_ss [LIM, dist, REAL_SUB_RZERO]); 5895 5896val LIM_NULL_ABS = store_thm ("LIM_NULL_ABS", 5897 ``!net f. (f --> 0) net <=> ((\x. (abs(f x))) --> 0) net``, 5898 SIMP_TAC std_ss [LIM, dist, REAL_SUB_RZERO, ABS_ABS]); 5899 5900val LIM_NULL_CMUL_EQ = store_thm ("LIM_NULL_CMUL_EQ", 5901 ``!net f c. 5902 ~(c = &0) ==> (((\x. c * f x) --> 0) net <=> (f --> 0) net)``, 5903 METIS_TAC[LIM_CMUL_EQ, REAL_MUL_RZERO]); 5904 5905val LIM_NULL_CMUL = store_thm ("LIM_NULL_CMUL", 5906 ``!net f c. (f --> 0) net ==> ((\x. c * f x) --> 0) net``, 5907 REPEAT GEN_TAC THEN ASM_CASES_TAC ``c = &0:real`` THEN 5908 ASM_SIMP_TAC std_ss [LIM_NULL_CMUL_EQ, REAL_MUL_LZERO, LIM_CONST]); 5909 5910val LIM_NULL_ADD = store_thm ("LIM_NULL_ADD", 5911 ``!net f g:'a->real. 5912 (f --> 0) net /\ (g --> 0) net 5913 ==> ((\x. f x + g x) --> 0) net``, 5914 REPEAT GEN_TAC THEN 5915 DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN 5916 REWRITE_TAC[REAL_ADD_LID]); 5917 5918val LIM_NULL_SUB = store_thm ("LIM_NULL_SUB", 5919 ``!net f g:'a->real. 5920 (f --> 0) net /\ (g --> 0) net 5921 ==> ((\x. f x - g x) --> 0) net``, 5922 REPEAT GEN_TAC THEN 5923 DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN 5924 REWRITE_TAC[REAL_SUB_RZERO]); 5925 5926val LIM_NULL_COMPARISON = store_thm ("LIM_NULL_COMPARISON", 5927 ``!net f g. eventually (\x. abs(f x) <= g x) net /\ 5928 ((\x. (g x)) --> 0) net 5929 ==> (f --> 0) net``, 5930 REPEAT GEN_TAC THEN SIMP_TAC std_ss [tendsto, RIGHT_AND_FORALL_THM] THEN 5931 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 5932 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [GSYM EVENTUALLY_AND] THEN 5933 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 5934 SIMP_TAC arith_ss [dist, REAL_SUB_RZERO] THEN REAL_ARITH_TAC); 5935 5936val LIM_COMPONENT = store_thm ("LIM_COMPONENT", 5937 ``!net f i l:real. (f --> l) net 5938 ==> ((\a. f(a)) --> l) net``, 5939 REWRITE_TAC[LIM, dist] THEN 5940 METIS_TAC[REAL_LET_TRANS]); 5941 5942val LIM_TRANSFORM_BOUND = store_thm ("LIM_TRANSFORM_BOUND", 5943 ``!f g. eventually (\n. abs(f n) <= abs(g n)) net /\ (g --> 0) net 5944 ==> (f --> 0) net``, 5945 REPEAT GEN_TAC THEN 5946 SIMP_TAC std_ss [tendsto, RIGHT_AND_FORALL_THM] THEN 5947 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 5948 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [GSYM EVENTUALLY_AND] THEN 5949 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 5950 SIMP_TAC arith_ss [dist, REAL_SUB_RZERO] THEN REAL_ARITH_TAC); 5951 5952val LIM_NULL_CMUL_BOUNDED = store_thm ("LIM_NULL_CMUL_BOUNDED", 5953 ``!f g:'a->real B. 5954 eventually (\a. (g a = 0) \/ abs(f a) <= B) net /\ 5955 (g --> 0) net 5956 ==> ((\n. f n * g n) --> 0) net``, 5957 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN STRIP_TAC THEN 5958 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 5959 FIRST_X_ASSUM(MP_TAC o SPEC ``e / (abs B + &1:real)``) THEN 5960 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_ARITH ``&0 < abs x + &1:real``] THEN 5961 UNDISCH_TAC ``eventually 5962 (\(a :'a). ((g :'a -> real) a = (0 :real)) \/ 5963 abs ((f :'a -> real) a) <= (B :real)) (net :'a net)`` THEN 5964 REWRITE_TAC[AND_IMP_INTRO, GSYM EVENTUALLY_AND] THEN 5965 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MP) THEN 5966 SIMP_TAC std_ss [dist, REAL_SUB_RZERO, o_THM, ABS_MUL] THEN 5967 MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC ``x:'a`` THEN BETA_TAC THEN 5968 ASM_CASES_TAC ``(g:'a->real) x = 0`` THEN 5969 ASM_SIMP_TAC std_ss [ABS_0, REAL_MUL_RZERO] THEN 5970 STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 5971 EXISTS_TAC ``B * e / (abs B + &1:real)`` THEN CONJ_TAC THENL 5972 [ONCE_REWRITE_TAC [real_div] THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN 5973 MATCH_MP_TAC REAL_LE_MUL2 THEN ONCE_REWRITE_TAC [GSYM real_div] THEN 5974 ASM_SIMP_TAC std_ss [REAL_ABS_POS, REAL_LT_IMP_LE], ALL_TAC] THEN 5975 SIMP_TAC std_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``&0 < abs x + &1:real``] THEN 5976 MATCH_MP_TAC(REAL_ARITH 5977 ``e * B <= e * abs B /\ &0 < e ==> B * e < e * (abs B + &1:real)``) THEN 5978 ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN REAL_ARITH_TAC); 5979 5980val LIM_SUM = store_thm ("LIM_SUM", 5981 ``!net f:'a->'b->real l s. 5982 FINITE s /\ (!i. i IN s ==> ((f i) --> (l i)) net) 5983 ==> ((\x. sum s (\i. f i x)) --> sum s l) net``, 5984 GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 5985 KNOW_TAC ``!s:'a->bool. ( (!(i :'a). i IN s ==> 5986 ((f :'a -> 'b -> real) i --> (l :'a -> real) i) (net :'b net)) ==> 5987 ((\(x :'b). sum s (\(i :'a). f i x)) --> sum s l) net) = 5988 (\s. (!(i :'a). i IN s ==> 5989 ((f :'a -> 'b -> real) i --> (l :'a -> real) i) (net :'b net)) ==> 5990 ((\(x :'b). sum s (\(i :'a). f i x)) --> sum s l) net) s`` THENL 5991 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 5992 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 5993 SIMP_TAC std_ss [SUM_CLAUSES, LIM_CONST, LIM_ADD, IN_INSERT, ETA_AX] THEN 5994 METIS_TAC [SUM_CLAUSES, LIM_CONST, LIM_ADD, IN_INSERT, ETA_AX]); 5995 5996val LIM_NULL_SUM = store_thm ("LIM_NULL_SUM", 5997 ``!net f:'a->'b->real s. 5998 FINITE s /\ (!a. a IN s ==> ((\x. f x a) --> 0) net) 5999 ==> ((\x. sum s (f x)) --> 0) net``, 6000 REPEAT GEN_TAC THEN 6001 ONCE_REWRITE_TAC [METIS [] ``!a. (\x. f x a) = (\a. (\x. f x a)) a``] THEN 6002 ONCE_REWRITE_TAC [METIS [] ``0:real = (\a. 0) (a:'b)``] THEN 6003 DISCH_THEN(MP_TAC o MATCH_MP LIM_SUM) THEN BETA_TAC THEN 6004 ONCE_REWRITE_TAC [METIS [] ``!i. (\i. f x i) = (\i. f x) i``] THEN 6005 METIS_TAC [SUM_0, ETA_AX]); 6006 6007(* ------------------------------------------------------------------------- *) 6008(* Deducing things about the limit from the elements. *) 6009(* ------------------------------------------------------------------------- *) 6010 6011val LIM_IN_CLOSED_SET = store_thm ("LIM_IN_CLOSED_SET", 6012 ``!net f:'a->real s l. 6013 closed s /\ eventually (\x. f(x) IN s) net /\ 6014 ~(trivial_limit net) /\ (f --> l) net 6015 ==> l IN s``, 6016 REWRITE_TAC[closed_def] THEN REPEAT STRIP_TAC THEN 6017 MATCH_MP_TAC(SET_RULE ``~(x IN (UNIV DIFF s)) ==> x IN s``) THEN 6018 DISCH_TAC THEN UNDISCH_TAC ``open (univ(:real) DIFF s)`` THEN 6019 GEN_REWR_TAC LAND_CONV [OPEN_CONTAINS_BALL] THEN DISCH_TAC THEN 6020 POP_ASSUM (MP_TAC o Q.SPEC `l:real`) THEN 6021 KNOW_TAC ``~(?e. &0 < e /\ (!x. dist (l,x) < e ==> 6022 x IN univ(:real) /\ ~(x IN s)))`` THENL 6023 [ALL_TAC, ASM_SIMP_TAC std_ss [SUBSET_DEF, IN_BALL, IN_DIFF, IN_UNION]] THEN 6024 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 6025 UNDISCH_TAC ``((f:'a->real) --> l) net`` THEN GEN_REWR_TAC LAND_CONV [tendsto] THEN 6026 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 6027 UNDISCH_TAC ``eventually (\x. (f:'a->real) x IN s) net`` THEN 6028 ASM_REWRITE_TAC[GSYM EVENTUALLY_AND, TAUT `a ==> ~b <=> ~(a /\ b)`] THEN 6029 MATCH_MP_TAC NOT_EVENTUALLY THEN ASM_MESON_TAC[DIST_SYM]); 6030 6031(* ------------------------------------------------------------------------- *) 6032(* Need to prove closed(cball(x,e)) before deducing this as a corollary. *) 6033(* ------------------------------------------------------------------------- *) 6034 6035val LIM_ABS_UBOUND = store_thm ("LIM_ABS_UBOUND", 6036 ``!net:('a)net f (l:real) b. 6037 ~(trivial_limit net) /\ (f --> l) net /\ 6038 eventually (\x. abs(f x) <= b) net 6039 ==> abs(l) <= b``, 6040 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6041 ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6042 ASM_REWRITE_TAC[eventually] THEN 6043 STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN 6044 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN 6045 SUBGOAL_THEN 6046 ``?x:'a. dist(f(x):real,l) < abs(l:real) - b /\ abs(f x) <= b`` 6047 (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET], ALL_TAC] THEN 6048 REWRITE_TAC[REAL_NOT_LT, REAL_LE_SUB_RADD, DE_MORGAN_THM, dist] THEN 6049 REAL_ARITH_TAC); 6050 6051val LIM_ABS_LBOUND = store_thm ("LIM_ABS_LBOUND", 6052 ``!net:('a)net f (l:real) b. 6053 ~(trivial_limit net) /\ (f --> l) net /\ 6054 eventually (\x. b <= abs(f x)) net 6055 ==> b <= abs(l)``, 6056 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6057 ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6058 ASM_REWRITE_TAC[eventually] THEN 6059 STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN 6060 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN 6061 SUBGOAL_THEN 6062 ``?x:'a. dist(f(x):real,l) < b - abs(l:real) /\ b <= abs(f x)`` 6063 (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET], ALL_TAC] THEN 6064 REWRITE_TAC[REAL_NOT_LT, REAL_LE_SUB_RADD, DE_MORGAN_THM, dist] THEN 6065 REAL_ARITH_TAC); 6066 6067(* ------------------------------------------------------------------------- *) 6068(* Uniqueness of the limit, when nontrivial. *) 6069(* ------------------------------------------------------------------------- *) 6070 6071val LIM_UNIQUE = store_thm ("LIM_UNIQUE", 6072 ``!net:('a)net f l:real l'. 6073 ~(trivial_limit net) /\ (f --> l) net /\ (f --> l') net ==> (l = l')``, 6074 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6075 DISCH_THEN(ASSUME_TAC o REWRITE_RULE[REAL_SUB_REFL] o MATCH_MP LIM_SUB) THEN 6076 SUBGOAL_THEN ``!e. &0 < e ==> abs(l:real - l') <= e`` MP_TAC THENL 6077 [GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC LIM_ABS_UBOUND THEN 6078 MAP_EVERY EXISTS_TAC [``net:('a)net``, ``\x:'a. 0:real``] THEN 6079 ASM_SIMP_TAC std_ss [ABS_0, REAL_LT_IMP_LE, eventually] THEN 6080 ASM_MESON_TAC[trivial_limit], 6081 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN REWRITE_TAC[DIST_NZ, dist] THEN 6082 DISCH_TAC THEN DISCH_THEN(MP_TAC o SPEC ``abs(l - l':real) / &2``) THEN 6083 ASM_SIMP_TAC arith_ss [REAL_LT_RDIV_EQ, REAL_LE_RDIV_EQ, REAL_LT] THEN 6084 UNDISCH_TAC ``&0 < abs(l - l':real)`` THEN REAL_ARITH_TAC]); 6085 6086val TENDSTO_LIM = store_thm ("TENDSTO_LIM", 6087 ``!net f l. ~(trivial_limit net) /\ (f --> l) net ==> (lim net f = l)``, 6088 REWRITE_TAC[lim_def] THEN METIS_TAC[LIM_UNIQUE]); 6089 6090val LIM_CONST_EQ = store_thm ("LIM_CONST_EQ", 6091 ``!net:('a net) c d:real. 6092 ((\x. c) --> d) net <=> trivial_limit net \/ (c = d)``, 6093 REPEAT GEN_TAC THEN 6094 ASM_CASES_TAC ``trivial_limit (net:'a net)`` THEN ASM_REWRITE_TAC[] THENL 6095 [ASM_REWRITE_TAC[LIM], ALL_TAC] THEN 6096 EQ_TAC THEN SIMP_TAC std_ss [LIM_CONST] THEN DISCH_TAC THEN 6097 MATCH_MP_TAC(SPEC ``net:'a net`` LIM_UNIQUE) THEN 6098 EXISTS_TAC ``(\x. c):'a->real`` THEN ASM_REWRITE_TAC[LIM_CONST]); 6099 6100(* ------------------------------------------------------------------------- *) 6101(* Some unwieldy but occasionally useful theorems about uniform limits. *) 6102(* ------------------------------------------------------------------------- *) 6103 6104val UNIFORM_LIM_ADD = store_thm ("UNIFORM_LIM_ADD", 6105 ``!net:('a)net P f g l m. 6106 (!e:real. &0 < e 6107 ==> eventually (\x. !n:'b. P n ==> abs(f n x - l n) < e) net) /\ 6108 (!e:real. &0 < e 6109 ==> eventually (\x. !n. P n ==> abs(g n x - m n) < e) net) 6110 ==> !e. &0 < e ==> eventually (\x. !n. P n 6111 ==> abs((f n x + g n x) - (l n + m n)) < e) net``, 6112 REPEAT GEN_TAC THEN SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN DISCH_TAC THEN 6113 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6114 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 6115 ASM_REWRITE_TAC[REAL_LT_HALF1, GSYM EVENTUALLY_AND] THEN 6116 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 6117 GEN_TAC THEN REWRITE_TAC[GSYM FORALL_AND_THM] THEN 6118 BETA_TAC THEN STRIP_TAC THEN X_GEN_TAC ``n:'b`` THEN 6119 POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN 6120 ASM_CASES_TAC ``(P:'b->bool) n`` THEN ASM_REWRITE_TAC[] THEN 6121 REPEAT STRIP_TAC THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 6122 REWRITE_TAC [REAL_ADD2_SUB2] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 6123 EXISTS_TAC ``abs ((f:'b->'a->real) n x - l n) + abs (-g n x - -m n):real`` THEN 6124 ASM_REAL_ARITH_TAC); 6125 6126val UNIFORM_LIM_SUB = store_thm ("UNIFORM_LIM_SUB", 6127 ``!net:('a)net P f g l m. 6128 (!e:real. &0 < e 6129 ==> eventually (\x. !n:'b. P n ==> abs(f n x - l n) < e) net) /\ 6130 (!e:real. &0 < e 6131 ==> eventually (\x. !n. P n ==> abs(g n x - m n) < e) net) 6132 ==> !e. &0 < e ==> eventually (\x. !n. P n 6133 ==> abs((f n x - g n x) - (l n - m n)) < e) net``, 6134 REPEAT GEN_TAC THEN SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN DISCH_TAC THEN 6135 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6136 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 6137 ASM_REWRITE_TAC[REAL_LT_HALF1, GSYM EVENTUALLY_AND] THEN 6138 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 6139 GEN_TAC THEN REWRITE_TAC[GSYM FORALL_AND_THM] THEN 6140 BETA_TAC THEN STRIP_TAC THEN X_GEN_TAC ``n:'b`` THEN 6141 POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN 6142 ASM_CASES_TAC ``(P:'b->bool) n`` THEN ASM_REWRITE_TAC[] THEN 6143 REPEAT STRIP_TAC THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 6144 REWRITE_TAC [REAL_ARITH ``abs (f n x - g n x - (l n - m n)):real = 6145 abs (f n x + -g n x - (l n + -m n))``] THEN 6146 REWRITE_TAC [REAL_ADD2_SUB2] THEN 6147 MATCH_MP_TAC REAL_LET_TRANS THEN 6148 EXISTS_TAC ``abs ((f:'b->'a->real) n x - l n) + abs (-g n x - -m n):real`` THEN 6149 REWRITE_TAC [ABS_TRIANGLE] THEN MATCH_MP_TAC REAL_LT_ADD2 THEN 6150 ASM_REWRITE_TAC [REAL_ARITH ``-a - -b = - (a - b):real``, ABS_NEG]); 6151 6152(* ------------------------------------------------------------------------- *) 6153(* Limit under bilinear function, uniform version first. *) 6154(* ------------------------------------------------------------------------- *) 6155 6156val UNIFORM_LIM_BILINEAR = store_thm ("UNIFORM_LIM_BILINEAR", 6157 ``!net:('a)net P (h:real->real->real) f g l m b1 b2. 6158 bilinear h /\ 6159 eventually (\x. !n. P n ==> abs(l n) <= b1) net /\ 6160 eventually (\x. !n. P n ==> abs(m n) <= b2) net /\ 6161 (!e. &0 < e 6162 ==> eventually (\x. !n:'b. P n ==> abs(f n x - l n) < e) net) /\ 6163 (!e. &0 < e 6164 ==> eventually (\x. !n. P n ==> abs(g n x - m n) < e) net) 6165 ==> !e. &0 < e 6166 ==> eventually (\x. !n. P n 6167 ==> abs(h (f n x) (g n x) - h (l n) (m n)) < e) net``, 6168 REPEAT GEN_TAC THEN 6169 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6170 FIRST_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o MATCH_MP 6171 BILINEAR_BOUNDED_POS) THEN 6172 SIMP_TAC std_ss [GSYM FORALL_AND_THM, RIGHT_AND_FORALL_THM] THEN DISCH_TAC THEN 6173 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6174 FIRST_X_ASSUM(MP_TAC o SPEC 6175 ``min (abs b2 + &1:real) (e / &2 / (B * (abs b1 + abs b2 + &2)))``) THEN 6176 ASM_SIMP_TAC std_ss [REAL_LT_HALF1, REAL_LT_DIV, REAL_LT_MUL, REAL_LT_MIN, 6177 REAL_ARITH ``&0 < abs x + &1:real``, 6178 REAL_ARITH ``&0 < abs x + abs y + &2:real``] THEN 6179 REWRITE_TAC[GSYM EVENTUALLY_AND] THEN BETA_TAC THEN 6180 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 6181 X_GEN_TAC ``x:'a`` THEN SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN 6182 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN 6183 ASM_CASES_TAC ``(P:'b->bool) n`` THEN ASM_REWRITE_TAC[] THEN 6184 STRIP_TAC THEN 6185 ONCE_REWRITE_TAC[REAL_ARITH 6186 ``h a b - h c d :real = (h a b - h a d) + (h a d - h c d)``] THEN 6187 ASM_SIMP_TAC std_ss [GSYM BILINEAR_LSUB, GSYM BILINEAR_RSUB] THEN 6188 MATCH_MP_TAC ABS_TRIANGLE_LT THEN 6189 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP 6190 (MESON[REAL_LE_ADD2, REAL_LET_TRANS] 6191 ``(!x y. abs(h x y:real) <= B * abs x * abs y) 6192 ==> B * abs a * abs b + B * abs c * abs d < e 6193 ==> abs(h a b) + abs(h c d) < e``)) THEN 6194 REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN 6195 MATCH_MP_TAC(METIS [REAL_LT_ADD2, REAL_HALF_DOUBLE, REAL_MUL_SYM] 6196 ``x * B < e / &2:real /\ y * B < e / &2:real ==> B * x + B * y < e``) THEN 6197 CONJ_TAC THEN ASM_SIMP_TAC std_ss [GSYM REAL_LT_RDIV_EQ] THENL 6198 [ONCE_REWRITE_TAC[REAL_MUL_SYM], ALL_TAC] THEN 6199 MATCH_MP_TAC REAL_LET_TRANS THEN 6200 EXISTS_TAC ``e / &2 / (B * (abs b1 + abs b2 + &2)) * 6201 (abs b1 + abs b2 + &1:real)`` THEN 6202 (CONJ_TAC THENL 6203 [MATCH_MP_TAC REAL_LE_MUL2 THEN 6204 ASM_SIMP_TAC std_ss [ABS_POS, REAL_LT_IMP_LE] THEN 6205 ASM_SIMP_TAC std_ss [REAL_ARITH ``a <= b2 ==> a <= abs b1 + abs b2 + &1:real``] THEN 6206 ASM_MESON_TAC[REAL_ARITH 6207 ``abs(f - l:real) < abs b2 + &1 /\ abs(l) <= b1 6208 ==> abs(f) <= abs b1 + abs b2 + &1``], 6209 ONCE_REWRITE_TAC[real_div] THEN 6210 KNOW_TAC ``(abs b1 + abs b2 + 2) <> 0:real`` THENL 6211 [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN 6212 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``2:real`` THEN 6213 REWRITE_TAC [REAL_LE_ADDL] THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN 6214 ONCE_REWRITE_TAC [REAL_ARITH ``0 = 0 + 0:real``] THEN MATCH_MP_TAC REAL_LE_ADD2 THEN 6215 REWRITE_TAC [ABS_POS], ALL_TAC] THEN DISCH_TAC THEN 6216 ASM_SIMP_TAC arith_ss [REAL_LT_LMUL, REAL_LT_HALF1, GSYM REAL_MUL_ASSOC, 6217 REAL_INV_MUL, REAL_LT_IMP_NE] THEN REWRITE_TAC [REAL_MUL_ASSOC] THEN 6218 REWRITE_TAC[METIS [real_div, REAL_MUL_RID, REAL_ARITH ``a * b * c = a * c * b:real``] 6219 ``B * inv x * y < B <=> B * y / x < B * &1:real``] THEN 6220 ASM_SIMP_TAC arith_ss [REAL_LT_INV_EQ, REAL_LT_LMUL, REAL_LT_LDIV_EQ, REAL_MUL_RID, 6221 REAL_ARITH ``&0 < abs x + abs y + &2:real``] THEN 6222 REAL_ARITH_TAC])); 6223 6224val LIM_BILINEAR = store_thm ("LIM_BILINEAR", 6225 ``!net:('a)net (h:real->real->real) f g l m. 6226 (f --> l) net /\ (g --> m) net /\ bilinear h 6227 ==> ((\x. h (f x) (g x)) --> (h l m)) net``, 6228 REPEAT STRIP_TAC THEN 6229 MP_TAC(ISPECL 6230 [``net:('a)net``, ``\x:one. T``, ``h:real->real->real``, 6231 ``\n:one. (f:'a->real)``, ``\n:one. (g:'a->real)``, 6232 ``\n:one. (l:real)``, ``\n:one. (m:real)``, 6233 ``abs(l:real)``, ``abs(m:real)``] 6234 UNIFORM_LIM_BILINEAR) THEN 6235 ASM_REWRITE_TAC[REAL_LE_REFL, EVENTUALLY_TRUE] THEN 6236 ASM_SIMP_TAC std_ss [GSYM dist, GSYM tendsto]); 6237 6238(* ------------------------------------------------------------------------- *) 6239(* These are special for limits out of the same vector space. *) 6240(* ------------------------------------------------------------------------- *) 6241 6242val LIM_WITHIN_ID = store_thm ("LIM_WITHIN_ID", 6243 ``!a s. ((\x. x) --> a) (at a within s)``, 6244 REWRITE_TAC[LIM_WITHIN] THEN MESON_TAC[]); 6245 6246val LIM_AT_ID = store_thm ("LIM_AT_ID", 6247 ``!a. ((\x. x) --> a) (at a)``, 6248 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN REWRITE_TAC[LIM_WITHIN_ID]); 6249 6250val LIM_AT_ZERO = store_thm ("LIM_AT_ZERO", 6251 ``!f:real->real l a. 6252 (f --> l) (at a) <=> ((\x. f(a + x)) --> l) (at(0))``, 6253 REPEAT GEN_TAC THEN REWRITE_TAC[LIM_AT] THEN 6254 AP_TERM_TAC THEN ABS_TAC THEN 6255 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN 6256 AP_TERM_TAC THEN ABS_TAC THEN 6257 ASM_CASES_TAC ``&0 < d:real`` THEN ASM_REWRITE_TAC[] THEN 6258 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``x:real`` THENL 6259 [FIRST_X_ASSUM(MP_TAC o SPEC ``a + x:real``) THEN 6260 SIMP_TAC std_ss [dist, REAL_ADD_SUB, REAL_SUB_RZERO], 6261 FIRST_X_ASSUM(MP_TAC o SPEC ``x - a:real``) THEN 6262 SIMP_TAC std_ss [dist, REAL_SUB_RZERO, REAL_SUB_ADD2]]); 6263 6264(* ------------------------------------------------------------------------- *) 6265(* It's also sometimes useful to extract the limit point from the net. *) 6266(* ------------------------------------------------------------------------- *) 6267 6268val netlimit = new_definition ("netlimit", 6269 ``netlimit net = @a. !x. ~(netord net x a)``); 6270 6271val NETLIMIT_WITHIN = store_thm ("NETLIMIT_WITHIN", 6272 ``!a:real s. ~(trivial_limit (at a within s)) 6273 ==> (netlimit (at a within s) = a)``, 6274 REWRITE_TAC[trivial_limit, netlimit, AT, WITHIN, DE_MORGAN_THM] THEN 6275 REPEAT STRIP_TAC THEN MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN 6276 SUBGOAL_THEN 6277 ``!x:real. ~(&0 < dist(x,a) /\ dist(x,a) <= dist(a,a) /\ x IN s)`` 6278 ASSUME_TAC THENL 6279 [ASM_MESON_TAC[DIST_REFL, REAL_NOT_LT], ASM_MESON_TAC[]]); 6280 6281val NETLIMIT_AT = store_thm ("NETLIMIT_AT", 6282 ``!a. netlimit(at a) = a``, 6283 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 6284 MATCH_MP_TAC NETLIMIT_WITHIN THEN 6285 SIMP_TAC std_ss [TRIVIAL_LIMIT_AT, WITHIN_UNIV]); 6286 6287(* ------------------------------------------------------------------------- *) 6288(* Transformation of limit. *) 6289(* ------------------------------------------------------------------------- *) 6290 6291val LIM_TRANSFORM = store_thm ("LIM_TRANSFORM", 6292 ``!net f g l. 6293 ((\x. f x - g x) --> 0) net /\ (f --> l) net ==> (g --> l) net``, 6294 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN 6295 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN MATCH_MP_TAC EQ_IMPLIES THEN 6296 AP_THM_TAC THEN BINOP_TAC THEN SIMP_TAC std_ss [FUN_EQ_THM] THEN 6297 REAL_ARITH_TAC); 6298 6299val LIM_TRANSFORM_EVENTUALLY = store_thm ("LIM_TRANSFORM_EVENTUALLY", 6300 ``!net f g l. 6301 eventually (\x. f x = g x) net /\ (f --> l) net ==> (g --> l) net``, 6302 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN STRIP_TAC THEN 6303 KNOW_TAC ``((\ (x:'a). f x - g x) --> (0:real)) net`` THENL 6304 [METIS_TAC [LIM_EVENTUALLY], ALL_TAC] THEN 6305 METIS_TAC[LIM_TRANSFORM]); 6306 6307val LIM_TRANSFORM_WITHIN = store_thm ("LIM_TRANSFORM_WITHIN", 6308 ``!f g x s d. &0 < d /\ 6309 (!x'. x' IN s /\ &0 < dist(x',x) /\ dist(x',x) < d ==> (f(x') = g(x'))) /\ 6310 (f --> l) (at x within s) ==> (g --> l) (at x within s)``, 6311 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 6312 DISCH_TAC THEN DISCH_TAC THEN 6313 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] LIM_TRANSFORM) THEN 6314 REWRITE_TAC[LIM_WITHIN] THEN REPEAT STRIP_TAC THEN EXISTS_TAC ``d:real`` THEN 6315 ASM_SIMP_TAC std_ss [REAL_SUB_REFL, DIST_REFL]); 6316 6317val LIM_TRANSFORM_AT = store_thm ("LIM_TRANSFORM_AT", 6318 ``!f g x d. &0 < d /\ 6319 (!x'. &0 < dist(x',x) /\ dist(x',x) < d ==> (f(x') = g(x'))) /\ 6320 (f --> l) (at x) ==> (g --> l) (at x)``, 6321 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN MESON_TAC[LIM_TRANSFORM_WITHIN]); 6322 6323val LIM_TRANSFORM_EQ = store_thm ("LIM_TRANSFORM_EQ", 6324 ``!net f:'a->real g l. 6325 ((\x. f x - g x) --> 0) net ==> ((f --> l) net <=> (g --> l) net)``, 6326 REPEAT STRIP_TAC THEN EQ_TAC THEN 6327 DISCH_TAC THEN MATCH_MP_TAC LIM_TRANSFORM THENL 6328 [EXISTS_TAC ``f:'a->real`` THEN ASM_REWRITE_TAC[], 6329 EXISTS_TAC ``g:'a->real`` THEN ASM_REWRITE_TAC[] THEN 6330 ONCE_REWRITE_TAC[GSYM LIM_NEG_EQ] THEN BETA_TAC THEN 6331 ASM_REWRITE_TAC[REAL_NEG_SUB, REAL_NEG_0]]); 6332 6333val LIM_TRANSFORM_WITHIN_SET = store_thm ("LIM_TRANSFORM_WITHIN_SET", 6334 ``!f a s t. 6335 eventually (\x. x IN s <=> x IN t) (at a) 6336 ==> ((f --> l) (at a within s) <=> (f --> l) (at a within t))``, 6337 REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT, LIM_WITHIN] THEN 6338 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 6339 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6340 FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN 6341 DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN 6342 EXISTS_TAC ``min d k:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 6343 ASM_MESON_TAC[]); 6344 6345val LIM_TRANSFORM_WITHIN_SET_IMP = store_thm ("LIM_TRANSFORM_WITHIN_SET_IMP", 6346 ``!f l a s t. 6347 eventually (\x. x IN t ==> x IN s) (at a) /\ (f --> l) (at a within s) 6348 ==> (f --> l) (at a within t)``, 6349 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO, EVENTUALLY_AT, LIM_WITHIN] THEN 6350 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 6351 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6352 FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN 6353 DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN 6354 EXISTS_TAC ``min d k:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 6355 ASM_MESON_TAC[]); 6356 6357(* ------------------------------------------------------------------------- *) 6358(* Common case assuming being away from some crucial point like 0. *) 6359(* ------------------------------------------------------------------------- *) 6360 6361val LIM_TRANSFORM_AWAY_WITHIN = store_thm ("LIM_TRANSFORM_AWAY_WITHIN", 6362 ``!f:real->real g a b s. ~(a = b) /\ 6363 (!x. x IN s /\ ~(x = a) /\ ~(x = b) ==> (f(x) = g(x))) /\ 6364 (f --> l) (at a within s) ==> (g --> l) (at a within s)``, 6365 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN 6366 MAP_EVERY EXISTS_TAC [``f:real->real``, ``dist(a:real,b)``] THEN 6367 ASM_REWRITE_TAC[GSYM DIST_NZ] THEN X_GEN_TAC ``y:real`` THEN 6368 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 6369 ASM_MESON_TAC[DIST_SYM, REAL_LT_REFL]); 6370 6371val LIM_TRANSFORM_AWAY_AT = store_thm ("LIM_TRANSFORM_AWAY_AT", 6372 ``!f:real->real g a b. ~(a = b) /\ 6373 (!x. ~(x = a) /\ ~(x = b) ==> (f(x) = g(x))) /\ 6374 (f --> l) (at a) ==> (g --> l) (at a)``, 6375 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 6376 MESON_TAC[LIM_TRANSFORM_AWAY_WITHIN]); 6377 6378(* ------------------------------------------------------------------------- *) 6379(* Alternatively, within an open set. *) 6380(* ------------------------------------------------------------------------- *) 6381 6382val LIM_TRANSFORM_WITHIN_OPEN = store_thm ("LIM_TRANSFORM_WITHIN_OPEN", 6383 ``!f g:real->real s a l. open s /\ a IN s /\ 6384 (!x. x IN s /\ ~(x = a) ==> (f x = g x)) /\ 6385 (f --> l) (at a) ==> (g --> l) (at a)``, 6386 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_AT THEN 6387 EXISTS_TAC ``f:real->real`` THEN ASM_REWRITE_TAC[] THEN 6388 UNDISCH_TAC ``open s`` THEN GEN_REWR_TAC LAND_CONV [OPEN_CONTAINS_BALL] THEN 6389 DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN ASM_REWRITE_TAC[] THEN 6390 STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN POP_ASSUM MP_TAC THEN 6391 REWRITE_TAC[SUBSET_DEF, IN_BALL] THEN ASM_MESON_TAC[DIST_NZ, DIST_SYM]); 6392 6393val LIM_TRANSFORM_WITHIN_OPEN_IN = store_thm ("LIM_TRANSFORM_WITHIN_OPEN_IN", 6394 ``!f g:real->real s t a l. 6395 open_in (subtopology euclidean t) s /\ a IN s /\ 6396 (!x. x IN s /\ ~(x = a) ==> (f x = g x)) /\ 6397 (f --> l) (at a within t) ==> (g --> l) (at a within t)``, 6398 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN 6399 EXISTS_TAC ``f:real->real`` THEN ASM_REWRITE_TAC[] THEN 6400 UNDISCH_TAC ``open_in (subtopology euclidean t) s`` THEN 6401 GEN_REWR_TAC LAND_CONV [OPEN_IN_CONTAINS_BALL] THEN 6402 DISCH_THEN(MP_TAC o SPEC ``a:real`` o CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN 6403 STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN POP_ASSUM MP_TAC THEN 6404 REWRITE_TAC[SUBSET_DEF, IN_INTER, IN_BALL] THEN ASM_MESON_TAC[DIST_NZ, DIST_SYM]); 6405 6406(* ------------------------------------------------------------------------- *) 6407(* Another quite common idiom of an explicit conditional in a sequence. *) 6408(* ------------------------------------------------------------------------- *) 6409 6410val LIM_CASES_FINITE_SEQUENTIALLY = store_thm ("LIM_CASES_FINITE_SEQUENTIALLY", 6411 ``!f g l. FINITE {n | P n} 6412 ==> (((\n. if P n then f n else g n) --> l) sequentially <=> 6413 (g --> l) sequentially)``, 6414 REPEAT STRIP_TAC THEN EQ_TAC THEN 6415 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] LIM_TRANSFORM_EVENTUALLY) THEN 6416 FIRST_ASSUM(MP_TAC o SPEC ``\n:num. n`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN 6417 SIMP_TAC std_ss [GSPECIFICATION, LEFT_IMP_EXISTS_THM] THEN 6418 X_GEN_TAC ``N:num`` THEN DISCH_TAC THEN SIMP_TAC std_ss [EVENTUALLY_SEQUENTIALLY] THEN 6419 EXISTS_TAC ``N + 1:num`` THEN 6420 METIS_TAC[ARITH_PROVE ``~(x <= n:num /\ n + 1 <= x)``]); 6421 6422val lemma = prove ( 6423 ``(if p then x else y) = (if ~p then y else x)``, 6424 RW_TAC std_ss []); 6425 6426val LIM_CASES_COFINITE_SEQUENTIALLY = store_thm ("LIM_CASES_COFINITE_SEQUENTIALLY", 6427 ``!f g l. FINITE {n | ~P n} 6428 ==> (((\n. if P n then f n else g n) --> l) sequentially <=> 6429 (f --> l) sequentially)``, 6430 ONCE_REWRITE_TAC[lemma] THEN 6431 SIMP_TAC std_ss [LIM_CASES_FINITE_SEQUENTIALLY]); 6432 6433val LIM_CASES_SEQUENTIALLY = store_thm ("LIM_CASES_SEQUENTIALLY", 6434 ``!f g l m. (((\n. if m <= n then f n else g n) --> l) sequentially <=> 6435 (f --> l) sequentially) /\ 6436 (((\n. if m < n then f n else g n) --> l) sequentially <=> 6437 (f --> l) sequentially) /\ 6438 (((\n. if n <= m then f n else g n) --> l) sequentially <=> 6439 (g --> l) sequentially) /\ 6440 (((\n. if n < m then f n else g n) --> l) sequentially <=> 6441 (g --> l) sequentially)``, 6442 SIMP_TAC std_ss [LIM_CASES_FINITE_SEQUENTIALLY, LIM_CASES_COFINITE_SEQUENTIALLY, 6443 NOT_LESS, NOT_LESS_EQUAL, FINITE_NUMSEG_LT, FINITE_NUMSEG_LE]); 6444 6445(* ------------------------------------------------------------------------- *) 6446(* A congruence rule allowing us to transform limits assuming not at point. *) 6447(* ------------------------------------------------------------------------- *) 6448 6449val LIM_CONG_WITHIN = store_thm ("LIM_CONG_WITHIN", 6450 ``(!x. ~(x = a) ==> (f x = g x)) 6451 ==> (((\x. f x) --> l) (at a within s) <=> ((g --> l) (at a within s)))``, 6452 REWRITE_TAC[LIM_WITHIN, GSYM DIST_NZ] THEN SIMP_TAC std_ss []); 6453 6454val LIM_CONG_AT = store_thm ("LIM_CONG_AT", 6455 ``(!x. ~(x = a) ==> (f x = g x)) 6456 ==> (((\x. f x) --> l) (at a) <=> ((g --> l) (at a)))``, 6457 REWRITE_TAC[LIM_AT, GSYM DIST_NZ] THEN SIMP_TAC std_ss []); 6458 6459(* ------------------------------------------------------------------------- *) 6460(* Useful lemmas on closure and set of possible sequential limits. *) 6461(* ------------------------------------------------------------------------- *) 6462 6463val CLOSURE_SEQUENTIAL = store_thm ("CLOSURE_SEQUENTIAL", 6464 ``!s l:real. 6465 l IN closure(s) <=> ?x. (!n. x(n) IN s) /\ (x --> l) sequentially``, 6466 SIMP_TAC std_ss [closure, IN_UNION, LIMPT_SEQUENTIAL, GSPECIFICATION, IN_DELETE] THEN 6467 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT 6468 `((b ==> c) /\ (~a /\ c ==> b)) /\ (a ==> c) ==> (a \/ b <=> c)`) THEN 6469 CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN DISCH_TAC THEN 6470 EXISTS_TAC ``\n:num. l:real`` THEN ASM_REWRITE_TAC[LIM_CONST]); 6471 6472val CLOSED_CONTAINS_SEQUENTIAL_LIMIT = store_thm ("CLOSED_CONTAINS_SEQUENTIAL_LIMIT", 6473 ``!s x l:real. 6474 closed s /\ (!n. x n IN s) /\ (x --> l) sequentially ==> l IN s``, 6475 MESON_TAC[CLOSURE_SEQUENTIAL, CLOSURE_CLOSED]); 6476 6477val CLOSED_SEQUENTIAL_LIMITS = store_thm ("CLOSED_SEQUENTIAL_LIMITS", 6478 ``!s. closed s <=> 6479 !x l. (!n. x(n) IN s) /\ (x --> l) sequentially ==> l IN s``, 6480 MESON_TAC[CLOSURE_SEQUENTIAL, CLOSURE_CLOSED, 6481 CLOSED_LIMPT, LIMPT_SEQUENTIAL, IN_DELETE]); 6482 6483val CLOSED_APPROACHABLE = store_thm ("CLOSED_APPROACHABLE", 6484 ``!x s. closed s 6485 ==> ((!e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e) <=> x IN s)``, 6486 MESON_TAC[CLOSURE_CLOSED, CLOSURE_APPROACHABLE]); 6487 6488val IN_CLOSURE_DELETE = store_thm ("IN_CLOSURE_DELETE", 6489 ``!s x:real. x IN closure(s DELETE x) <=> x limit_point_of s``, 6490 SIMP_TAC std_ss [CLOSURE_APPROACHABLE, LIMPT_APPROACHABLE, IN_DELETE, CONJ_ASSOC]); 6491 6492val DENSE_IMP_PERFECT = store_thm ("DENSE_IMP_PERFECT", 6493 ``!s. (closure s = univ(:real)) ==> !x. x IN s ==> x limit_point_of s``, 6494 REPEAT STRIP_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN 6495 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6496 KNOW_TAC ``~(!x'. ~(x' = x) /\ dist (x',x) < e ==> ~(x' IN s))`` THENL 6497 [ALL_TAC, METIS_TAC []] THEN DISCH_TAC THEN 6498 MP_TAC(ISPECL [``x:real``, ``e / &2:real``] REAL_CHOOSE_DIST) THEN 6499 KNOW_TAC ``~(?y. dist (x,y) = e / &2)`` THENL 6500 [ALL_TAC, ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE, REAL_LT_HALF1]] THEN 6501 DISCH_THEN(X_CHOOSE_TAC ``y:real``) THEN 6502 FIRST_ASSUM(MP_TAC o SPEC ``y:real`` o MATCH_MP (SET_RULE 6503 ``(s = UNIV) ==> !x. x IN s``)) THEN 6504 REWRITE_TAC[CLOSURE_APPROACHABLE] THEN 6505 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN 6506 ASM_SIMP_TAC std_ss [REAL_HALF, NOT_EXISTS_THM] THEN 6507 X_GEN_TAC ``z:real`` THEN FIRST_X_ASSUM(MP_TAC o SPEC ``z:real``) THEN 6508 ASM_CASES_TAC ``(z:real) IN s`` THEN ASM_REWRITE_TAC[] THEN 6509 SIMP_TAC std_ss [] THEN STRIP_TAC THENL 6510 [METIS_TAC [REAL_LE_LT, REAL_NOT_LT], ALL_TAC] THEN 6511 DISCH_TAC THEN UNDISCH_TAC ``~(dist (z,x) < e)`` THEN REWRITE_TAC [] THEN 6512 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 6513 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``dist (z,y) + dist (y,x)`` THEN 6514 REWRITE_TAC [DIST_TRIANGLE] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN 6515 ASM_REWRITE_TAC [] THEN METIS_TAC [REAL_LT_RADD, DIST_SYM]); 6516 6517val DENSE_LIMIT_POINTS = store_thm ("DENSE_LIMIT_POINTS", 6518 ``!x. ({x | x limit_point_of s} = univ(:real)) <=> (closure s = univ(:real))``, 6519 GEN_TAC THEN EQ_TAC THENL [SIMP_TAC std_ss [closure] THEN SET_TAC[], DISCH_TAC] THEN 6520 FIRST_ASSUM(MP_TAC o MATCH_MP DENSE_IMP_PERFECT) THEN 6521 RULE_ASSUM_TAC(REWRITE_RULE[closure]) THEN ASM_SET_TAC[]); 6522 6523(* ------------------------------------------------------------------------- *) 6524(* Some other lemmas about sequences. *) 6525(* ------------------------------------------------------------------------- *) 6526 6527val SEQ_OFFSET = store_thm ("SEQ_OFFSET", 6528 ``!f l k. (f --> l) sequentially ==> ((\i. f(i + k)) --> l) sequentially``, 6529 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 6530 MESON_TAC[ARITH_PROVE ``N <= n ==> N <= n + k:num``]); 6531 6532val SEQ_OFFSET_NEG = store_thm ("SEQ_OFFSET_NEG", 6533 ``!f l k. (f --> l) sequentially ==> ((\i. f(i - k)) --> l) sequentially``, 6534 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 6535 MESON_TAC[ARITH_PROVE ``N + k <= n ==> N <= n - k:num``]); 6536 6537val SEQ_OFFSET_REV = store_thm ("SEQ_OFFSET_REV", 6538 ``!f l k. ((\i. f(i + k)) --> l) sequentially ==> (f --> l) sequentially``, 6539 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 6540 MESON_TAC[ARITH_PROVE ``N + k <= n ==> N <= n - k /\ ((n - k) + k = n:num)``]); 6541 6542val SEQ_HARMONIC_OFFSET = store_thm ("SEQ_HARMONIC_OFFSET", 6543 ``!a. ((\n. inv(&n + a)) --> 0) sequentially``, 6544 GEN_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN 6545 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6546 ASSUME_TAC REAL_ARCH_INV THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 6547 ASM_REWRITE_TAC [] THEN DISCH_THEN (X_CHOOSE_THEN ``N:num`` STRIP_ASSUME_TAC) THEN 6548 X_CHOOSE_THEN ``M:num`` STRIP_ASSUME_TAC 6549 (SPEC ``-a:real`` SIMP_REAL_ARCH) THEN 6550 EXISTS_TAC ``M + N:num`` THEN REWRITE_TAC[DIST_0] THEN 6551 X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 6552 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``inv (&N:real)`` THEN 6553 KNOW_TAC ``(&n + a:real) <> 0`` THENL 6554 [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN 6555 UNDISCH_TAC ``-a <= &M:real`` THEN 6556 GEN_REWR_TAC LAND_CONV [GSYM REAL_LE_NEG] THEN REWRITE_TAC [REAL_NEG_NEG] THEN 6557 DISCH_TAC THEN FULL_SIMP_TAC arith_ss [GSYM REAL_LE, GSYM REAL_ADD] THEN 6558 KNOW_TAC ``&M + &N + (-&M) <= &n + a:real`` THENL 6559 [FULL_SIMP_TAC arith_ss [REAL_LE_ADD2], ALL_TAC] THEN 6560 REWRITE_TAC [GSYM real_sub] THEN ONCE_REWRITE_TAC [REAL_ADD_COMM] THEN 6561 REWRITE_TAC [REAL_ADD_SUB_ALT] THEN DISCH_TAC THEN 6562 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``&N:real`` THEN 6563 FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ], ALL_TAC] THEN DISCH_TAC THEN 6564 BETA_TAC THEN ASM_SIMP_TAC arith_ss [ABS_INV] THEN 6565 MATCH_MP_TAC REAL_LE_INV2 THEN FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ] THEN 6566 RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE, GSYM REAL_OF_NUM_ADD]) THEN 6567 ASM_REAL_ARITH_TAC); 6568 6569val SEQ_HARMONIC = store_thm ("SEQ_HARMONIC", 6570 ``((\n. inv(&n)) --> 0) sequentially``, 6571 MP_TAC(SPEC ``&0:real`` SEQ_HARMONIC_OFFSET) THEN REWRITE_TAC[REAL_ADD_RID]); 6572 6573(* ------------------------------------------------------------------------- *) 6574(* More properties of closed balls. *) 6575(* ------------------------------------------------------------------------- *) 6576 6577val CLOSED_CBALL = store_thm ("CLOSED_CBALL", 6578 ``!x:real e. closed(cball(x,e))``, 6579 REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS, IN_CBALL, dist] THEN 6580 GEN_TAC THEN GEN_TAC THEN X_GEN_TAC ``s:num->real`` THEN 6581 X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 6582 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_ABS_UBOUND) THEN 6583 EXISTS_TAC ``\n. x - (s:num->real) n`` THEN 6584 REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY, EVENTUALLY_SEQUENTIALLY] THEN 6585 ASM_SIMP_TAC std_ss [LIM_SUB, LIM_CONST, SEQUENTIALLY]); 6586 6587val IN_INTERIOR_CBALL = store_thm ("IN_INTERIOR_CBALL", 6588 ``!x s. x IN interior s <=> ?e. &0 < e /\ cball(x,e) SUBSET s``, 6589 SIMP_TAC std_ss [interior, GSPECIFICATION] THEN 6590 MESON_TAC[OPEN_CONTAINS_CBALL, SUBSET_TRANS, 6591 BALL_SUBSET_CBALL, CENTRE_IN_BALL, OPEN_BALL]); 6592 6593val LIMPT_BALL = store_thm ("LIMPT_BALL", 6594 ``!x:real y e. y limit_point_of ball(x,e) <=> &0 < e /\ y IN cball(x,e)``, 6595 REPEAT GEN_TAC THEN ASM_CASES_TAC ``&0 < e:real`` THENL 6596 [ALL_TAC, ASM_MESON_TAC[LIMPT_EMPTY, REAL_NOT_LT, BALL_EQ_EMPTY]] THEN 6597 ASM_REWRITE_TAC[] THEN EQ_TAC THENL 6598 [MESON_TAC[CLOSED_CBALL, CLOSED_LIMPT, LIMPT_SUBSET, BALL_SUBSET_CBALL], 6599 REWRITE_TAC[IN_CBALL, LIMPT_APPROACHABLE, IN_BALL]] THEN 6600 DISCH_TAC THEN X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN 6601 ASM_CASES_TAC ``y:real = x`` THEN ASM_REWRITE_TAC[DIST_NZ] THENL 6602 [MP_TAC(SPECL [``d:real``, ``e:real``] REAL_DOWN2) THEN 6603 ASM_REWRITE_TAC[] THEN 6604 GEN_MESON_TAC 0 40 1 [REAL_CHOOSE_DIST, DIST_SYM, REAL_LT_IMP_LE], 6605 ALL_TAC] THEN 6606 MP_TAC(SPECL [``abs(y:real - x)``, ``d:real``] REAL_DOWN2) THEN 6607 RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ, dist]) THEN ASM_REWRITE_TAC[] THEN 6608 DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN 6609 EXISTS_TAC ``(y:real) - (k / dist(y,x)) * (y - x)`` THEN 6610 REWRITE_TAC[dist, REAL_ARITH ``(y - c * z) - y = -c * z:real``] THEN 6611 ASM_SIMP_TAC std_ss [ABS_MUL, ABS_DIV, ABS_ABS, ABS_NEG, REAL_POS_NZ] THEN 6612 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN 6613 REWRITE_TAC[REAL_ARITH ``x - (y - k * (y - x)) = (&1 - k) * (x - y:real)``] THEN 6614 ASM_SIMP_TAC std_ss [REAL_ARITH ``&0 < k ==> &0 < abs k:real``, ABS_MUL] THEN 6615 ASM_SIMP_TAC std_ss [REAL_ARITH ``&0 < k /\ k < d ==> abs k < d:real``] THEN 6616 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``abs(x:real - y)`` THEN 6617 ASM_REWRITE_TAC[] THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN 6618 KNOW_TAC ``0:real < abs (x - y)`` THENL [ASM_MESON_TAC[ABS_SUB], ALL_TAC] THEN 6619 DISCH_TAC THEN ASM_SIMP_TAC std_ss [REAL_LT_RMUL] THEN 6620 MATCH_MP_TAC(REAL_ARITH ``&0 < k /\ k < &1 ==> abs(&1 - k) < &1:real``) THEN 6621 ASM_SIMP_TAC std_ss [REAL_LT_LDIV_EQ, REAL_LT_RDIV_EQ, REAL_MUL_LZERO, 6622 REAL_MUL_LID]); 6623 6624val CLOSURE_BALL = store_thm ("CLOSURE_BALL", 6625 ``!x:real e. &0 < e ==> (closure(ball(x,e)) = cball(x,e))``, 6626 SIMP_TAC std_ss [EXTENSION, closure, GSPECIFICATION, IN_UNION, LIMPT_BALL] THEN 6627 REWRITE_TAC[IN_BALL, IN_CBALL] THEN REAL_ARITH_TAC); 6628 6629val INTERIOR_BALL = store_thm ("INTERIOR_BALL", 6630 ``!a r. interior(ball(a,r)) = ball(a,r)``, 6631 SIMP_TAC std_ss [INTERIOR_OPEN, OPEN_BALL]); 6632 6633val INTERIOR_CBALL = store_thm ("INTERIOR_CBALL", 6634 ``!x:real e. interior(cball(x,e)) = ball(x,e)``, 6635 REPEAT GEN_TAC THEN ASM_CASES_TAC ``&0 <= e:real`` THENL 6636 [ALL_TAC, 6637 SUBGOAL_THEN ``(cball(x:real,e) = {}) /\ (ball(x:real,e) = {})`` 6638 (fn th => REWRITE_TAC[th, INTERIOR_EMPTY]) THEN 6639 REWRITE_TAC[IN_BALL, IN_CBALL, EXTENSION, NOT_IN_EMPTY] THEN 6640 CONJ_TAC THEN X_GEN_TAC ``y:real`` THEN 6641 MP_TAC(ISPECL [``x:real``, ``y:real``] DIST_POS_LE) THEN 6642 POP_ASSUM MP_TAC THEN REAL_ARITH_TAC] THEN 6643 MATCH_MP_TAC INTERIOR_UNIQUE THEN 6644 REWRITE_TAC[BALL_SUBSET_CBALL, OPEN_BALL] THEN 6645 X_GEN_TAC ``t:real->bool`` THEN 6646 SIMP_TAC std_ss [SUBSET_DEF, IN_CBALL, IN_BALL, REAL_LT_LE] THEN STRIP_TAC THEN 6647 X_GEN_TAC ``z:real`` THEN DISCH_TAC THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN 6648 UNDISCH_TAC ``open t`` THEN REWRITE_TAC [open_def] THEN 6649 DISCH_THEN(MP_TAC o SPEC ``z:real``) THEN 6650 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN ``d:real`` MP_TAC) THEN 6651 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6652 ASM_CASES_TAC ``z:real = x`` THENL 6653 [FIRST_X_ASSUM SUBST_ALL_TAC THEN 6654 FIRST_X_ASSUM(X_CHOOSE_TAC ``k:real`` o MATCH_MP REAL_DOWN) THEN 6655 SUBGOAL_THEN ``?w:real. dist(w,x) = k`` STRIP_ASSUME_TAC THENL 6656 [ASM_MESON_TAC[REAL_CHOOSE_DIST, DIST_SYM, REAL_LT_IMP_LE], 6657 ASM_MESON_TAC[REAL_NOT_LE, DIST_REFL, DIST_SYM]], 6658 RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ]) THEN 6659 DISCH_THEN(MP_TAC o SPEC ``z + ((d / &2) / dist(z,x)) * (z - x:real)``) THEN 6660 FULL_SIMP_TAC arith_ss [dist, REAL_ADD_SUB, ABS_MUL, ABS_DIV, 6661 ABS_ABS, ABS_N, REAL_POS_NZ, REAL_ARITH ``0 < 2:real``] THEN 6662 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, GSYM dist, REAL_POS_NZ] THEN 6663 ASM_SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_LT] THEN 6664 ASM_REWRITE_TAC [REAL_ARITH ``abs d < d * &2 <=> &0 < d:real``] THEN 6665 DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN REWRITE_TAC[dist] THEN 6666 REWRITE_TAC[REAL_ARITH ``x - (z + k * (z - x)) = (&1 + k) * (x - z:real)``] THEN 6667 REWRITE_TAC[REAL_NOT_LE, ABS_MUL] THEN 6668 GEN_REWR_TAC LAND_CONV [GSYM REAL_MUL_LID] THEN 6669 ONCE_REWRITE_TAC[ABS_SUB] THEN 6670 ASM_SIMP_TAC std_ss [REAL_LT_RMUL, GSYM dist] THEN 6671 MATCH_MP_TAC(REAL_ARITH ``&0 < x ==> &1:real < abs(&1 + x)``) THEN 6672 ONCE_REWRITE_TAC[DIST_SYM] THEN 6673 ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT, dist]]); 6674 6675val FRONTIER_BALL = store_thm ("FRONTIER_BALL", 6676 ``!a e. &0 < e ==> (frontier(ball(a,e)) = sphere(a,e))``, 6677 SIMP_TAC std_ss [frontier, sphere, CLOSURE_BALL, INTERIOR_OPEN, OPEN_BALL, 6678 REAL_LT_IMP_LE] THEN 6679 SIMP_TAC std_ss [EXTENSION, IN_DIFF, GSPECIFICATION, IN_BALL, IN_CBALL] THEN 6680 REAL_ARITH_TAC); 6681 6682val FRONTIER_CBALL = store_thm ("FRONTIER_CBALL", 6683 ``!a e. (frontier(cball(a,e)) = sphere(a,e))``, 6684 SIMP_TAC std_ss [frontier, sphere, INTERIOR_CBALL, CLOSED_CBALL, CLOSURE_CLOSED, 6685 REAL_LT_IMP_LE] THEN 6686 SIMP_TAC std_ss [EXTENSION, IN_DIFF, SPECIFICATION, IN_BALL, IN_CBALL, dist] THEN 6687 GEN_REWR_TAC (QUANT_CONV o QUANT_CONV o QUANT_CONV o RAND_CONV) [GSYM SPECIFICATION] THEN 6688 SIMP_TAC std_ss [GSPECIFICATION] THEN REAL_ARITH_TAC); 6689 6690val CBALL_EQ_EMPTY = store_thm ("CBALL_EQ_EMPTY", 6691 ``!x e. (cball(x,e) = {}) <=> e < &0``, 6692 REWRITE_TAC[EXTENSION, IN_CBALL, NOT_IN_EMPTY, REAL_NOT_LE] THEN 6693 MESON_TAC[DIST_POS_LE, DIST_REFL, REAL_LTE_TRANS]); 6694 6695val CBALL_EMPTY = store_thm ("CBALL_EMPTY", 6696 ``!x e. e < &0 ==> (cball(x,e) = {})``, 6697 REWRITE_TAC[CBALL_EQ_EMPTY]); 6698 6699val CBALL_EQ_SING = store_thm ("CBALL_EQ_SING", 6700 ``!x:real e. (cball(x,e) = {x}) <=> (e = &0)``, 6701 REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION, IN_CBALL, IN_SING] THEN 6702 EQ_TAC THENL [ALL_TAC, MESON_TAC[DIST_LE_0]] THEN 6703 DISCH_THEN(fn th => MP_TAC(SPEC ``x + (e / &2) * 1:real`` th) THEN 6704 MP_TAC(SPEC ``x:real`` th)) THEN 6705 REWRITE_TAC[dist, REAL_ARITH ``x - (x + e):real = -e``, 6706 REAL_ARITH ``(x + e = x) <=> (e:real = 0)``] THEN 6707 REWRITE_TAC[ABS_NEG, ABS_MUL, REAL_ENTIRE, ABS_0, REAL_SUB_REFL] THEN 6708 SIMP_TAC std_ss [ABS_1, REAL_ARITH ``~(1 = 0:real)``] THEN 6709 SIMP_TAC arith_ss [REAL_MUL_RID, REAL_EQ_LDIV_EQ, 6710 REAL_ARITH ``0 < 2:real``, REAL_MUL_LZERO] THEN 6711 GEN_REWR_TAC LAND_CONV [REAL_LE_LT] THEN RW_TAC arith_ss [] THEN 6712 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN ASM_REWRITE_TAC [abs] THEN 6713 COND_CASES_TAC THENL 6714 [FULL_SIMP_TAC std_ss [REAL_LE_LT] THEN DISJ1_TAC THEN 6715 ASM_SIMP_TAC std_ss [REAL_LT_HALF2], ALL_TAC] THEN 6716 UNDISCH_TAC ``0 < e:real`` THEN GEN_REWR_TAC LAND_CONV [GSYM REAL_LT_HALF1] THEN 6717 DISCH_TAC THEN FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN METIS_TAC [REAL_LT_ANTISYM]); 6718 6719val CBALL_SING = store_thm ("CBALL_SING", 6720 ``!x e. (e = &0) ==> (cball(x,e) = {x})``, 6721 REWRITE_TAC[CBALL_EQ_SING]); 6722 6723val SPHERE_SING = store_thm ("SPHERE_SING", 6724 ``!x e. (e = &0) ==> (sphere(x,e) = {x})``, 6725 SIMP_TAC std_ss [sphere, DIST_EQ_0, GSPEC_EQ, GSPEC_EQ2]); 6726 6727val SPHERE_EQ_SING = store_thm ("SPHERE_EQ_SING", 6728 ``!a:real r x. (sphere(a,r) = {x}) <=> (x = a) /\ (r = &0)``, 6729 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [SPHERE_SING] THEN 6730 ASM_CASES_TAC ``r < &0:real`` THEN ASM_SIMP_TAC std_ss [SPHERE_EMPTY, NOT_INSERT_EMPTY] THEN 6731 ASM_CASES_TAC ``r = &0:real`` THEN ASM_SIMP_TAC std_ss [SPHERE_SING] THENL 6732 [ASM_SET_TAC[], ALL_TAC] THEN 6733 MATCH_MP_TAC(SET_RULE 6734 ``!y. (x IN s ==> y IN s /\ ~(y = x)) ==> ~(s = {x})``) THEN 6735 EXISTS_TAC ``a - (x - a):real`` THEN REWRITE_TAC[IN_SPHERE] THEN 6736 REWRITE_TAC [dist] THEN REPEAT(POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC); 6737 6738(* ------------------------------------------------------------------------- *) 6739(* For points in the interior, localization of limits makes no difference. *) 6740(* ------------------------------------------------------------------------- *) 6741 6742val EVENTUALLY_WITHIN_INTERIOR = store_thm ("EVENTUALLY_WITHIN_INTERIOR", 6743 ``!p s x. 6744 x IN interior s 6745 ==> (eventually p (at x within s) <=> eventually p (at x))``, 6746 REWRITE_TAC[EVENTUALLY_WITHIN, EVENTUALLY_AT, IN_INTERIOR] THEN 6747 REPEAT GEN_TAC THEN SIMP_TAC std_ss [SUBSET_DEF, IN_BALL] THEN 6748 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 6749 EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 6750 EXISTS_TAC ``min (d:real) e`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 6751 ASM_MESON_TAC[DIST_SYM]); 6752 6753val LIM_WITHIN_INTERIOR = store_thm ("LIM_WITHIN_INTERIOR", 6754 ``!f l s x. x IN interior s 6755 ==> ((f --> l) (at x within s) <=> (f --> l) (at x))``, 6756 SIMP_TAC std_ss [tendsto, EVENTUALLY_WITHIN_INTERIOR]); 6757 6758val NETLIMIT_WITHIN_INTERIOR = store_thm ("NETLIMIT_WITHIN_INTERIOR", 6759 ``!s x:real. x IN interior s ==> (netlimit(at x within s) = x)``, 6760 REPEAT STRIP_TAC THEN MATCH_MP_TAC NETLIMIT_WITHIN THEN 6761 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN 6762 FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[OPEN_CONTAINS_BALL] 6763 (SPEC_ALL OPEN_INTERIOR))) THEN 6764 ASM_MESON_TAC[LIMPT_SUBSET, LIMPT_BALL, CENTRE_IN_CBALL, REAL_LT_IMP_LE, 6765 SUBSET_TRANS, INTERIOR_SUBSET]); 6766 6767(* ------------------------------------------------------------------------- *) 6768(* A non-singleton connected set is perfect (i.e. has no isolated points). *) 6769(* ------------------------------------------------------------------------- *) 6770 6771val CONNECTED_IMP_PERFECT = store_thm ("CONNECTED_IMP_PERFECT", 6772 ``!s x:real. 6773 connected s /\ ~(?a. s = {a}) /\ x IN s ==> x limit_point_of s``, 6774 REPEAT STRIP_TAC THEN REWRITE_TAC[limit_point_of] THEN 6775 X_GEN_TAC ``t:real->bool`` THEN STRIP_TAC THEN 6776 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN 6777 KNOW_TAC ``open t`` THENL [ASM_REWRITE_TAC [], ALL_TAC] THEN 6778 GEN_REWR_TAC LAND_CONV [OPEN_CONTAINS_CBALL] THEN 6779 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x:real`) THEN 6780 ASM_REWRITE_TAC[] THEN 6781 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 6782 UNDISCH_TAC ``connected s`` THEN GEN_REWR_TAC LAND_CONV [CONNECTED_CLOPEN] THEN 6783 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `{x:real}`) THEN 6784 REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL 6785 [REWRITE_TAC[OPEN_IN_OPEN] THEN EXISTS_TAC ``t:real->bool`` THEN 6786 ASM_SET_TAC[], 6787 REWRITE_TAC[CLOSED_IN_CLOSED] THEN 6788 EXISTS_TAC ``cball(x:real,e)`` THEN REWRITE_TAC[CLOSED_CBALL] THEN 6789 REWRITE_TAC[EXTENSION, IN_INTER, IN_SING] THEN 6790 ASM_MESON_TAC[CENTRE_IN_CBALL, SUBSET_DEF, REAL_LT_IMP_LE], 6791 ASM_SET_TAC[]]); 6792 6793val CONNECTED_IMP_PERFECT_CLOSED = store_thm ("CONNECTED_IMP_PERFECT_CLOSED", 6794 ``!s x. connected s /\ closed s /\ ~(?a. s = {a}) 6795 ==> (x limit_point_of s <=> x IN s)``, 6796 MESON_TAC[CONNECTED_IMP_PERFECT, CLOSED_LIMPT]); 6797 6798(* ------------------------------------------------------------------------- *) 6799(* Boundedness. *) 6800(* ------------------------------------------------------------------------- *) 6801 6802val bounded_def = new_definition ("bounded_def", 6803 ``bounded_def s <=> ?a. !x:real. x IN s ==> abs(x) <= a``); 6804 6805val _ = overload_on ("bounded",``bounded_def``); 6806 6807val BOUNDED_EMPTY = store_thm ("BOUNDED_EMPTY", 6808 ``bounded {}``, 6809 REWRITE_TAC[bounded_def, NOT_IN_EMPTY]); 6810 6811val BOUNDED_SUBSET = store_thm ("BOUNDED_SUBSET", 6812 ``!s t. bounded t /\ s SUBSET t ==> bounded s``, 6813 MESON_TAC[bounded_def, SUBSET_DEF]); 6814 6815val BOUNDED_INTERIOR = store_thm ("BOUNDED_INTERIOR", 6816 ``!s:real->bool. bounded s ==> bounded(interior s)``, 6817 MESON_TAC[BOUNDED_SUBSET, INTERIOR_SUBSET]); 6818 6819val BOUNDED_CLOSURE = store_thm ("BOUNDED_CLOSURE", 6820 ``!s:real->bool. bounded s ==> bounded(closure s)``, 6821 REWRITE_TAC[bounded_def, CLOSURE_SEQUENTIAL] THEN 6822 GEN_TAC THEN STRIP_TAC THEN EXISTS_TAC ``a:real`` THEN 6823 GEN_TAC THEN 6824 METIS_TAC[REWRITE_RULE[eventually] LIM_ABS_UBOUND, 6825 TRIVIAL_LIMIT_SEQUENTIALLY, trivial_limit]); 6826 6827val BOUNDED_CLOSURE_EQ = store_thm ("BOUNDED_CLOSURE_EQ", 6828 ``!s:real->bool. bounded(closure s) <=> bounded s``, 6829 GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSURE] THEN 6830 MESON_TAC[BOUNDED_SUBSET, CLOSURE_SUBSET]); 6831 6832val BOUNDED_CBALL = store_thm ("BOUNDED_CBALL", 6833 ``!x:real e. bounded(cball(x,e))``, 6834 REPEAT GEN_TAC THEN REWRITE_TAC[bounded_def] THEN 6835 EXISTS_TAC ``abs(x:real) + e`` THEN REWRITE_TAC[IN_CBALL, dist] THEN 6836 REAL_ARITH_TAC); 6837 6838val BOUNDED_BALL = store_thm ("BOUNDED_BALL", 6839 ``!x e. bounded(ball(x,e))``, 6840 MESON_TAC[BALL_SUBSET_CBALL, BOUNDED_CBALL, BOUNDED_SUBSET]); 6841 6842val FINITE_IMP_BOUNDED = store_thm ("FINITE_IMP_BOUNDED", 6843 ``!s:real->bool. FINITE s ==> bounded s``, 6844 KNOW_TAC ``!s:real->bool. (bounded s) = (\s. bounded s) s`` THENL 6845 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 6846 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN REWRITE_TAC[BOUNDED_EMPTY] THEN 6847 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 6848 REWRITE_TAC[bounded_def, IN_INSERT] THEN GEN_TAC THEN X_GEN_TAC ``x:real`` THEN 6849 REWRITE_TAC [AND_IMP_INTRO] THEN STRIP_TAC THEN 6850 EXISTS_TAC ``abs(x:real) + abs a`` THEN REPEAT STRIP_TAC THEN 6851 ASM_MESON_TAC[ABS_POS, REAL_ARITH 6852 ``(y <= b /\ &0 <= x ==> y <= x + abs b) /\ x <= x + abs b:real``]); 6853 6854val BOUNDED_UNION = store_thm ("BOUNDED_UNION", 6855 ``!s t. bounded (s UNION t) <=> bounded s /\ bounded t``, 6856 REWRITE_TAC[bounded_def, IN_UNION] THEN MESON_TAC[REAL_LE_MAX]); 6857 6858val BOUNDED_BIGUNION = store_thm ("BOUNDED_BIGUNION", 6859 ``!f. FINITE f /\ (!s. s IN f ==> bounded s) ==> bounded(BIGUNION f)``, 6860 REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 6861 KNOW_TAC ``!f. ((!s. s IN f ==> bounded s) ==> bounded(BIGUNION f)) = 6862 (\f. (!s. s IN f ==> bounded s) ==> bounded(BIGUNION f)) f`` THENL 6863 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 6864 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 6865 REWRITE_TAC[BIGUNION_EMPTY, BOUNDED_EMPTY, IN_INSERT, BIGUNION_INSERT] THEN 6866 MESON_TAC[BOUNDED_UNION]); 6867 6868val BOUNDED_POS = store_thm ("BOUNDED_POS", 6869 ``!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> abs(x) <= b``, 6870 REWRITE_TAC[bounded_def] THEN 6871 METIS_TAC[REAL_ARITH ``&0 < &1 + abs(y) /\ (x <= y ==> x:real <= &1 + abs(y))``]); 6872 6873val BOUNDED_POS_LT = store_thm ("BOUNDED_POS_LT", 6874 ``!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> abs(x) < b``, 6875 REWRITE_TAC[bounded_def] THEN 6876 MESON_TAC[REAL_LT_IMP_LE, 6877 REAL_ARITH ``&0 < &1 + abs(y) /\ (x <= y ==> x < &1 + abs(y:real))``]); 6878 6879val BOUNDED_INTER = store_thm ("BOUNDED_INTER", 6880 ``!s t. bounded s \/ bounded t ==> bounded (s INTER t)``, 6881 MESON_TAC[BOUNDED_SUBSET, INTER_SUBSET]); 6882 6883val BOUNDED_DIFF = store_thm ("BOUNDED_DIFF", 6884 ``!s t. bounded s ==> bounded (s DIFF t)``, 6885 METIS_TAC[BOUNDED_SUBSET, DIFF_SUBSET]); 6886 6887val BOUNDED_INSERT = store_thm ("BOUNDED_INSERT", 6888 ``!x s. bounded(x INSERT s) <=> bounded s``, 6889 ONCE_REWRITE_TAC[SET_RULE ``x INSERT s = {x} UNION s``] THEN 6890 SIMP_TAC std_ss [BOUNDED_UNION, FINITE_IMP_BOUNDED, FINITE_EMPTY, FINITE_INSERT]); 6891 6892val BOUNDED_SING = store_thm ("BOUNDED_SING", 6893 ``!a. bounded {a}``, 6894 REWRITE_TAC[BOUNDED_INSERT, BOUNDED_EMPTY]); 6895 6896val BOUNDED_BIGINTER = store_thm ("BOUNDED_BIGINTER", 6897 ``!f:(real->bool)->bool. 6898 (?s:real->bool. s IN f /\ bounded s) ==> bounded(BIGINTER f)``, 6899 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, CONJ_EQ_IMP] THEN REPEAT GEN_TAC THEN 6900 DISCH_TAC THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN 6901 ASM_SET_TAC[]); 6902 6903val NOT_BOUNDED_UNIV = store_thm ("NOT_BOUNDED_UNIV", 6904 ``~(bounded univ(:real))``, 6905 SIMP_TAC std_ss [BOUNDED_POS, NOT_FORALL_THM, NOT_EXISTS_THM, IN_UNIV, 6906 DE_MORGAN_THM, REAL_NOT_LE] THEN 6907 X_GEN_TAC ``B:real`` THEN ASM_CASES_TAC ``&0 < B:real`` THEN ASM_REWRITE_TAC[] THEN 6908 EXISTS_TAC ``(B + &1):real`` THEN REAL_ARITH_TAC); 6909 6910val COBOUNDED_IMP_UNBOUNDED = store_thm ("COBOUNDED_IMP_UNBOUNDED", 6911 ``!s. bounded(univ(:real) DIFF s) ==> ~bounded s``, 6912 GEN_TAC THEN REWRITE_TAC[TAUT `a ==> ~b <=> ~(a /\ b)`] THEN 6913 REWRITE_TAC[GSYM BOUNDED_UNION, SET_RULE ``UNIV DIFF s UNION s = UNIV``] THEN 6914 REWRITE_TAC[NOT_BOUNDED_UNIV]); 6915 6916val BOUNDED_LINEAR_IMAGE = store_thm ("BOUNDED_LINEAR_IMAGE", 6917 ``!f:real->real s. bounded s /\ linear f ==> bounded(IMAGE f s)``, 6918 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN 6919 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC ``B1:real``) MP_TAC) THEN 6920 DISCH_THEN(X_CHOOSE_TAC ``B2:real`` o MATCH_MP LINEAR_BOUNDED_POS) THEN 6921 EXISTS_TAC ``B2 * B1:real`` THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL, FORALL_IN_IMAGE] THEN 6922 X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN 6923 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``B2 * abs(x:real)`` THEN 6924 ASM_SIMP_TAC std_ss [REAL_LE_LMUL]); 6925 6926val BOUNDED_SCALING = store_thm ("BOUNDED_SCALING", 6927 ``!c s. bounded s ==> bounded (IMAGE (\x. c * x) s)``, 6928 REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_LINEAR_IMAGE THEN 6929 ASM_SIMP_TAC std_ss [LINEAR_COMPOSE_CMUL, LINEAR_ID]); 6930 6931val BOUNDED_NEGATIONS = store_thm ("BOUNDED_NEGATIONS", 6932 ``!s. bounded s ==> bounded (IMAGE (\x. -x) s)``, 6933 GEN_TAC THEN 6934 DISCH_THEN(MP_TAC o SPEC ``-&1:real`` o MATCH_MP BOUNDED_SCALING) THEN 6935 REWRITE_TAC[bounded_def, IN_IMAGE, REAL_MUL_LNEG, REAL_MUL_LID]); 6936 6937val BOUNDED_TRANSLATION = store_thm ("BOUNDED_TRANSLATION", 6938 ``!a:real s. bounded s ==> bounded (IMAGE (\x. a + x) s)``, 6939 REPEAT GEN_TAC THEN SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE] THEN 6940 DISCH_THEN(X_CHOOSE_TAC ``B:real``) THEN 6941 EXISTS_TAC ``B + abs(a:real)`` THEN POP_ASSUM MP_TAC THEN 6942 MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN 6943 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x:real`) THEN 6944 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN REAL_ARITH_TAC); 6945 6946val BOUNDED_TRANSLATION_EQ = store_thm ("BOUNDED_TRANSLATION_EQ", 6947 ``!a s. bounded (IMAGE (\x:real. a + x) s) <=> bounded s``, 6948 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_TRANSLATION] THEN 6949 DISCH_THEN(MP_TAC o SPEC ``-a:real`` o MATCH_MP BOUNDED_TRANSLATION) THEN 6950 SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID, 6951 REAL_ARITH ``-a + (a + x:real) = x``]); 6952 6953val BOUNDED_DIFFS = store_thm ("BOUNDED_DIFFS", 6954 ``!s t:real->bool. 6955 bounded s /\ bounded t ==> bounded {x - y | x IN s /\ y IN t}``, 6956 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN 6957 DISCH_THEN(CONJUNCTS_THEN2 6958 (X_CHOOSE_TAC ``B:real``) (X_CHOOSE_TAC ``C:real``)) THEN 6959 EXISTS_TAC ``B + C:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN 6960 CONJ_TAC THENL [MATCH_MP_TAC REAL_LT_ADD THEN ASM_REWRITE_TAC [], REPEAT STRIP_TAC] THEN 6961 ASM_REWRITE_TAC[] THEN KNOW_TAC ``abs p_1 <= B:real /\ abs p_2 <= C:real`` THENL 6962 [ASM_SET_TAC [], ALL_TAC] THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN 6963 EXISTS_TAC ``abs p_1 + abs p_2:real`` THEN REWRITE_TAC [real_sub, ABS_TRIANGLE] THEN 6964 CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN 6965 MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC [ABS_NEG]); 6966 6967val BOUNDED_SUMS = store_thm ("BOUNDED_SUMS", 6968 ``!s t:real->bool. 6969 bounded s /\ bounded t ==> bounded {x + y | x IN s /\ y IN t}``, 6970 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN 6971 DISCH_THEN(CONJUNCTS_THEN2 6972 (X_CHOOSE_TAC ``B:real``) (X_CHOOSE_TAC ``C:real``)) THEN 6973 EXISTS_TAC ``B + C:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN 6974 CONJ_TAC THENL [MATCH_MP_TAC REAL_LT_ADD THEN ASM_REWRITE_TAC [], REPEAT STRIP_TAC] THEN 6975 ASM_REWRITE_TAC[] THEN KNOW_TAC ``abs p_1 <= B:real /\ abs p_2 <= C:real`` THENL 6976 [ASM_SET_TAC [], ALL_TAC] THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN 6977 EXISTS_TAC ``abs p_1 + abs p_2:real`` THEN REWRITE_TAC [ABS_TRIANGLE] THEN 6978 MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC []); 6979 6980val BOUNDED_SUMS_IMAGE = store_thm ("BOUNDED_SUMS_IMAGE", 6981 ``!f g t. bounded {f x | x IN t} /\ bounded {g x | x IN t} 6982 ==> bounded {f x + g x | x IN t}``, 6983 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUMS) THEN 6984 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN 6985 REWRITE_TAC [SUBSET_DEF] THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN 6986 METIS_TAC []); 6987 6988val BOUNDED_SUMS_IMAGES = store_thm ("BOUNDED_SUMS_IMAGES", 6989 ``!f:'a->'b->real t s. FINITE s /\ 6990 (!a. a IN s ==> bounded {f x a | x IN t}) 6991 ==> bounded { sum s (f x) | x IN t}``, 6992 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 6993 KNOW_TAC ``!s. ((!a. a IN s ==> bounded {(f:'a->'b->real) x a | x IN t}) ==> 6994 bounded {sum s (f x) | x IN t}) = 6995 (\s. (!a. a IN s ==> bounded {f x a | x IN t}) ==> 6996 bounded {sum s (f x) | x IN t}) s`` THENL 6997 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 6998 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 6999 SIMP_TAC std_ss [SUM_CLAUSES] THEN CONJ_TAC THENL 7000 [DISCH_THEN(K ALL_TAC) THEN MATCH_MP_TAC BOUNDED_SUBSET THEN 7001 EXISTS_TAC ``{0:real}`` THEN 7002 SIMP_TAC std_ss [FINITE_IMP_BOUNDED, FINITE_EMPTY, FINITE_INSERT] THEN SET_TAC[], 7003 ALL_TAC] THEN REPEAT STRIP_TAC THEN 7004 KNOW_TAC ``bounded {(f:'a->'b->real) x e | x IN t} /\ 7005 bounded {sum s ((f:'a->'b->real) x) | x IN t}`` THENL 7006 [ALL_TAC, METIS_TAC [BOUNDED_SUMS_IMAGE]] THEN ASM_SIMP_TAC std_ss [IN_INSERT]); 7007 7008val BOUNDED_SUBSET_BALL = store_thm ("BOUNDED_SUBSET_BALL", 7009 ``!s x:real. bounded(s) ==> ?r. &0 < r /\ s SUBSET ball(x,r)``, 7010 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN 7011 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 7012 EXISTS_TAC ``&2 * B + abs(x:real)`` THEN 7013 ASM_SIMP_TAC std_ss [ABS_POS, REAL_ARITH 7014 ``&0 < B /\ &0 <= x ==> &0 < &2 * B + x:real``] THEN 7015 REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 7016 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN ASM_REWRITE_TAC[IN_BALL, dist] THEN 7017 UNDISCH_TAC ``&0 < B:real`` THEN REAL_ARITH_TAC); 7018 7019val BOUNDED_SUBSET_CBALL = store_thm ("BOUNDED_SUBSET_CBALL", 7020 ``!s x:real. bounded(s) ==> ?r. &0 < r /\ s SUBSET cball(x,r)``, 7021 MESON_TAC[BOUNDED_SUBSET_BALL, SUBSET_TRANS, BALL_SUBSET_CBALL]); 7022 7023val UNBOUNDED_INTER_COBOUNDED = store_thm ("UNBOUNDED_INTER_COBOUNDED", 7024 ``!s t. ~bounded s /\ bounded(univ(:real) DIFF t) ==> ~(s INTER t = {})``, 7025 REWRITE_TAC[SET_RULE ``(s INTER t = {}) <=> s SUBSET univ(:real) DIFF t``] THEN 7026 MESON_TAC[BOUNDED_SUBSET]); 7027 7028val COBOUNDED_INTER_UNBOUNDED = store_thm ("COBOUNDED_INTER_UNBOUNDED", 7029 ``!s t. bounded(univ(:real) DIFF s) /\ ~bounded t ==> ~(s INTER t = {})``, 7030 REWRITE_TAC[SET_RULE ``(s INTER t = {}) <=> t SUBSET univ(:real) DIFF s``] THEN 7031 MESON_TAC[BOUNDED_SUBSET]); 7032 7033val SUBSPACE_BOUNDED_EQ_TRIVIAL = store_thm ("SUBSPACE_BOUNDED_EQ_TRIVIAL", 7034 ``!s:real->bool. subspace s ==> (bounded s <=> (s = {0}))``, 7035 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [BOUNDED_SING] THEN 7036 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 7037 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE 7038 ``~(s = {a}) ==> a IN s ==> ?b. b IN s /\ ~(b = a)``)) THEN 7039 ASM_SIMP_TAC std_ss [SUBSPACE_0] THEN 7040 DISCH_THEN(X_CHOOSE_THEN ``v:real`` STRIP_ASSUME_TAC) THEN 7041 SIMP_TAC std_ss [bounded_def, NOT_EXISTS_THM] THEN X_GEN_TAC ``B:real`` THEN 7042 EXISTS_TAC ``(B + &1) / abs v * v:real`` THEN 7043 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM ABS_ZERO]) THEN 7044 ASM_SIMP_TAC std_ss [SUBSPACE_MUL, ABS_MUL, ABS_DIV, ABS_ABS] THEN 7045 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, ABS_ZERO] THEN REAL_ARITH_TAC); 7046 7047val BOUNDED_COMPONENTWISE = store_thm ("BOUNDED_COMPONENTWISE", 7048 ``!s:real->bool. 7049 bounded s <=> bounded (IMAGE (\x. x) s)``, 7050 METIS_TAC [IMAGE_ID]); 7051 7052(* ------------------------------------------------------------------------- *) 7053(* Some theorems on sups and infs using the notion "bounded". *) 7054(* ------------------------------------------------------------------------- *) 7055 7056val BOUNDED_HAS_SUP = store_thm ("BOUNDED_HAS_SUP", 7057 ``!s. bounded s /\ ~(s = {}) 7058 ==> (!x. x IN s ==> x <= sup s) /\ 7059 (!b. (!x. x IN s ==> x <= b) ==> sup s <= b)``, 7060 REWRITE_TAC[bounded_def, IMAGE_EQ_EMPTY] THEN 7061 MESON_TAC[SUP, REAL_ARITH ``abs(x) <= a ==> x <= a:real``]); 7062 7063val SUP_INSERT = store_thm ("SUP_INSERT", 7064 ``!x s:real->bool. bounded s 7065 ==> (sup(x INSERT s) = if s = {} then x else (max x (sup s)))``, 7066 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_UNIQUE THEN 7067 COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL 7068 [MESON_TAC[REAL_LE_REFL], ALL_TAC] THEN 7069 REWRITE_TAC[REAL_LE_MAX, REAL_LT_MAX, IN_INSERT] THEN 7070 MP_TAC(ISPEC ``s:real->bool`` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN 7071 REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL, REAL_NOT_LT]); 7072 7073val BOUNDED_HAS_INF = store_thm ("BOUNDED_HAS_INF", 7074 ``!s. bounded s /\ ~(s = {}) 7075 ==> (!x. x IN s ==> inf s <= x) /\ 7076 (!b. (!x. x IN s ==> b <= x) ==> b <= inf s)``, 7077 REWRITE_TAC[bounded_def, IMAGE_EQ_EMPTY] THEN 7078 MESON_TAC[INF, REAL_ARITH ``abs(x) <= a ==> -a <= x:real``]); 7079 7080val INF_INSERT = store_thm ("INF_INSERT", 7081 ``!x s. bounded s 7082 ==> (inf(x INSERT s) = if s = {} then x else (min x (inf s)))``, 7083 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INF_UNIQUE THEN 7084 COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL 7085 [MESON_TAC[REAL_LE_REFL], ALL_TAC] THEN 7086 REWRITE_TAC[REAL_MIN_LE, REAL_MIN_LT, IN_INSERT] THEN 7087 MP_TAC(ISPEC ``s:real->bool`` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN 7088 REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL, REAL_NOT_LT]); 7089 7090(* ------------------------------------------------------------------------- *) 7091(* Subset and overlapping relations on balls. *) 7092(* ------------------------------------------------------------------------- *) 7093 7094val lemma = prove ( 7095 ``(!a':real r r'. 7096 cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0) /\ 7097 (!a':real r r'. 7098 cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0)``, 7099 CONJ_TAC THENL 7100 [KNOW_TAC ``(!a' r r'. 7101 cball (a,r) SUBSET cball (a',r') <=> dist (a,a') + r <= r' \/ r < 0) = 7102 (!r r' a. 7103 cball (a,r) SUBSET cball (0,r') <=> dist (a,0) + r <= r' \/ r < 0)`` THENL 7104 [EQ_TAC THENL 7105 [DISCH_TAC THEN REPEAT GEN_TAC THEN 7106 FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist, 7107 REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN 7108 POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN 7109 FULL_SIMP_TAC std_ss [REAL_ARITH ``a - (a - b) = b:real``] THEN 7110 POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN 7111 POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN 7112 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 7113 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL 7114 [DISCH_TAC THEN GEN_TAC THEN 7115 POP_ASSUM (MP_TAC o Q.SPEC `-(a - a' - x:real)`) THEN 7116 REWRITE_TAC [ABS_NEG] THEN REAL_ARITH_TAC, ALL_TAC] THEN 7117 DISCH_TAC THEN GEN_TAC THEN 7118 POP_ASSUM (MP_TAC o Q.SPEC `-(-a + a' - x:real)`) THEN 7119 REAL_ARITH_TAC, ALL_TAC] THEN 7120 DISCH_TAC THEN REPEAT GEN_TAC THEN 7121 FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist, 7122 REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN 7123 POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN 7124 POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN 7125 POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN 7126 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 7127 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL 7128 [DISCH_TAC THEN GEN_TAC THEN 7129 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7130 REAL_ARITH_TAC, ALL_TAC] THEN 7131 DISCH_TAC THEN GEN_TAC THEN 7132 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7133 REAL_ARITH_TAC, 7134 DISCH_TAC THEN ASM_REWRITE_TAC[] THEN POP_ASSUM K_TAC], 7135 KNOW_TAC ``(!a' r r'. 7136 cball (a,r) SUBSET ball (a',r') <=> dist (a,a') + r < r' \/ r < 0) = 7137 (!r r' a. 7138 cball (a,r) SUBSET ball (0,r') <=> dist (a,0) + r < r' \/ r < 0)`` THENL 7139 [EQ_TAC THENL 7140 [DISCH_TAC THEN REPEAT GEN_TAC THEN 7141 FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist, 7142 REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN 7143 POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN 7144 FULL_SIMP_TAC std_ss [REAL_ARITH ``a - (a - b) = b:real``] THEN 7145 POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN 7146 POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN 7147 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 7148 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL 7149 [DISCH_TAC THEN GEN_TAC THEN 7150 POP_ASSUM (MP_TAC o Q.SPEC `-(a - a' - x:real)`) THEN 7151 REWRITE_TAC [ABS_NEG] THEN REAL_ARITH_TAC, ALL_TAC] THEN 7152 DISCH_TAC THEN GEN_TAC THEN 7153 POP_ASSUM (MP_TAC o Q.SPEC `-(-a + a' - x:real)`) THEN 7154 REAL_ARITH_TAC, ALL_TAC] THEN 7155 DISCH_TAC THEN REPEAT GEN_TAC THEN 7156 FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist, 7157 REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN 7158 POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN 7159 POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN 7160 POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN 7161 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 7162 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL 7163 [DISCH_TAC THEN GEN_TAC THEN 7164 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7165 REAL_ARITH_TAC, ALL_TAC] THEN 7166 DISCH_TAC THEN GEN_TAC THEN 7167 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7168 REAL_ARITH_TAC, 7169 DISCH_TAC THEN ASM_REWRITE_TAC[] THEN POP_ASSUM K_TAC]] THEN 7170 (REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET_DEF, IN_CBALL, IN_BALL] THEN 7171 EQ_TAC THENL 7172 [REWRITE_TAC[DIST_0], 7173 REWRITE_TAC [dist] THEN REAL_ARITH_TAC] THEN 7174 DISJ_CASES_TAC(REAL_ARITH ``r < &0 \/ &0 <= r:real``) THEN 7175 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN DISJ1_TAC THEN 7176 ASM_CASES_TAC ``a:real = 0`` THENL 7177 [FIRST_X_ASSUM(MP_TAC o SPEC ``r:real``) THEN 7178 ASM_SIMP_TAC std_ss [DIST_0, ABS_MUL, LESS_EQ_REFL] THEN 7179 ASM_REAL_ARITH_TAC, 7180 FIRST_X_ASSUM(MP_TAC o SPEC ``(&1 + r / abs(a)) * a:real``) THEN 7181 SIMP_TAC std_ss [dist, REAL_ARITH ``a - (&1 + x) * a:real = -(x * a)``] THEN 7182 ASM_SIMP_TAC std_ss [ABS_MUL, ABS_DIV, ABS_ABS, ABS_NEG, REAL_POS, 7183 REAL_LE_DIV, ABS_POS, REAL_ADD_RDISTRIB, REAL_DIV_RMUL, 7184 ABS_ZERO, REAL_ARITH ``&0 <= x ==> (abs(&1 + x) = &1 + x:real)``] THEN 7185 ASM_REAL_ARITH_TAC])); 7186 7187val tac = DISCH_THEN(MP_TAC o MATCH_MP SUBSET_CLOSURE) THEN 7188 ASM_SIMP_TAC std_ss [CLOSED_CBALL, CLOSURE_CLOSED, CLOSURE_BALL]; 7189 7190val SUBSET_BALLS = store_thm ("SUBSET_BALLS", 7191 ``(!a a':real r r'. 7192 ball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\ 7193 (!a a':real r r'. 7194 ball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\ 7195 (!a a':real r r'. 7196 cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0) /\ 7197 (!a a':real r r'. 7198 cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0)``, 7199 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN 7200 KNOW_TAC ``(!a a':real r r'. 7201 (ball (a,r) SUBSET ball (a',r') <=> 7202 dist (a,a') + r <= r' \/ r <= 0) /\ 7203 (ball (a,r) SUBSET cball (a',r') <=> 7204 dist (a,a') + r <= r' \/ r <= 0) /\ 7205 (cball (a,r) SUBSET ball (a',r') <=> 7206 dist (a,a') + r < r' \/ r < 0) /\ 7207 (cball (a,r) SUBSET cball (a',r') <=> 7208 dist (a,a') + r <= r' \/ r < 0)) = 7209 (!a:real r r'. 7210 (ball (a,r) SUBSET ball (0,r') <=> 7211 dist (a,0) + r <= r' \/ r <= 0) /\ 7212 (ball (a,r) SUBSET cball (0,r') <=> 7213 dist (a,0) + r <= r' \/ r <= 0) /\ 7214 (cball (a,r) SUBSET ball (0,r') <=> 7215 dist (a,0) + r < r' \/ r < 0) /\ 7216 (cball (a,r) SUBSET cball (0,r') <=> 7217 dist (a,0) + r <= r' \/ r < 0))`` THENL 7218 [EQ_TAC THENL 7219 [DISCH_TAC THEN REPEAT GEN_TAC THEN METIS_TAC [], ALL_TAC] THEN 7220 DISCH_TAC THEN REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [DIST_0] THEN 7221 FULL_SIMP_TAC std_ss [cball, ball, dist, SUBSET_DEF, GSPECIFICATION] THEN 7222 FULL_SIMP_TAC std_ss [REAL_SUB_LZERO, ABS_NEG] THEN 7223 POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN 7224 POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN 7225 POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN 7226 GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN 7227 REPEAT STRIP_TAC THENL 7228 [UNDISCH_TAC ``abs (a - a') + r <= r' \/ r <= 0 <=> 7229 !x:real. abs (a - a' - x) < r ==> abs x < r'`` THEN 7230 REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN 7231 ASM_REWRITE_TAC [] THEN EQ_TAC THENL 7232 [DISCH_TAC THEN GEN_TAC THEN 7233 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7234 REAL_ARITH_TAC, 7235 DISCH_TAC THEN GEN_TAC THEN 7236 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7237 REAL_ARITH_TAC], 7238 UNDISCH_TAC ``abs (a - a') + r <= r' \/ r <= 0 <=> 7239 !x:real. abs (a - a' - x) < r ==> abs x <= r'`` THEN 7240 REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN 7241 ASM_REWRITE_TAC [] THEN EQ_TAC THENL 7242 [DISCH_TAC THEN GEN_TAC THEN 7243 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7244 REAL_ARITH_TAC, 7245 DISCH_TAC THEN GEN_TAC THEN 7246 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7247 REAL_ARITH_TAC], 7248 UNDISCH_TAC ``abs (a - a') + r < r' \/ r < 0 <=> 7249 !x:real. abs (a - a' - x) <= r ==> abs x < r'`` THEN 7250 REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN 7251 ASM_REWRITE_TAC [] THEN EQ_TAC THENL 7252 [DISCH_TAC THEN GEN_TAC THEN 7253 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7254 REAL_ARITH_TAC, 7255 DISCH_TAC THEN GEN_TAC THEN 7256 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7257 REAL_ARITH_TAC], 7258 UNDISCH_TAC ``abs (a - a') + r <= r' \/ r < 0 <=> 7259 !x:real. abs (a - a' - x) <= r ==> abs x <= r'`` THEN 7260 REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN 7261 ASM_REWRITE_TAC [] THEN EQ_TAC THENL 7262 [DISCH_TAC THEN GEN_TAC THEN 7263 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7264 REAL_ARITH_TAC, 7265 DISCH_TAC THEN GEN_TAC THEN 7266 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7267 REAL_ARITH_TAC]], 7268 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 7269 REPEAT STRIP_TAC THEN 7270 (EQ_TAC THENL 7271 [ALL_TAC, REWRITE_TAC[SUBSET_DEF, IN_BALL, IN_CBALL, dist] THEN REAL_ARITH_TAC]) THEN 7272 MATCH_MP_TAC(SET_RULE 7273 ``((s = {}) <=> q) /\ (s SUBSET t /\ ~(s = {}) /\ ~(t = {}) ==> p) 7274 ==> s SUBSET t ==> p \/ q``) THEN 7275 SIMP_TAC std_ss [BALL_EQ_EMPTY, CBALL_EQ_EMPTY, REAL_NOT_LE, REAL_NOT_LT] THEN 7276 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THENL 7277 [tac, tac, ALL_TAC, ALL_TAC] THEN REWRITE_TAC[lemma] THEN 7278 REPEAT(POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC); 7279 7280(* NOTE: this proof needs 10s to finish *) 7281Theorem INTER_BALLS_EQ_EMPTY : 7282 (!a b:real r s. (ball(a,r) INTER ball(b,s) = {}) <=> 7283 r <= &0 \/ s <= &0 \/ r + s <= dist(a,b)) /\ 7284 (!a b:real r s. (ball(a,r) INTER cball(b,s) = {}) <=> 7285 r <= &0 \/ s < &0 \/ r + s <= dist(a,b)) /\ 7286 (!a b:real r s. (cball(a,r) INTER ball(b,s) = {}) <=> 7287 r < &0 \/ s <= &0 \/ r + s <= dist(a,b)) /\ 7288 (!a b:real r s. (cball(a,r) INTER cball(b,s) = {}) <=> 7289 r < &0 \/ s < &0 \/ r + s < dist(a,b)) 7290Proof 7291 rpt STRIP_TAC >| (* 4 subgoals *) 7292 [(* goal 1 (of 4) *) 7293 Suff `!b:real. 0 <= b ==> 7294 !r s:real. ((ball (0,r) INTER ball (b,s) = {}) <=> 7295 r <= 0 \/ s <= 0 \/ r + s <= dist (0,b))` >- 7296 (SIMP_TAC std_ss [ball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``, 7297 EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN 7298 DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN 7299 REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN 7300 POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN 7301 GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 7302 POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN 7303 REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 7304 POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN 7305 EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN 7306 POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC, 7307 DISCH_TAC THEN GEN_TAC THEN 7308 POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC]), 7309 (* goal 2 (of 4) *) 7310 Suff `!b:real. 0 <= b ==> 7311 !r s:real. ((ball (0,r) INTER cball (b,s) = {}) <=> 7312 r <= 0 \/ s < 0 \/ r + s <= dist (0,b))` >- 7313 (SIMP_TAC std_ss [ball, cball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``, 7314 EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN 7315 DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN 7316 REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN 7317 POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN 7318 GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 7319 POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN 7320 REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 7321 POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN 7322 EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN 7323 POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC, 7324 DISCH_TAC THEN GEN_TAC THEN 7325 POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC]), 7326 (* goal 3 (of 4) *) 7327 Suff `!b:real. 0 <= b ==> 7328 !r s:real. ((cball (0,r) INTER ball (b,s) = {}) <=> 7329 r < 0 \/ s <= 0 \/ r + s <= dist (0,b))` >- 7330 (SIMP_TAC std_ss [ball, cball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``, 7331 EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN 7332 DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN 7333 REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN 7334 POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN 7335 GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 7336 POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN 7337 REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 7338 POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN 7339 EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN 7340 POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC, 7341 DISCH_TAC THEN GEN_TAC THEN 7342 POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC]), 7343 (* goal 4 (of 4) *) 7344 Suff `!b:real. 0 <= b ==> 7345 !r s:real. ((cball (0,r) INTER cball (b,s) = {}) <=> 7346 r < 0 \/ s < 0 \/ r + s < dist (0,b))` >- 7347 (SIMP_TAC std_ss [ball, cball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``, 7348 EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN 7349 DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN 7350 REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN 7351 POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN 7352 GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 7353 POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN 7354 REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 7355 POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN 7356 EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN 7357 POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC, 7358 DISCH_TAC THEN GEN_TAC THEN 7359 POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC])] THEN 7360 (* still 4 subgoals *) 7361 rpt STRIP_TAC THEN 7362 REWRITE_TAC[EXTENSION, NOT_IN_EMPTY, IN_INTER, IN_CBALL, IN_BALL] THEN 7363 (reverse EQ_TAC 7364 >- (Q.SPEC_TAC (`b`, `v`) THEN REWRITE_TAC [dist] THEN REAL_ARITH_TAC)) THEN 7365 DISCH_THEN(MP_TAC o GEN ``c:real`` o SPEC ``c:real``) THEN 7366 SIMP_TAC std_ss [ABS_MUL, LESS_EQ_REFL, dist, ABS_NEG, 7367 REAL_SUB_LZERO, GSYM REAL_SUB_RDISTRIB, REAL_MUL_RID] THEN 7368 ASM_REWRITE_TAC[abs] THEN REWRITE_TAC[GSYM abs] THEN 7369 DISCH_THEN(fn th => 7370 MP_TAC(SPEC ``min b r:real`` th) THEN 7371 MP_TAC(SPEC ``max (&0) (b - s:real)`` th) THEN 7372 MP_TAC(SPEC ``(r + (b - s)) / &2:real`` th)) THEN 7373 REWRITE_TAC [real_div] THEN 7374 ONCE_REWRITE_TAC [REAL_ARITH ``a - b * c = a * 1 - b * c:real``] THEN 7375 REWRITE_TAC [METIS [REAL_DIV_REFL, REAL_ARITH ``2 <> 0:real``, real_div] 7376 ``1 = 2 * inv 2:real``, REAL_ARITH ``a * (b * c) = (a * b) * c:real``] THEN 7377 REWRITE_TAC [GSYM REAL_SUB_RDISTRIB] THEN 7378 SIMP_TAC std_ss [real_div, ABS_MUL, REAL_ARITH ``2 <> 0:real``, ABS_INV, ABS_N] THEN 7379 SIMP_TAC std_ss [GSYM real_div] THEN 7380 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_LE_RDIV_EQ, 7381 REAL_LT_LDIV_EQ, REAL_LE_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 7382 RW_TAC real_ss [abs, max_def, min_def] THEN (* 1024 subgoals (for each goals) *) 7383 ASM_REAL_ARITH_TAC 7384QED 7385 7386(* ------------------------------------------------------------------------- *) 7387(* Every closed set is a G_Delta. *) 7388(* ------------------------------------------------------------------------- *) 7389 7390val CLOSED_AS_GDELTA = store_thm ("CLOSED_AS_GDELTA", 7391 ``!s:real->bool. closed s ==> ?g. COUNTABLE g /\ 7392 (!u. u IN g ==> open u) /\ (BIGINTER g = s)``, 7393 REPEAT STRIP_TAC THEN EXISTS_TAC 7394 ``{ BIGUNION { ball(x:real,inv(&n + &1)) | x IN s} | n IN univ(:num)}`` THEN 7395 SIMP_TAC std_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, NUM_COUNTABLE] THEN 7396 SIMP_TAC std_ss [FORALL_IN_IMAGE, OPEN_BIGUNION, OPEN_BALL] THEN 7397 MATCH_MP_TAC(SET_RULE 7398 ``(closure s = s) /\ s SUBSET t /\ t SUBSET closure s ==> (t = s)``) THEN 7399 ASM_REWRITE_TAC[CLOSURE_EQ] THEN CONJ_TAC THENL 7400 [SIMP_TAC std_ss [SUBSET_BIGINTER, FORALL_IN_IMAGE, IN_UNIV] THEN 7401 X_GEN_TAC ``n:num`` THEN SIMP_TAC std_ss [BIGUNION_IMAGE, SUBSET_DEF, GSPECIFICATION] THEN 7402 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN EXISTS_TAC ``x:real`` THEN 7403 ASM_REWRITE_TAC[CENTRE_IN_BALL, REAL_LT_INV_EQ] THEN 7404 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``1:real`` THEN CONJ_TAC THENL 7405 [REAL_ARITH_TAC, ALL_TAC] THEN REWRITE_TAC [REAL_LE_ADDL, REAL_POS], 7406 SIMP_TAC std_ss [SUBSET_DEF, CLOSURE_APPROACHABLE, BIGINTER_IMAGE, IN_UNIV] THEN 7407 X_GEN_TAC ``x:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, BIGUNION_IMAGE] THEN 7408 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 7409 POP_ASSUM MP_TAC THEN GEN_REWR_TAC LAND_CONV [REAL_ARCH_INV] THEN 7410 DISCH_THEN(X_CHOOSE_THEN ``n:num`` STRIP_ASSUME_TAC) THEN 7411 FIRST_X_ASSUM(MP_TAC o SPEC ``n:num``) THEN REWRITE_TAC[IN_BALL] THEN 7412 DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN 7413 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN 7414 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LT_TRANS) THEN 7415 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] REAL_LT_TRANS)) THEN 7416 MATCH_MP_TAC REAL_LT_INV2 THEN 7417 REWRITE_TAC[REAL_OF_NUM_ADD, REAL_LT] THEN CONJ_TAC THENL 7418 [FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ, GSYM REAL_LT], 7419 FULL_SIMP_TAC arith_ss [REAL_LT_ADDR]]]); 7420 7421(* ------------------------------------------------------------------------- *) 7422(* Compactness (the definition is the one based on convegent subsequences). *) 7423(* ------------------------------------------------------------------------- *) 7424 7425val compact = new_definition ("compact", 7426 ``compact s <=> !f:num->real. (!n. f(n) IN s) 7427 ==> ?l r. l IN s /\ (!m n:num. m < n ==> r(m) < r(n)) /\ 7428 ((f o r) --> l) sequentially``); 7429 7430val MONOTONE_BIGGER = store_thm ("MONOTONE_BIGGER", 7431 ``!r. (!m n. m < n ==> r(m) < r(n)) ==> !n:num. n <= r(n)``, 7432 GEN_TAC THEN DISCH_TAC THEN INDUCT_TAC THEN 7433 METIS_TAC[ZERO_LESS_EQ, ARITH_PROVE ``n <= m /\ m < p ==> SUC n <= p``, LT]); 7434 7435val LIM_SUBSEQUENCE = store_thm ("LIM_SUBSEQUENCE", 7436 ``!s r l. (!m n. m < n ==> r(m) < r(n)) /\ (s --> l) sequentially 7437 ==> (s o r --> l) sequentially``, 7438 SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN 7439 MESON_TAC[MONOTONE_BIGGER, LESS_EQ_TRANS]); 7440 7441val MONOTONE_SUBSEQUENCE = store_thm ("MONOTONE_SUBSEQUENCE", 7442 ``!s:num->real. ?r:num->num. 7443 (!m n. m < n ==> r(m) < r(n)) /\ 7444 ((!m n. m <= n ==> s(r(m)) <= s(r(n))) \/ 7445 (!m n. m <= n ==> s(r(n)) <= s(r(m))))``, 7446 GEN_TAC THEN 7447 ASM_CASES_TAC ``!n:num. ?p. n < p /\ !m. p <= m ==> s(m):real <= s(p)`` THEN 7448 POP_ASSUM MP_TAC THEN 7449 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_EXISTS_THM, NOT_IMP, DE_MORGAN_THM] THEN 7450 SIMP_TAC std_ss [RIGHT_OR_EXISTS_THM, SKOLEM_THM, REAL_NOT_LE, REAL_NOT_LT] THENL 7451 [ABBREV_TAC ``N = 0:num``, DISCH_THEN(X_CHOOSE_THEN ``N:num`` MP_TAC)] THEN 7452 DISCH_THEN(X_CHOOSE_THEN ``next:num->num`` STRIP_ASSUME_TAC) THEN 7453 (KNOW_TAC ``(?r. (r 0 = (next:num->num) (SUC N)) /\ 7454 (!n. r (SUC n) = (next:num->num) (r n)))`` THENL 7455 [RW_TAC std_ss [num_Axiom], ALL_TAC]) THEN 7456 STRIP_TAC THEN EXISTS_TAC ``r:num->num`` THENL 7457 [SUBGOAL_THEN ``!m:num n:num. r n <= m ==> s(m) <= s(r n):real`` 7458 ASSUME_TAC THEN TRY CONJ_TAC THEN TRY DISJ2_TAC THEN 7459 GEN_TAC THEN INDUCT_TAC THEN ASM_SIMP_TAC std_ss [LT, LE] THEN 7460 ASM_MESON_TAC[REAL_LE_TRANS, REAL_LE_REFL, LESS_IMP_LESS_OR_EQ, LESS_TRANS], 7461 SUBGOAL_THEN ``!n. N < (r:num->num) n`` ASSUME_TAC THEN 7462 TRY(CONJ_TAC THENL [GEN_TAC, DISJ1_TAC THEN GEN_TAC]) THEN 7463 INDUCT_TAC THEN ASM_SIMP_TAC std_ss [LT, LE] THEN 7464 TRY STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 7465 ASM_MESON_TAC[REAL_LT_REFL, LT_LE, LESS_LESS_EQ_TRANS, REAL_LE_REFL, 7466 REAL_LT_LE, REAL_LE_TRANS, LT]]); 7467 7468val CONVERGENT_BOUNDED_INCREASING = store_thm ("CONVERGENT_BOUNDED_INCREASING", 7469 ``!s:num->real b. (!m n. m <= n ==> s m <= s n) /\ (!n. abs(s n) <= b) 7470 ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e``, 7471 REPEAT STRIP_TAC THEN 7472 MP_TAC(SPEC ``\x. ?n. (s:num->real) n = x`` REAL_COMPLETE) THEN BETA_TAC THEN 7473 KNOW_TAC ``(?x:real n:num. s n = x) /\ (?M. !x. (?n. s n = x) ==> x <= M)`` THENL 7474 [ASM_MESON_TAC[REAL_ARITH ``abs(x:real) <= b ==> x <= b``], 7475 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 7476 DISCH_THEN (X_CHOOSE_TAC ``l:real``) THEN EXISTS_TAC ``l:real`` THEN 7477 POP_ASSUM MP_TAC THEN STRIP_TAC THEN 7478 X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN 7479 FIRST_X_ASSUM(MP_TAC o SPEC ``l - e:real``) THEN 7480 METIS_TAC[REAL_ARITH ``&0:real < e ==> ~(l <= l - e)``, 7481 REAL_ARITH ``x <= y /\ y <= l /\ ~(x <= l - e) ==> abs(y - l) < e:real``]); 7482 7483val CONVERGENT_BOUNDED_MONOTONE = store_thm ("CONVERGENT_BOUNDED_MONOTONE", 7484 ``!s:num->real b. (!n. abs(s n) <= b) /\ 7485 ((!m n. m <= n ==> s m <= s n) \/ 7486 (!m n. m <= n ==> s n <= s m)) 7487 ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e``, 7488 REPEAT STRIP_TAC THENL 7489 [ASM_MESON_TAC[CONVERGENT_BOUNDED_INCREASING], ALL_TAC] THEN 7490 MP_TAC(SPEC ``\n. -((s:num->real) n)`` CONVERGENT_BOUNDED_INCREASING) THEN 7491 ASM_SIMP_TAC std_ss [REAL_LE_NEG2, ABS_NEG] THEN 7492 ASM_MESON_TAC[REAL_ARITH ``abs(x - -l) = abs(-x - l:real)``]); 7493 7494val COMPACT_REAL_LEMMA = store_thm ("COMPACT_REAL_LEMMA", 7495 ``!s b. (!n:num. abs(s n) <= b) 7496 ==> ?l r. (!m n:num. m < n ==> r(m) < r(n)) /\ 7497 !e. &0:real < e ==> ?N. !n. N <= n ==> abs(s(r n) - l) < e``, 7498 REPEAT GEN_TAC THEN DISCH_TAC THEN 7499 KNOW_TAC ``?(r :num -> num) (l :real). 7500 (!(m :num) (n :num). m < n ==> r m < r n) /\ 7501 !(e :real). 7502 (0 :real) < e ==> 7503 ?(N :num). 7504 !(n :num). N <= n ==> abs ((s :num -> real) (r n) - l) < e`` THENL 7505 [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN 7506 MP_TAC(SPEC ``s:num->real`` MONOTONE_SUBSEQUENCE) THEN 7507 DISCH_THEN (X_CHOOSE_TAC ``r:num->num``) THEN EXISTS_TAC ``r:num->num`` THEN 7508 ASM_SIMP_TAC std_ss [] THEN POP_ASSUM MP_TAC THEN STRIP_TAC THENL 7509 [MP_TAC(SPEC ``\n. ((s:num->real) ((r:num->num) n))`` CONVERGENT_BOUNDED_INCREASING), 7510 MP_TAC(SPEC ``\n. -((s:num->real) ((r:num->num) n))`` CONVERGENT_BOUNDED_INCREASING)] THEN 7511 ASM_SIMP_TAC std_ss [REAL_LE_NEG2, ABS_NEG] THEN 7512 ASM_MESON_TAC[REAL_ARITH ``abs(x - -l) = abs(-x - l:real)``]); 7513 7514val COMPACT_LEMMA = store_thm ("COMPACT_LEMMA", 7515``!s. bounded s /\ (!n. (x:num->real) n IN s) 7516 ==> ?l:real r. (!m n. m < n ==> r m < (r:num->num) n) /\ 7517 !e. &0 < e ==> ?N. !n i. N <= n ==> abs(x(r n) - l) < e``, 7518 METIS_TAC [COMPACT_REAL_LEMMA, bounded_def]); 7519 7520val BOUNDED_CLOSED_IMP_COMPACT = store_thm ("BOUNDED_CLOSED_IMP_COMPACT", 7521 ``!s:real->bool. bounded s /\ closed s ==> compact s``, 7522 REPEAT STRIP_TAC THEN REWRITE_TAC[compact] THEN 7523 X_GEN_TAC ``x:num->real`` THEN DISCH_TAC THEN 7524 MP_TAC(ISPEC ``s:real->bool`` COMPACT_LEMMA) THEN 7525 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN 7526 MAP_EVERY EXISTS_TAC [``l:real``, ``r:num->num``] THEN 7527 ASM_SIMP_TAC std_ss [] THEN 7528 MATCH_MP_TAC(TAUT `(b ==> a) /\ b ==> a /\ b`) THEN 7529 REPEAT STRIP_TAC THENL 7530 [FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CLOSED_SEQUENTIAL_LIMITS]) THEN 7531 EXISTS_TAC ``(x:num->real) o (r:num->num)`` THEN 7532 ASM_SIMP_TAC std_ss [o_THM], ALL_TAC] THEN 7533 REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 7534 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 7535 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT, REAL_HALF, 7536 ARITH_PROVE ``0:num < n <=> ~(n = 0)``] THEN 7537 STRIP_TAC THEN EXISTS_TAC ``N:num`` THEN 7538 POP_ASSUM MP_TAC THEN 7539 REWRITE_TAC[dist] THEN REPEAT STRIP_TAC THEN 7540 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN 7541 GEN_REWR_TAC LAND_CONV [GSYM REAL_ADD_RID] THEN MATCH_MP_TAC REAL_LT_ADD2 THEN 7542 UNDISCH_TAC `` !n:num. N <= n ==> abs (x ((r:num->num) n) - l) < e / 2:real`` THEN 7543 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `n:num`) THEN 7544 ASM_REWRITE_TAC [] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 7545 METIS_TAC [REAL_LT_HALF1]); 7546 7547(* ------------------------------------------------------------------------- *) 7548(* Completeness. *) 7549(* ------------------------------------------------------------------------- *) 7550 7551val cauchy = new_definition ("cauchy", 7552 ``cauchy (s:num->real) <=> 7553 !e. &0 < e ==> ?N. !m n. m >= N /\ n >= N ==> dist(s m,s n) < e``); 7554 7555val complete = new_definition ("complete", 7556 ``complete s <=> 7557 !f:num->real. (!n. f n IN s) /\ cauchy f 7558 ==> ?l. l IN s /\ (f --> l) sequentially``); 7559 7560val CAUCHY = store_thm ("CAUCHY", 7561 ``!s:num->real. 7562 cauchy s <=> !e. &0 < e ==> ?N. !n. n >= N ==> dist(s n,s N) < e``, 7563 REPEAT GEN_TAC THEN REWRITE_TAC[cauchy, GREATER_EQ] THEN EQ_TAC THENL 7564 [MESON_TAC[LESS_EQ_REFL], DISCH_TAC] THEN 7565 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 7566 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN 7567 MESON_TAC[DIST_TRIANGLE_HALF_L]); 7568 7569val CONVERGENT_IMP_CAUCHY = store_thm ("CONVERGENT_IMP_CAUCHY", 7570 ``!s l. (s --> l) sequentially ==> cauchy s``, 7571 REWRITE_TAC[LIM_SEQUENTIALLY, cauchy] THEN 7572 REPEAT GEN_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 7573 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 7574 ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT] THEN 7575 ASM_MESON_TAC[GREATER_EQ, LESS_EQ_REFL, DIST_TRIANGLE_HALF_L]); 7576 7577val GREATER_EQ_REFL = store_thm ("GREATER_EQ_REFL", 7578 ``!m:num. m >= m``, 7579 REWRITE_TAC [GREATER_EQ, LESS_EQ_REFL]); 7580 7581val UPPER_BOUND_FINITE_SET_REAL = store_thm ("UPPER_BOUND_FINITE_SET_REAL", 7582 ``!f:('a->real) s. FINITE(s) ==> ?a. !x. x IN s ==> f(x) <= a``, 7583 REPEAT GEN_TAC THEN 7584 KNOW_TAC `` (?a. !x. x IN s ==> (f:'a->real) x <= a) = 7585 (\s. ?a. !x. x IN s ==> (f:'a->real) x <= a) s`` THENL 7586 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 7587 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 7588 REWRITE_TAC[IN_INSERT, NOT_IN_EMPTY] THEN 7589 MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]); 7590 7591val CAUCHY_IMP_BOUNDED = store_thm ("CAUCHY_IMP_BOUNDED", 7592 ``!s:num->real. cauchy s ==> bounded {y | ?n. y = s n}``, 7593 REWRITE_TAC[cauchy, bounded_def, GSPECIFICATION] THEN GEN_TAC THEN 7594 DISCH_THEN(MP_TAC o SPEC ``&1:real``) THEN REWRITE_TAC[REAL_LT_01] THEN 7595 DISCH_THEN(X_CHOOSE_THEN ``N:num`` (MP_TAC o SPEC ``N:num``)) THEN 7596 REWRITE_TAC[GREATER_EQ_REFL] THEN DISCH_TAC THEN 7597 SUBGOAL_THEN ``!n:num. N <= n ==> abs(s n :real) <= abs(s N) + &1:real`` 7598 ASSUME_TAC THENL 7599 [ASM_MESON_TAC[GREATER_EQ, dist, DIST_SYM, ABS_TRIANGLE_SUB, 7600 REAL_ARITH ``a <= b + c /\ c < &1 ==> a <= b + &1:real``], 7601 MP_TAC(ISPECL [``\n:num. abs(s n :real)``, ``0..N``] 7602 UPPER_BOUND_FINITE_SET_REAL) THEN 7603 SIMP_TAC std_ss [FINITE_NUMSEG, IN_NUMSEG, LESS_EQ_0, GSYM LEFT_EXISTS_IMP_THM] THEN 7604 ASM_MESON_TAC[LESS_EQ_CASES, 7605 REAL_ARITH ``x <= a \/ x <= b ==> x <= abs a + abs b:real``]]); 7606 7607val COMPACT_IMP_COMPLETE = store_thm ("COMPACT_IMP_COMPLETE", 7608 ``!s:real->bool. compact s ==> complete s``, 7609 GEN_TAC THEN REWRITE_TAC[complete, compact] THEN 7610 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `f:num->real`) THEN 7611 DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN 7612 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC ``l:real`` THEN 7613 FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] LIM_ADD)) THEN 7614 DISCH_THEN(MP_TAC o SPEC ``\n. (f:num->real)(n) - f(r n)``) THEN 7615 DISCH_THEN(MP_TAC o SPEC ``0:real``) THEN ASM_SIMP_TAC std_ss [o_THM] THEN 7616 SIMP_TAC std_ss [REAL_ADD_RID, REAL_SUB_ADD2, ETA_AX] THEN 7617 DISCH_THEN MATCH_MP_TAC THEN 7618 UNDISCH_TAC ``cauchy f`` THEN GEN_REWR_TAC LAND_CONV [cauchy] THEN 7619 SIMP_TAC std_ss [GE, LIM, SEQUENTIALLY, dist, REAL_SUB_RZERO] THEN 7620 SUBGOAL_THEN ``!n:num. n <= r(n)`` MP_TAC THENL [INDUCT_TAC, ALL_TAC] THEN 7621 ASM_MESON_TAC[LESS_EQ_TRANS, LESS_EQ_REFL, LT, LESS_EQ_LESS_TRANS, ZERO_LESS_EQ, LE_SUC_LT]); 7622 7623val COMPLETE_UNIV = store_thm ("COMPLETE_UNIV", 7624 ``complete univ(:real)``, 7625 REWRITE_TAC[complete, IN_UNIV] THEN X_GEN_TAC ``x:num->real`` THEN 7626 DISCH_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN 7627 DISCH_THEN(ASSUME_TAC o MATCH_MP BOUNDED_CLOSURE) THEN 7628 MP_TAC(ISPEC ``closure {y:real | ?n:num. y = x n}`` 7629 COMPACT_IMP_COMPLETE) THEN 7630 ASM_SIMP_TAC std_ss [BOUNDED_CLOSED_IMP_COMPACT, CLOSED_CLOSURE, complete] THEN 7631 DISCH_THEN(MP_TAC o SPEC ``x:num->real``) THEN 7632 KNOW_TAC ``(!n. x n IN closure {y | ?n. y = x n}) /\ cauchy x`` THENL 7633 [ALL_TAC, MESON_TAC[]] THEN 7634 ASM_SIMP_TAC std_ss [closure, GSPECIFICATION, IN_UNION] THEN MESON_TAC[]); 7635 7636val COMPLETE_EQ_CLOSED = store_thm ("COMPLETE_EQ_CLOSED", 7637 ``!s:real->bool. complete s <=> closed s``, 7638 GEN_TAC THEN EQ_TAC THENL 7639 [REWRITE_TAC[complete, CLOSED_LIMPT, LIMPT_SEQUENTIAL] THEN 7640 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN GEN_TAC THEN 7641 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN DISCH_TAC THEN 7642 GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `f:num->real`) THEN 7643 MESON_TAC[CONVERGENT_IMP_CAUCHY, IN_DELETE, LIM_UNIQUE, 7644 TRIVIAL_LIMIT_SEQUENTIALLY], 7645 REWRITE_TAC[complete, CLOSED_SEQUENTIAL_LIMITS] THEN DISCH_TAC THEN 7646 X_GEN_TAC ``f:num->real`` THEN STRIP_TAC THEN 7647 MP_TAC(REWRITE_RULE[complete] COMPLETE_UNIV) THEN 7648 DISCH_THEN(MP_TAC o SPEC ``f:num->real``) THEN 7649 ASM_REWRITE_TAC[IN_UNIV] THEN ASM_MESON_TAC[]]); 7650 7651val CONVERGENT_EQ_CAUCHY = store_thm ("CONVERGENT_EQ_CAUCHY", 7652 ``!s. (?l. (s --> l) sequentially) <=> cauchy s``, 7653 GEN_TAC THEN EQ_TAC THENL 7654 [METIS_TAC [LEFT_IMP_EXISTS_THM, CONVERGENT_IMP_CAUCHY], 7655 REWRITE_TAC[REWRITE_RULE[complete, IN_UNIV] COMPLETE_UNIV]]); 7656 7657val CONVERGENT_IMP_BOUNDED = store_thm ("CONVERGENT_IMP_BOUNDED", 7658 ``!s l. (s --> l) sequentially ==> bounded (IMAGE s univ(:num))``, 7659 SIMP_TAC std_ss [LEFT_FORALL_IMP_THM, CONVERGENT_EQ_CAUCHY] THEN 7660 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN 7661 REWRITE_TAC [bounded_def] THEN SET_TAC []); 7662 7663(* ------------------------------------------------------------------------- *) 7664(* Total boundedness. *) 7665(* ------------------------------------------------------------------------- *) 7666 7667val COMPACT_IMP_TOTALLY_BOUNDED = store_thm 7668 ("COMPACT_IMP_TOTALLY_BOUNDED", 7669 ``!s:real->bool. compact s 7670 ==> !e. &0 < e ==> ?k. FINITE k /\ k SUBSET s /\ 7671 s SUBSET (BIGUNION (IMAGE (\x. ball(x,e)) k))``, 7672 GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 7673 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN 7674 REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`, SUBSET_DEF] THEN 7675 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 7676 SUBGOAL_THEN 7677 ``?x:num->real. !n. x(n) IN s /\ !m. m < n ==> ~(dist(x(m),x(n)) < e)`` 7678 MP_TAC THENL 7679 [SUBGOAL_THEN 7680 ``?x:num->real. 7681 !n. x(n) = @y. y IN s /\ !m. m < n ==> ~(dist(x(m),y) < e)`` 7682 MP_TAC THENL 7683 [KNOW_TAC ``?(x :num -> real). !(n :num). x n = 7684 (\x n. @(y :real). y IN (s :real -> bool) /\ 7685 !(m :num). m < n ==> ~((dist (x m,y) :real) < (e :real))) x n`` THENL 7686 [ALL_TAC, METIS_TAC []] THEN 7687 MATCH_MP_TAC(MATCH_MP WF_REC WF_num) THEN SIMP_TAC std_ss [], ALL_TAC] THEN 7688 DISCH_THEN (X_CHOOSE_TAC ``x:num->real``) THEN EXISTS_TAC ``x:num->real`` THEN 7689 KNOW_TAC ``!(n :num). (\n. (x :num -> real) n IN (s :real -> bool) /\ 7690 !(m :num). m < n ==> ~((dist (x m,x n) :real) < (e :real))) n`` THENL 7691 [ALL_TAC, METIS_TAC []] THEN 7692 MATCH_MP_TAC COMPLETE_INDUCTION THEN X_GEN_TAC ``n:num`` THEN 7693 BETA_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SPEC ``n:num``) THEN STRIP_TAC THEN 7694 CONV_TAC SELECT_CONV THEN 7695 FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (x:num->real) {m | m < n}``) THEN 7696 SIMP_TAC std_ss [IMAGE_FINITE, FINITE_NUMSEG_LT, NOT_FORALL_THM, NOT_IMP] THEN 7697 SIMP_TAC std_ss [IN_BIGUNION, IN_IMAGE, GSPECIFICATION] THEN METIS_TAC[IN_BALL], 7698 ALL_TAC] THEN 7699 SIMP_TAC std_ss [compact, NOT_FORALL_THM] THEN 7700 DISCH_THEN (X_CHOOSE_TAC ``x:num->real``) THEN EXISTS_TAC ``x:num->real`` THEN 7701 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IMP, FORALL_AND_THM] THEN 7702 STRIP_TAC THEN ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN REPEAT STRIP_TAC THEN 7703 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 7704 FIRST_X_ASSUM(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN 7705 REWRITE_TAC[cauchy] THEN DISCH_THEN(MP_TAC o SPEC ``e:real``) THEN 7706 ASM_SIMP_TAC std_ss [o_THM, NOT_EXISTS_THM, NOT_IMP, NOT_FORALL_THM, NOT_IMP] THEN 7707 X_GEN_TAC ``N:num`` THEN MAP_EVERY EXISTS_TAC [``N:num``, ``SUC N``] THEN 7708 CONJ_TAC THENL [ARITH_TAC, ASM_MESON_TAC[LT]]); 7709 7710(* ------------------------------------------------------------------------- *) 7711(* Heine-Borel theorem (following Burkill & Burkill vol. 2) *) 7712(* ------------------------------------------------------------------------- *) 7713 7714val HEINE_BOREL_LEMMA = store_thm ("HEINE_BOREL_LEMMA", 7715 ``!s:real->bool. compact s 7716 ==> !t. s SUBSET (BIGUNION t) /\ (!b. b IN t ==> open b) 7717 ==> ?e. &0 < e /\ 7718 !x. x IN s ==> ?b. b IN t /\ ball(x,e) SUBSET b``, 7719 GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 7720 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN 7721 DISCH_THEN(CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 7722 DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC ``&1 / (&n + &1:real)``) THEN 7723 SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT_01, REAL_ARITH ``x <= y ==> x < y + &1:real``, 7724 FORALL_AND_THM, REAL_POS, NOT_FORALL_THM, NOT_IMP, SKOLEM_THM, compact] THEN 7725 DISCH_THEN (X_CHOOSE_TAC ``f:num->real``) THEN 7726 EXISTS_TAC ``f:num->real`` THEN POP_ASSUM MP_TAC THEN 7727 SIMP_TAC std_ss [NOT_EXISTS_THM] THEN 7728 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN 7729 DISCH_TAC THEN MAP_EVERY X_GEN_TAC [``l:real``, ``r:num->num``] THEN 7730 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 7731 SUBGOAL_THEN ``?b:real->bool. l IN b /\ b IN t`` STRIP_ASSUME_TAC THENL 7732 [ASM_MESON_TAC[SUBSET_DEF, IN_BIGUNION], ALL_TAC] THEN 7733 SUBGOAL_THEN ``?e. &0 < e /\ !z:real. dist(z,l) < e ==> z IN b`` 7734 STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[open_def], ALL_TAC] THEN 7735 UNDISCH_TAC ``(f o r:num->num --> l:real) sequentially`` THEN DISCH_TAC THEN 7736 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LIM_SEQUENTIALLY]) THEN 7737 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN 7738 SUBGOAL_THEN ``&0 < e / &2:real`` (fn th => 7739 REWRITE_TAC [th, o_THM] THEN MP_TAC(ONCE_REWRITE_RULE [REAL_ARCH_INV] th)) 7740 THENL [ASM_REWRITE_TAC[REAL_HALF], ALL_TAC] THEN 7741 DISCH_THEN(X_CHOOSE_THEN ``N1:num`` STRIP_ASSUME_TAC) THEN 7742 DISCH_THEN(X_CHOOSE_THEN ``N2:num`` STRIP_ASSUME_TAC) THEN 7743 FIRST_X_ASSUM(MP_TAC o SPECL 7744 [``(r:num->num)(N1 + N2)``, ``b:real->bool``]) THEN 7745 ASM_REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 7746 FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_R THEN 7747 EXISTS_TAC ``(f:num->real)(r(N1 + N2:num))`` THEN CONJ_TAC THENL 7748 [ALL_TAC, FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC] THEN 7749 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [IN_BALL]) THEN 7750 MATCH_MP_TAC(REAL_ARITH ``a <= b ==> x < a ==> x < b:real``) THEN 7751 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``inv(&N1:real)`` THEN 7752 ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE] THEN REWRITE_TAC[real_div, REAL_MUL_LID] THEN 7753 MATCH_MP_TAC REAL_LE_INV2 THEN 7754 REWRITE_TAC[REAL_OF_NUM_ADD, REAL_OF_NUM_LE, REAL_LT] THEN 7755 ASM_MESON_TAC[ARITH_PROVE ``(~(n = 0) ==> 0 < n:num)``, LESS_EQ_ADD, MONOTONE_BIGGER, 7756 LESS_IMP_LESS_OR_EQ, LESS_EQ_TRANS]); 7757 7758val COMPACT_IMP_HEINE_BOREL = store_thm 7759 ("COMPACT_IMP_HEINE_BOREL", 7760 ``!s. compact (s:real->bool) 7761 ==> !f. (!t. t IN f ==> open t) /\ s SUBSET (BIGUNION f) 7762 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (BIGUNION f')``, 7763 REPEAT STRIP_TAC THEN 7764 FIRST_ASSUM(MP_TAC o SPEC ``f:(real->bool)->bool`` o 7765 MATCH_MP HEINE_BOREL_LEMMA) THEN ASM_REWRITE_TAC[] THEN 7766 DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 7767 DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 7768 SIMP_TAC std_ss [SKOLEM_THM, SUBSET_DEF, IN_BALL] THEN 7769 DISCH_THEN(X_CHOOSE_TAC ``B:real->real->bool``) THEN 7770 FIRST_ASSUM(MP_TAC o SPEC ``e:real`` o 7771 MATCH_MP COMPACT_IMP_TOTALLY_BOUNDED) THEN 7772 ASM_SIMP_TAC std_ss [BIGUNION_IMAGE, SUBSET_DEF, GSPECIFICATION] THEN 7773 REWRITE_TAC[IN_BIGUNION, IN_BALL] THEN 7774 DISCH_THEN(X_CHOOSE_THEN ``k:real->bool`` STRIP_ASSUME_TAC) THEN 7775 EXISTS_TAC ``IMAGE (B:real->real->bool) k`` THEN 7776 ASM_SIMP_TAC std_ss [IMAGE_FINITE, SUBSET_DEF, IN_IMAGE, LEFT_IMP_EXISTS_THM] THEN 7777 ASM_MESON_TAC[IN_BALL]); 7778 7779(* ------------------------------------------------------------------------- *) 7780(* Bolzano-Weierstrass property. *) 7781(* ------------------------------------------------------------------------- *) 7782 7783val HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS = store_thm 7784 ("HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS", 7785 ``!s:real->bool. 7786 (!f. (!t. t IN f ==> open t) /\ s SUBSET (BIGUNION f) 7787 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (BIGUNION f')) 7788 ==> !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t``, 7789 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM, limit_point_of] THEN REPEAT GEN_TAC THEN 7790 ONCE_REWRITE_TAC[TAUT `a ==> b /\ c ==> d <=> c ==> ~d ==> a ==> ~b`] THEN 7791 KNOW_TAC ``t SUBSET s 7792 ==> (!x. ?t'. ~(x IN s:real->bool /\ 7793 (x IN t' /\ open t' ==> (?y. ~(y = x) /\ y IN t /\ y IN t')))) 7794 ==> (!f. (!t. t IN f ==> open t) /\ s SUBSET BIGUNION f 7795 ==> (?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET BIGUNION f')) 7796 ==> ~INFINITE t`` THENL 7797 [ALL_TAC, SIMP_TAC std_ss [NOT_FORALL_THM, NOT_EXISTS_THM, RIGHT_AND_FORALL_THM] THEN 7798 METIS_TAC []] THEN 7799 DISCH_TAC THEN SIMP_TAC std_ss [SKOLEM_THM] THEN 7800 DISCH_THEN(X_CHOOSE_TAC ``f:real->real->bool``) THEN 7801 DISCH_THEN(MP_TAC o SPEC 7802 ``{t:real->bool | ?x:real. x IN s /\ (t = f x)}``) THEN 7803 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_BIGUNION, NOT_IMP] THEN 7804 KNOW_TAC ``(!t. (?x. x IN s:real->bool /\ (t = f x)) ==> open t) /\ 7805 (!x. x IN s ==> ?s'. x IN s' /\ ?x. x IN s /\ (s' = f x))`` THENL 7806 [METIS_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 7807 DISCH_THEN(X_CHOOSE_THEN ``g:(real->bool)->bool`` STRIP_ASSUME_TAC) THEN 7808 MATCH_MP_TAC SUBSET_FINITE_I THEN 7809 EXISTS_TAC ``{x:real | x IN t /\ (f(x):real->bool) IN g}`` THEN 7810 CONJ_TAC THENL 7811 [MATCH_MP_TAC FINITE_IMAGE_INJ_GENERAL THEN ASM_MESON_TAC[SUBSET_DEF], 7812 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN X_GEN_TAC ``u:real`` THEN 7813 DISCH_TAC THEN SUBGOAL_THEN ``(u:real) IN s`` ASSUME_TAC THEN 7814 ASM_MESON_TAC[SUBSET_DEF]]); 7815 7816(* ------------------------------------------------------------------------- *) 7817(* Complete the chain of compactness variants. *) 7818(* ------------------------------------------------------------------------- *) 7819 7820val BOLZANO_WEIERSTRASS_IMP_BOUNDED = store_thm ("BOLZANO_WEIERSTRASS_IMP_BOUNDED", 7821 ``!s:real->bool. 7822 (!t. INFINITE t /\ t SUBSET s ==> ?x. x limit_point_of t) 7823 ==> bounded s``, 7824 GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 7825 SIMP_TAC std_ss [compact, bounded_def] THEN 7826 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_EXISTS_THM, SKOLEM_THM, NOT_IMP] THEN 7827 REWRITE_TAC[REAL_NOT_LE] THEN 7828 DISCH_THEN(X_CHOOSE_TAC ``beyond:real->real``) THEN 7829 KNOW_TAC ``?f. (f(0) = beyond(&0)) /\ 7830 (!n. f(SUC n) = beyond(abs(f n) + &1):real)`` THENL 7831 [RW_TAC std_ss [num_Axiom], ALL_TAC] THEN 7832 DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN 7833 EXISTS_TAC ``IMAGE (x:num->real) UNIV`` THEN 7834 SUBGOAL_THEN 7835 ``!m n. m < n ==> abs((x:num->real) m) + &1 < abs(x n)`` 7836 ASSUME_TAC THENL 7837 [GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[LT] THEN 7838 ASM_MESON_TAC[REAL_LT_TRANS, REAL_ARITH ``b < b + &1:real``], 7839 ALL_TAC] THEN 7840 SUBGOAL_THEN ``!m n. ~(m = n) ==> &1 < dist((x:num->real) m,x n)`` 7841 ASSUME_TAC THENL 7842 [REPEAT GEN_TAC THEN REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC 7843 (SPECL [``m:num``, ``n:num``] LT_CASES) THEN 7844 ASM_MESON_TAC[dist, LT_CASES, ABS_TRIANGLE_SUB, ABS_SUB, 7845 REAL_ARITH ``x + &1 < y /\ y <= x + d ==> &1 < d:real``], 7846 ALL_TAC] THEN 7847 REPEAT CONJ_TAC THENL 7848 [ASM_MESON_TAC[IMAGE_11_INFINITE, num_INFINITE, DIST_REFL, 7849 REAL_ARITH ``~(&1 < &0:real)``], 7850 SIMP_TAC std_ss [SUBSET_DEF, IN_IMAGE, IN_UNIV, LEFT_IMP_EXISTS_THM] THEN 7851 INDUCT_TAC THEN METIS_TAC[], ALL_TAC] THEN 7852 X_GEN_TAC ``l:real`` THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN 7853 SIMP_TAC std_ss [IN_IMAGE, IN_UNIV, GSYM LEFT_EXISTS_AND_THM] THEN 7854 KNOW_TAC ``~(!(e :real). (0 :real) < e ==> 7855 (?(x'' :num) (x' :real). (x' = (x :num -> real) x'') /\ (x' <> (l :real)) /\ 7856 ((dist (x',l) :real) < e)))`` THENL 7857 [ALL_TAC, METIS_TAC []] THEN SIMP_TAC std_ss [UNWIND_THM2] THEN 7858 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 7859 FIRST_ASSUM(MP_TAC o SPEC ``&1 / &2:real``) THEN 7860 REWRITE_TAC [METIS [REAL_HALF_BETWEEN] ``0 < 1 / 2:real``] THEN 7861 DISCH_THEN(X_CHOOSE_THEN ``k:num`` STRIP_ASSUME_TAC) THEN 7862 FIRST_X_ASSUM(MP_TAC o SPEC ``dist((x:num->real) k,l)``) THEN 7863 ASM_SIMP_TAC std_ss [DIST_POS_LT] THEN 7864 X_GEN_TAC ``m:num`` THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 7865 ASM_CASES_TAC ``m:num = k`` THEN 7866 ASM_MESON_TAC[DIST_TRIANGLE_HALF_L, REAL_LT_TRANS, REAL_LT_REFL]); 7867 7868val INF_FINITE_LEMMA = store_thm ("INF_FINITE_LEMMA", 7869 ``!s. FINITE s /\ ~(s = {}) ==> ?b:real. b IN s /\ !x. x IN s ==> b <= x``, 7870 REWRITE_TAC[CONJ_EQ_IMP] THEN 7871 ONCE_REWRITE_TAC [METIS [] ``!s. ( s <> {} ==> ?b. b IN s /\ !x. x IN s ==> b <= x) = (\s. s <> {} ==> ?b:real. b IN s /\ !x. x IN s ==> b <= x) s``] THEN 7872 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 7873 REWRITE_TAC[NOT_INSERT_EMPTY, IN_INSERT] THEN 7874 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN 7875 MESON_TAC[REAL_LE_TOTAL, REAL_LE_TRANS]); 7876 7877val INF_FINITE = store_thm ("INF_FINITE", 7878 ``!s:real->bool. FINITE s /\ ~(s = {}) ==> (inf s) IN s /\ !x. x IN s ==> inf s <= x``, 7879 GEN_TAC THEN DISCH_TAC THEN 7880 FIRST_ASSUM(MP_TAC o MATCH_MP INF_FINITE_LEMMA) THEN 7881 ASM_MESON_TAC[REAL_LE_ANTISYM, REAL_LE_TOTAL, INF]); 7882 7883val REAL_LE_INF_FINITE = store_thm ("REAL_LE_INF_FINITE", 7884 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (a <= inf s <=> !x. x IN s ==> a <= x)``, 7885 METIS_TAC[INF_FINITE, REAL_LE_TRANS]); 7886 7887val REAL_INF_LE_FINITE = store_thm ("REAL_INF_LE_FINITE", 7888 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (inf s <= a <=> ?x. x IN s /\ x <= a)``, 7889 MESON_TAC[INF_FINITE, REAL_LE_TRANS]); 7890 7891val REAL_LT_INF_FINITE = store_thm ("REAL_LT_INF_FINITE", 7892 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (a < inf s <=> !x. x IN s ==> a < x)``, 7893 MESON_TAC[INF_FINITE, REAL_LTE_TRANS]); 7894 7895val REAL_INF_LT_FINITE = store_thm ("REAL_INF_LT_FINITE", 7896 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (inf s < a <=> ?x. x IN s /\ x < a)``, 7897 MESON_TAC[INF_FINITE, REAL_LET_TRANS]); 7898 7899val SEQUENCE_INFINITE_LEMMA = store_thm ("SEQUENCE_INFINITE_LEMMA", 7900 ``!f l. (!n. ~(f(n) = l)) /\ (f --> l) sequentially 7901 ==> INFINITE {y:real | ?n. y = f n}``, 7902 REPEAT STRIP_TAC THEN MP_TAC(ISPEC 7903 ``IMAGE (\y:real. dist(y,l)) {y | ?n:num. y = f n}`` INF_FINITE) THEN 7904 ASM_SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, IN_IMAGE, IMAGE_FINITE, GSPECIFICATION] THEN 7905 ASM_MESON_TAC[LIM_SEQUENTIALLY, LESS_EQ_REFL, REAL_NOT_LE, DIST_POS_LT]); 7906 7907val LE_1 = store_thm ("LE_1", 7908 ``(!n:num. ~(n = 0) ==> 0 < n) /\ 7909 (!n:num. ~(n = 0) ==> 1 <= n) /\ 7910 (!n:num. 0 < n ==> ~(n = 0)) /\ 7911 (!n:num. 0 < n ==> 1 <= n) /\ 7912 (!n:num. 1 <= n ==> 0 < n) /\ 7913 (!n:num. 1 <= n ==> ~(n = 0))``, 7914 REWRITE_TAC[LT_NZ, GSYM NOT_LESS, ONE, LT]); 7915 7916val LIMPT_OF_SEQUENCE_SUBSEQUENCE = store_thm ("LIMPT_OF_SEQUENCE_SUBSEQUENCE", 7917 ``!f:num->real l. 7918 l limit_point_of (IMAGE f univ(:num)) 7919 ==> ?r. (!m n. m < n ==> r(m) < r(n)) /\ ((f o r) --> l) sequentially``, 7920 REPEAT STRIP_TAC THEN 7921 FIRST_ASSUM(MP_TAC o REWRITE_RULE [LIMPT_APPROACHABLE]) THEN 7922 DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC 7923 ``inf((inv(&n + &1:real)) INSERT IMAGE (\k. dist((f:num->real) k,l)) 7924 {k | k IN (0:num)..n /\ ~(f k = l)})``) THEN 7925 SIMP_TAC std_ss [REAL_LT_INF_FINITE, FINITE_INSERT, NOT_INSERT_EMPTY, 7926 FINITE_RESTRICT, FINITE_NUMSEG, IMAGE_FINITE] THEN 7927 SIMP_TAC std_ss [FORALL_IN_INSERT, EXISTS_IN_IMAGE, FORALL_IN_IMAGE, IN_UNIV] THEN 7928 SIMP_TAC std_ss [REAL_LT_INV_EQ, METIS [REAL_LT, REAL_OF_NUM_ADD, GSYM ADD1, LESS_0] 7929 ``&0 < &n + &1:real``] THEN 7930 SIMP_TAC std_ss [FORALL_AND_THM, FORALL_IN_GSPEC, GSYM DIST_NZ, SKOLEM_THM] THEN 7931 DISCH_THEN(X_CHOOSE_THEN ``nn:num->num`` STRIP_ASSUME_TAC) THEN 7932 KNOW_TAC ``?r:num->num. (r 0 = nn 0) /\ (!n. r (SUC n) = nn(r n))`` THENL 7933 [RW_TAC std_ss [num_Axiom], ALL_TAC] THEN 7934 STRIP_TAC THEN EXISTS_TAC ``r:num->num`` THEN 7935 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL 7936 [ONCE_REWRITE_TAC [METIS [] 7937 `` (r:num->num) m < r n <=> (\m n. r m < r n) m n``] THEN 7938 MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN CONJ_TAC THENL 7939 [METIS_TAC [LESS_TRANS], ALL_TAC] THEN 7940 X_GEN_TAC ``n:num`` THEN ASM_REWRITE_TAC[] THEN 7941 FIRST_X_ASSUM(MP_TAC o SPECL 7942 [``(r:num->num) n``, ``(nn:num->num)(r(n:num))``]) THEN 7943 ASM_SIMP_TAC arith_ss [IN_NUMSEG, ZERO_LESS_EQ, REAL_LT_REFL], 7944 DISCH_THEN(ASSUME_TAC o MATCH_MP MONOTONE_BIGGER)] THEN 7945 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 7946 X_GEN_TAC ``e:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_ARCH_INV] THEN 7947 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 7948 POP_ASSUM MP_TAC THEN STRIP_TAC THEN 7949 ONCE_REWRITE_TAC [METIS [] ``!n:num. (N <= n ==> dist ((f o r) n,l) < e) <=> 7950 (\n. N <= n ==> dist ((f o r) n,l) < e) n``] THEN 7951 MATCH_MP_TAC INDUCTION THEN ASM_SIMP_TAC std_ss [CONJUNCT1 LE] THEN 7952 X_GEN_TAC ``n:num`` THEN DISCH_THEN(K ALL_TAC) THEN DISCH_TAC THEN 7953 ASM_SIMP_TAC std_ss [o_THM] THEN MATCH_MP_TAC REAL_LT_TRANS THEN 7954 EXISTS_TAC ``inv(&((r:num->num) n) + &1:real)`` THEN ASM_REWRITE_TAC[] THEN 7955 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``inv(&N:real)`` THEN 7956 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN 7957 ASM_SIMP_TAC std_ss [REAL_OF_NUM_LE, REAL_LT, LE_1, REAL_OF_NUM_ADD] THEN 7958 MATCH_MP_TAC(ARITH_PROVE ``N <= SUC n /\ n <= r n ==> N <= r n + 1``) THEN 7959 ASM_REWRITE_TAC[]); 7960 7961val SEQUENCE_UNIQUE_LIMPT = store_thm ("SEQUENCE_UNIQUE_LIMPT", 7962 ``!f l l':real. 7963 (f --> l) sequentially /\ l' limit_point_of {y | ?n. y = f n} 7964 ==> (l' = l)``, 7965 REWRITE_TAC[SET_RULE ``{y | ?n. y = f n} = IMAGE f univ(:num)``] THEN 7966 REPEAT STRIP_TAC THEN 7967 FIRST_X_ASSUM(MP_TAC o MATCH_MP LIMPT_OF_SEQUENCE_SUBSEQUENCE) THEN 7968 DISCH_THEN(X_CHOOSE_THEN ``r:num->num`` STRIP_ASSUME_TAC) THEN 7969 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN 7970 EXISTS_TAC ``(f:num->real) o (r:num->num)`` THEN 7971 ASM_SIMP_TAC std_ss [TRIVIAL_LIMIT_SEQUENTIALLY, LIM_SUBSEQUENCE]); 7972 7973val BOLZANO_WEIERSTRASS_IMP_CLOSED = store_thm ("BOLZANO_WEIERSTRASS_IMP_CLOSED", 7974 ``!s:real->bool. 7975 (!t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t) 7976 ==> closed s``, 7977 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS] THEN 7978 MAP_EVERY X_GEN_TAC [``f:num->real``, ``l:real``] THEN 7979 DISCH_TAC THEN 7980 MAP_EVERY (MP_TAC o ISPECL [``f:num->real``, ``l:real``]) 7981 [SEQUENCE_UNIQUE_LIMPT, SEQUENCE_INFINITE_LEMMA] THEN 7982 MATCH_MP_TAC(TAUT 7983 `(~d ==> a /\ ~(b /\ c)) ==> (a ==> b) ==> c ==> d`) THEN 7984 DISCH_TAC THEN CONJ_TAC THENL [ASM_MESON_TAC[], STRIP_TAC] THEN 7985 FIRST_X_ASSUM(MP_TAC o SPEC ``{y:real | ?n:num. y = f n}``) THEN 7986 ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL 7987 [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION], 7988 ABBREV_TAC ``t = {y:real | ?n:num. y = f n}``] THEN 7989 ASM_MESON_TAC[]); 7990 7991(* ------------------------------------------------------------------------- *) 7992(* Hence express everything as an equivalence. *) 7993(* ------------------------------------------------------------------------- *) 7994 7995val COMPACT_EQ_HEINE_BOREL = store_thm ("COMPACT_EQ_HEINE_BOREL", 7996 ``!s:real->bool. compact s <=> 7997 !f. (!t. t IN f ==> open t) /\ s SUBSET (BIGUNION f) 7998 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (BIGUNION f')``, 7999 GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [COMPACT_IMP_HEINE_BOREL] THEN 8000 DISCH_THEN(MP_TAC o MATCH_MP HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS) THEN 8001 DISCH_TAC THEN MATCH_MP_TAC BOUNDED_CLOSED_IMP_COMPACT THEN 8002 ASM_MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED, 8003 BOLZANO_WEIERSTRASS_IMP_CLOSED]); 8004 8005val COMPACT_EQ_BOLZANO_WEIERSTRASS = store_thm ("COMPACT_EQ_BOLZANO_WEIERSTRASS", 8006 ``!s:real->bool. compact s <=> 8007 !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t``, 8008 GEN_TAC THEN EQ_TAC THENL 8009 [SIMP_TAC std_ss [COMPACT_EQ_HEINE_BOREL, HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS], 8010 MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED, BOLZANO_WEIERSTRASS_IMP_CLOSED, 8011 BOUNDED_CLOSED_IMP_COMPACT]]); 8012 8013val COMPACT_EQ_BOUNDED_CLOSED = store_thm ("COMPACT_EQ_BOUNDED_CLOSED", 8014``!s:real->bool. compact s <=> bounded s /\ closed s``, 8015 GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSED_IMP_COMPACT] THEN 8016 MESON_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS, BOLZANO_WEIERSTRASS_IMP_BOUNDED, 8017 BOLZANO_WEIERSTRASS_IMP_CLOSED]); 8018 8019val COMPACT_IMP_BOUNDED = store_thm ("COMPACT_IMP_BOUNDED", 8020 ``!s. compact s ==> bounded s``, 8021 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED]); 8022 8023val COMPACT_IMP_CLOSED = store_thm ("COMPACT_IMP_CLOSED", 8024 ``!s. compact s ==> closed s``, 8025 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED]); 8026 8027val COMPACT_SEQUENCE_WITH_LIMIT = store_thm ("COMPACT_SEQUENCE_WITH_LIMIT", 8028 ``!f l:real. 8029 (f --> l) sequentially ==> compact (l INSERT IMAGE f univ(:num))``, 8030 REPEAT STRIP_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN 8031 REWRITE_TAC[BOUNDED_INSERT] THEN CONJ_TAC THENL 8032 [ASM_MESON_TAC[CONVERGENT_IMP_BOUNDED], 8033 SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_INSERT, IN_INSERT] THEN 8034 SIMP_TAC std_ss [IMAGE_DEF, IN_UNIV, SET_RULE ``{f x | x IN s} = 8035 {y | ?x. x IN s /\ (y = f x)}``] THEN REPEAT STRIP_TAC THEN DISJ1_TAC THEN 8036 MATCH_MP_TAC SEQUENCE_UNIQUE_LIMPT THEN METIS_TAC[]]); 8037 8038val CLOSED_IN_COMPACT = store_thm ("CLOSED_IN_COMPACT", 8039 ``!s t:real->bool. 8040 compact s /\ closed_in (subtopology euclidean s) t 8041 ==> compact t``, 8042 SIMP_TAC std_ss [CONJ_EQ_IMP, COMPACT_EQ_BOUNDED_CLOSED, CLOSED_IN_CLOSED_EQ] THEN 8043 MESON_TAC[BOUNDED_SUBSET]); 8044 8045val CLOSED_IN_COMPACT_EQ = store_thm ("CLOSED_IN_COMPACT_EQ", 8046 ``!s t. compact s 8047 ==> (closed_in (subtopology euclidean s) t <=> 8048 compact t /\ t SUBSET s)``, 8049 MESON_TAC[CLOSED_IN_CLOSED_EQ, COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_SUBSET]); 8050 8051(* ------------------------------------------------------------------------- *) 8052(* A version of Heine-Borel for subtopology. *) 8053(* ------------------------------------------------------------------------- *) 8054 8055val COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY = store_thm ("COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY", 8056 ``!s:real->bool. compact s <=> 8057 (!f. (!t. t IN f ==> open_in(subtopology euclidean s) t) /\ 8058 s SUBSET BIGUNION f 8059 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET BIGUNION f')``, 8060 GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN EQ_TAC THEN 8061 DISCH_TAC THEN X_GEN_TAC ``f:(real->bool)->bool`` THENL 8062 [REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_TAC THEN 8063 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 8064 SIMP_TAC std_ss [SKOLEM_THM] THEN 8065 DISCH_THEN(CONJUNCTS_THEN2 8066 (X_CHOOSE_TAC ``m:(real->bool)->(real->bool)``) ASSUME_TAC) THEN 8067 FIRST_X_ASSUM(MP_TAC o SPEC 8068 ``IMAGE (m:(real->bool)->(real->bool)) f``) THEN 8069 ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 8070 KNOW_TAC ``(s :real -> bool) SUBSET 8071 BIGUNION 8072 (IMAGE (m :(real -> bool) -> real -> bool) 8073 (f :(real -> bool) -> bool))`` THENL 8074 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 8075 DISCH_THEN(X_CHOOSE_THEN ``f':(real->bool)->bool`` STRIP_ASSUME_TAC) THEN 8076 EXISTS_TAC ``IMAGE (\t:real->bool. s INTER t) f'`` THEN 8077 ASM_SIMP_TAC std_ss [IMAGE_FINITE, BIGUNION_IMAGE, SUBSET_DEF, FORALL_IN_IMAGE] THEN 8078 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 8079 UNDISCH_TAC ``f' SUBSET IMAGE (m :(real -> bool) -> real -> bool) f`` THEN 8080 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_IMAGE]) THEN 8081 STRIP_TAC THEN ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN ASM_MESON_TAC[SUBSET_DEF], 8082 DISCH_TAC THEN 8083 FIRST_X_ASSUM(MP_TAC o SPEC ``{s INTER t:real->bool | t IN f}``) THEN 8084 SIMP_TAC std_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, OPEN_IN_OPEN, BIGUNION_IMAGE] THEN 8085 KNOW_TAC ``(!(t :real -> bool). 8086 t IN (f :(real -> bool) -> bool) ==> 8087 ?(t' :real -> bool). 8088 (open t' :bool) /\ ((s :real -> bool) INTER t = s INTER t')) /\ 8089 s SUBSET {y | ?(t :real -> bool). t IN f /\ y IN s INTER t}`` THENL 8090 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 8091 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN 8092 SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE, BIGUNION_IMAGE] THEN 8093 STRIP_TAC THEN EXISTS_TAC ``f' :(real -> bool) -> bool`` THEN 8094 ASM_SET_TAC []]); 8095 8096(* ------------------------------------------------------------------------- *) 8097(* More easy lemmas. *) 8098(* ------------------------------------------------------------------------- *) 8099 8100val COMPACT_CLOSURE = store_thm ("COMPACT_CLOSURE", 8101 ``!s. compact(closure s) <=> bounded s``, 8102 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE, BOUNDED_CLOSURE_EQ]); 8103 8104val BOLZANO_WEIERSTRASS_CONTRAPOS = store_thm ("BOLZANO_WEIERSTRASS_CONTRAPOS", 8105 ``!s t:real->bool. 8106 compact s /\ t SUBSET s /\ 8107 (!x. x IN s ==> ~(x limit_point_of t)) 8108 ==> FINITE t``, 8109 REWRITE_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS] THEN MESON_TAC[]); 8110 8111val DISCRETE_BOUNDED_IMP_FINITE = store_thm ("DISCRETE_BOUNDED_IMP_FINITE", 8112 ``!s:real->bool e. &0 < e /\ 8113 (!x y. x IN s /\ y IN s /\ abs(y - x) < e ==> (y = x)) /\ 8114 bounded s ==> FINITE s``, 8115 REPEAT STRIP_TAC THEN 8116 SUBGOAL_THEN ``compact(s:real->bool)`` MP_TAC THENL 8117 [ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN 8118 ASM_MESON_TAC[DISCRETE_IMP_CLOSED], 8119 DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_HEINE_BOREL)] THEN 8120 DISCH_THEN(MP_TAC o SPEC ``IMAGE (\x:real. ball(x,e)) s``) THEN 8121 SIMP_TAC std_ss [FORALL_IN_IMAGE, OPEN_BALL, BIGUNION_IMAGE, GSPECIFICATION] THEN 8122 KNOW_TAC ``(s :real -> bool) SUBSET 8123 {y | ?(x :real). x IN s /\ y IN ball (x,(e :real))}`` THENL 8124 [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN ASM_MESON_TAC[CENTRE_IN_BALL], 8125 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 8126 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`]] THEN 8127 SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE] THEN 8128 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 8129 SUBGOAL_THEN ``s:real->bool = t`` (fn th => ASM_REWRITE_TAC[th]) THEN 8130 MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN 8131 REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 8132 UNDISCH_TAC ``s SUBSET BIGUNION (IMAGE (\x. ball (x,e)) t)`` THEN 8133 GEN_REWR_TAC (LAND_CONV o RAND_CONV) [BIGUNION_IMAGE] THEN 8134 DISCH_THEN(MP_TAC o SPEC ``x:real`` o REWRITE_RULE [SUBSET_DEF]) THEN 8135 ASM_SIMP_TAC std_ss [GSPECIFICATION, IN_BALL, dist] THEN ASM_MESON_TAC[SUBSET_DEF]); 8136 8137val BOLZANO_WEIERSTRASS = store_thm ("BOLZANO_WEIERSTRASS", 8138 ``!s:real->bool. bounded s /\ INFINITE s ==> ?x. x limit_point_of s``, 8139 GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 8140 FIRST_ASSUM(ASSUME_TAC o MATCH_MP NO_LIMIT_POINT_IMP_CLOSED) THEN 8141 STRIP_TAC THEN 8142 MP_TAC(ISPEC ``s:real->bool`` COMPACT_EQ_BOLZANO_WEIERSTRASS) THEN 8143 ASM_SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED] THEN 8144 EXISTS_TAC ``s:real->bool`` THEN 8145 ASM_REWRITE_TAC[SUBSET_REFL] THEN ASM_MESON_TAC[]); 8146 8147val BOUNDED_EQ_BOLZANO_WEIERSTRASS = store_thm ("BOUNDED_EQ_BOLZANO_WEIERSTRASS", 8148 ``!s:real->bool. 8149 bounded s <=> !t. t SUBSET s /\ INFINITE t ==> ?x. x limit_point_of t``, 8150 MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED, BOLZANO_WEIERSTRASS, 8151 BOUNDED_SUBSET]); 8152 8153(* ------------------------------------------------------------------------- *) 8154(* In particular, some common special cases. *) 8155(* ------------------------------------------------------------------------- *) 8156 8157val COMPACT_EMPTY = store_thm ("COMPACT_EMPTY", 8158 ``compact {}``, 8159 REWRITE_TAC[compact, NOT_IN_EMPTY]); 8160 8161val COMPACT_UNION = store_thm ("COMPACT_UNION", 8162 ``!s t. compact s /\ compact t ==> compact (s UNION t)``, 8163 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_UNION, CLOSED_UNION]); 8164 8165val COMPACT_INTER = store_thm ("COMPACT_INTER", 8166 ``!s t. compact s /\ compact t ==> compact (s INTER t)``, 8167 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTER, CLOSED_INTER]); 8168 8169val COMPACT_INTER_CLOSED = store_thm ("COMPACT_INTER_CLOSED", 8170 ``!s t. compact s /\ closed t ==> compact (s INTER t)``, 8171 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_INTER] THEN 8172 MESON_TAC[BOUNDED_SUBSET, INTER_SUBSET]); 8173 8174val CLOSED_INTER_COMPACT = store_thm ("CLOSED_INTER_COMPACT", 8175 ``!s t. closed s /\ compact t ==> compact (s INTER t)``, 8176 MESON_TAC[COMPACT_INTER_CLOSED, INTER_COMM]); 8177 8178val COMPACT_BIGINTER = store_thm ("COMPACT_BIGINTER", 8179 ``!f:(real->bool)->bool. 8180 (!s. s IN f ==> compact s) /\ ~(f = {}) 8181 ==> compact(BIGINTER f)``, 8182 SIMP_TAC std_ss[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_BIGINTER] THEN 8183 REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_BIGINTER THEN ASM_SET_TAC[]); 8184 8185val FINITE_IMP_CLOSED = store_thm ("FINITE_IMP_CLOSED", 8186 ``!s. FINITE s ==> closed s``, 8187 MESON_TAC[BOLZANO_WEIERSTRASS_IMP_CLOSED, SUBSET_FINITE_I]); 8188 8189val FINITE_IMP_CLOSED_IN = store_thm ("FINITE_IMP_CLOSED_IN", 8190 ``!s t. FINITE s /\ s SUBSET t ==> closed_in (subtopology euclidean t) s``, 8191 SIMP_TAC std_ss [CLOSED_SUBSET_EQ, FINITE_IMP_CLOSED]); 8192 8193val FINITE_IMP_COMPACT = store_thm ("FINITE_IMP_COMPACT", 8194 ``!s. FINITE s ==> compact s``, 8195 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, FINITE_IMP_CLOSED, FINITE_IMP_BOUNDED]); 8196 8197val COMPACT_SING = store_thm ("COMPACT_SING", 8198 ``!a. compact {a}``, 8199 SIMP_TAC std_ss [FINITE_IMP_COMPACT, FINITE_EMPTY, FINITE_INSERT]); 8200 8201val COMPACT_INSERT = store_thm ("COMPACT_INSERT", 8202 ``!a s. compact s ==> compact(a INSERT s)``, 8203 ONCE_REWRITE_TAC[SET_RULE ``a INSERT s = {a} UNION s``] THEN 8204 SIMP_TAC std_ss [COMPACT_UNION, COMPACT_SING]); 8205 8206val CLOSED_SING = store_thm ("CLOSED_SING", 8207 ``!a. closed {a}``, 8208 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, COMPACT_SING]); 8209 8210val CLOSED_IN_SING = store_thm ("CLOSED_IN_SING", 8211 ``!u x:real. closed_in (subtopology euclidean u) {x} <=> x IN u``, 8212 SIMP_TAC std_ss [CLOSED_SUBSET_EQ, CLOSED_SING] THEN SET_TAC[]); 8213 8214val CLOSURE_SING = store_thm ("CLOSURE_SING", 8215 ``!x:real. closure {x} = {x}``, 8216 SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_SING]); 8217 8218val CLOSED_INSERT = store_thm ("CLOSED_INSERT", 8219 ``!a s. closed s ==> closed(a INSERT s)``, 8220 ONCE_REWRITE_TAC[SET_RULE ``a INSERT s = {a} UNION s``] THEN 8221 SIMP_TAC std_ss [CLOSED_UNION, CLOSED_SING]); 8222 8223val COMPACT_CBALL = store_thm ("COMPACT_CBALL", 8224 ``!x e. compact(cball(x,e))``, 8225 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_CBALL, CLOSED_CBALL]); 8226 8227val COMPACT_FRONTIER_BOUNDED = store_thm ("COMPACT_FRONTIER_BOUNDED", 8228 ``!s. bounded s ==> compact(frontier s)``, 8229 SIMP_TAC std_ss [frontier, COMPACT_EQ_BOUNDED_CLOSED, 8230 CLOSED_DIFF, OPEN_INTERIOR, CLOSED_CLOSURE] THEN 8231 MESON_TAC[DIFF_SUBSET, BOUNDED_SUBSET, BOUNDED_CLOSURE]); 8232 8233val COMPACT_FRONTIER = store_thm ("COMPACT_FRONTIER", 8234 ``!s. compact s ==> compact (frontier s)``, 8235 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, COMPACT_FRONTIER_BOUNDED]); 8236 8237val BOUNDED_FRONTIER = store_thm ("BOUNDED_FRONTIER", 8238 ``!s:real->bool. bounded s ==> bounded(frontier s)``, 8239 MESON_TAC[COMPACT_FRONTIER_BOUNDED, COMPACT_IMP_BOUNDED]); 8240 8241val FRONTIER_SUBSET_COMPACT = store_thm ("FRONTIER_SUBSET_COMPACT", 8242 ``!s. compact s ==> frontier s SUBSET s``, 8243 MESON_TAC[FRONTIER_SUBSET_CLOSED, COMPACT_EQ_BOUNDED_CLOSED]); 8244 8245val OPEN_DELETE = store_thm ("OPEN_DELETE", 8246 ``!s x. open s ==> open(s DELETE x)``, 8247SIMP_TAC std_ss [SET_RULE ``s DELETE x = s DIFF {x}``, 8248 OPEN_DIFF, CLOSED_SING]); 8249 8250val OPEN_IN_DELETE = store_thm ("OPEN_IN_DELETE", 8251 ``!u s a:real. 8252 open_in (subtopology euclidean u) s 8253 ==> open_in (subtopology euclidean u) (s DELETE a)``, 8254 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``(a:real) IN s`` THENL 8255 [ONCE_REWRITE_TAC[SET_RULE ``s DELETE a = s DIFF {a}``] THEN 8256 MATCH_MP_TAC OPEN_IN_DIFF THEN ASM_REWRITE_TAC[CLOSED_IN_SING] THEN 8257 FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM_SET_TAC[], 8258 ASM_SIMP_TAC std_ss [SET_RULE ``~(a IN s) ==> (s DELETE a = s)``]]); 8259 8260val CLOSED_BIGINTER_COMPACT = store_thm ("CLOSED_BIGINTER_COMPACT", 8261 ``!s:real->bool. 8262 closed s <=> !e. compact(cball(0,e) INTER s)``, 8263 GEN_TAC THEN EQ_TAC THENL 8264 [SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_INTER, CLOSED_CBALL, 8265 BOUNDED_INTER, BOUNDED_CBALL], ALL_TAC] THEN 8266 STRIP_TAC THEN REWRITE_TAC[CLOSED_LIMPT] THEN 8267 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 8268 FIRST_X_ASSUM(MP_TAC o SPEC ``abs(x:real) + &1:real``) THEN 8269 DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_CLOSED) THEN 8270 REWRITE_TAC[CLOSED_LIMPT] THEN DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 8271 REWRITE_TAC[IN_INTER] THEN 8272 KNOW_TAC ``(x :real) limit_point_of 8273 cball ((0 :real),abs x + (1 :real)) INTER (s :real -> bool)`` THENL 8274 [ALL_TAC, MESON_TAC[]] THEN 8275 POP_ASSUM MP_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN 8276 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 8277 FIRST_X_ASSUM(MP_TAC o SPEC ``min e (&1 / &2:real)``) THEN 8278 KNOW_TAC ``0 < min e (1 / 2:real)`` THENL 8279 [REWRITE_TAC [min_def] THEN COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [REAL_HALF_BETWEEN], 8280 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 8281 DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN 8282 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [IN_INTER, IN_CBALL] THEN 8283 REWRITE_TAC [REAL_LT_MIN, DIST_0, dist] THEN STRIP_TAC THEN 8284 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 8285 ASM_REAL_ARITH_TAC); 8286 8287val COMPACT_BIGUNION = store_thm ("COMPACT_BIGUNION", 8288 ``!s. FINITE s /\ (!t. t IN s ==> compact t) ==> compact(BIGUNION s)``, 8289 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_BIGUNION, BOUNDED_BIGUNION]); 8290 8291val COMPACT_DIFF = store_thm ("COMPACT_DIFF", 8292 ``!s t. compact s /\ open t ==> compact(s DIFF t)``, 8293 ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN 8294 SIMP_TAC std_ss [COMPACT_INTER_CLOSED, GSYM OPEN_CLOSED]); 8295 8296val COMPACT_SPHERE = store_thm ("COMPACT_SPHERE", 8297 ``!a:real r. compact(sphere(a,r))``, 8298 REPEAT GEN_TAC THEN 8299 REWRITE_TAC[GSYM FRONTIER_CBALL] THEN MATCH_MP_TAC COMPACT_FRONTIER THEN 8300 REWRITE_TAC[COMPACT_CBALL]); 8301 8302val BOUNDED_SPHERE = store_thm ("BOUNDED_SPHERE", 8303 ``!a:real r. bounded(sphere(a,r))``, 8304 SIMP_TAC std_ss [COMPACT_SPHERE, COMPACT_IMP_BOUNDED]); 8305 8306val CLOSED_SPHERE = store_thm ("CLOSED_SPHERE", 8307 ``!a r. closed(sphere(a,r))``, 8308 SIMP_TAC std_ss [COMPACT_SPHERE, COMPACT_IMP_CLOSED]); 8309 8310val FRONTIER_SING = store_thm ("FRONTIER_SING", 8311 ``!a:real. frontier {a} = {a}``, 8312 REWRITE_TAC[frontier, CLOSURE_SING, INTERIOR_SING, DIFF_EMPTY]); 8313 8314(* ------------------------------------------------------------------------- *) 8315(* Finite intersection property. I could make it an equivalence in fact. *) 8316(* ------------------------------------------------------------------------- *) 8317 8318val lemma = prove ( 8319 ``(s = UNIV DIFF t) <=> (UNIV DIFF s = t)``, 8320 SET_TAC[]); 8321 8322val COMPACT_IMP_FIP = store_thm ("COMPACT_IMP_FIP", 8323 ``!s:real->bool f. 8324 compact s /\ 8325 (!t. t IN f ==> closed t) /\ 8326 (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (BIGINTER f') = {})) 8327 ==> ~(s INTER (BIGINTER f) = {})``, 8328 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 8329 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [COMPACT_EQ_HEINE_BOREL]) THEN 8330 DISCH_THEN(MP_TAC o SPEC ``IMAGE (\t:real->bool. UNIV DIFF t) f``) THEN 8331 ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 8332 DISCH_THEN(fn th => REPEAT STRIP_TAC THEN MP_TAC th) THEN 8333 ASM_SIMP_TAC std_ss [OPEN_DIFF, CLOSED_DIFF, OPEN_UNIV, CLOSED_UNIV, NOT_IMP] THEN 8334 CONJ_TAC THENL 8335 [UNDISCH_TAC ``(s:real->bool) INTER BIGINTER f = {}`` THEN 8336 ONCE_REWRITE_TAC[SUBSET_DEF, EXTENSION] THEN 8337 REWRITE_TAC [IN_BIGUNION] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN 8338 REWRITE_TAC [EXISTS_IN_IMAGE] THEN BETA_TAC THEN SET_TAC[], 8339 X_GEN_TAC ``g:(real->bool)->bool`` THEN 8340 FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (\t:real->bool. UNIV DIFF t) g``) THEN 8341 ASM_CASES_TAC ``FINITE(g:(real->bool)->bool)`` THEN 8342 ASM_SIMP_TAC std_ss [IMAGE_FINITE] THEN ONCE_REWRITE_TAC[SUBSET_DEF, EXTENSION] THEN 8343 SIMP_TAC std_ss [FORALL_IN_IMAGE, IN_INTER, IN_BIGINTER, IN_IMAGE, IN_DIFF, 8344 IN_UNIV, NOT_IN_EMPTY, lemma, UNWIND_THM1, IN_BIGUNION] THEN 8345 SET_TAC[]]); 8346 8347val CLOSED_IMP_FIP = store_thm ("CLOSED_IMP_FIP", 8348 ``!s:real->bool f. 8349 closed s /\ 8350 (!t. t IN f ==> closed t) /\ (?t. t IN f /\ bounded t) /\ 8351 (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (BIGINTER f') = {})) 8352 ==> ~(s INTER (BIGINTER f) = {})``, 8353 REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC(SET_RULE 8354 ``~((s INTER t) INTER u = {}) ==> ~(s INTER u = {})``) THEN 8355 MATCH_MP_TAC COMPACT_IMP_FIP THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL 8356 [ASM_MESON_TAC[CLOSED_INTER_COMPACT, COMPACT_EQ_BOUNDED_CLOSED], 8357 REWRITE_TAC [METIS [INTER_ASSOC, GSYM BIGINTER_INSERT] 8358 ``!f. s INTER t INTER BIGINTER f = s INTER BIGINTER (t INSERT f)``] THEN 8359 GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 8360 ASM_SIMP_TAC std_ss [FINITE_INSERT, INSERT_SUBSET]]); 8361 8362val CLOSED_IMP_FIP_COMPACT = store_thm ("CLOSED_IMP_FIP_COMPACT", 8363 ``!s:real->bool f. 8364 closed s /\ (!t. t IN f ==> compact t) /\ 8365 (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (BIGINTER f') = {})) 8366 ==> ~(s INTER (BIGINTER f) = {})``, 8367 REPEAT GEN_TAC THEN 8368 ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN 8369 ASM_SIMP_TAC std_ss [SUBSET_EMPTY, BIGINTER_EMPTY, INTER_UNIV] THENL 8370 [MESON_TAC[FINITE_EMPTY], ALL_TAC] THEN 8371 STRIP_TAC THEN MATCH_MP_TAC CLOSED_IMP_FIP THEN 8372 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, MEMBER_NOT_EMPTY]); 8373 8374val CLOSED_FIP = store_thm ("CLOSED_FIP", 8375 ``!f. (!t:real->bool. t IN f ==> closed t) /\ (?t. t IN f /\ bounded t) /\ 8376 (!f'. FINITE f' /\ f' SUBSET f ==> ~(BIGINTER f' = {})) 8377 ==> ~(BIGINTER f = {})``, 8378 GEN_TAC THEN DISCH_TAC THEN 8379 ONCE_REWRITE_TAC[SET_RULE ``(s = {}) <=> (UNIV INTER s = {})``] THEN 8380 MATCH_MP_TAC CLOSED_IMP_FIP THEN ASM_REWRITE_TAC[CLOSED_UNIV, INTER_UNIV]); 8381 8382val COMPACT_FIP = store_thm ("COMPACT_FIP", 8383 ``!f. (!t:real->bool. t IN f ==> compact t) /\ 8384 (!f'. FINITE f' /\ f' SUBSET f ==> ~(BIGINTER f' = {})) 8385 ==> ~(BIGINTER f = {})``, 8386 GEN_TAC THEN DISCH_TAC THEN 8387 ONCE_REWRITE_TAC[SET_RULE ``(s = {}) <=> (UNIV INTER s = {})``] THEN 8388 MATCH_MP_TAC CLOSED_IMP_FIP_COMPACT THEN 8389 ASM_REWRITE_TAC[CLOSED_UNIV, INTER_UNIV]); 8390 8391(* ------------------------------------------------------------------------- *) 8392(* Bounded closed nest property (proof does not use Heine-Borel). *) 8393(* ------------------------------------------------------------------------- *) 8394 8395val BOUNDED_CLOSED_NEST = store_thm ("BOUNDED_CLOSED_NEST", 8396 ``!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\ 8397 (!m n. m <= n ==> s(n) SUBSET s(m)) /\ 8398 bounded(s 0) 8399 ==> ?a:real. !n:num. a IN s(n)``, 8400 GEN_TAC THEN SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, SKOLEM_THM] THEN 8401 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 8402 DISCH_THEN(CONJUNCTS_THEN2 8403 (X_CHOOSE_TAC ``a:num->real``) STRIP_ASSUME_TAC) THEN 8404 SUBGOAL_THEN ``compact(s (0:num):real->bool)`` MP_TAC THENL 8405 [METIS_TAC[BOUNDED_CLOSED_IMP_COMPACT], ALL_TAC] THEN 8406 REWRITE_TAC[compact] THEN 8407 DISCH_THEN(MP_TAC o SPEC ``a:num->real``) THEN 8408 KNOW_TAC ``(!n:num. a n IN s (0:num):real->bool)`` THENL 8409 [ASM_MESON_TAC[SUBSET_DEF, ZERO_LESS_EQ], 8410 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 8411 DISCH_THEN (X_CHOOSE_TAC ``l:real``) THEN 8412 EXISTS_TAC ``l:real`` THEN POP_ASSUM MP_TAC THEN 8413 SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN 8414 DISCH_THEN(X_CHOOSE_THEN ``r:num->num`` STRIP_ASSUME_TAC) THEN 8415 GEN_REWR_TAC I [TAUT `p <=> ~(~p)`] THEN 8416 REWRITE_TAC [NOT_FORALL_THM] THEN X_GEN_TAC ``N:num`` THEN 8417 MP_TAC(ISPECL [``l:real``, ``(s:num->real->bool) N``] 8418 CLOSED_APPROACHABLE) THEN 8419 ASM_MESON_TAC[SUBSET_DEF, LESS_EQ_REFL, LESS_EQ_TRANS, LE_CASES, MONOTONE_BIGGER]); 8420 8421(* ------------------------------------------------------------------------- *) 8422(* Decreasing case does not even need compactness, just completeness. *) 8423(* ------------------------------------------------------------------------- *) 8424 8425val DECREASING_CLOSED_NEST = store_thm ("DECREASING_CLOSED_NEST", 8426 ``!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\ 8427 (!m n. m <= n ==> s(n) SUBSET s(m)) /\ 8428 (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e) 8429 ==> ?a:real. !n:num. a IN s(n)``, 8430 GEN_TAC THEN SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, SKOLEM_THM] THEN 8431 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 8432 DISCH_THEN(CONJUNCTS_THEN2 8433 (X_CHOOSE_TAC ``a:num->real``) STRIP_ASSUME_TAC) THEN 8434 SUBGOAL_THEN ``?l:real. (a --> l) sequentially`` MP_TAC THENL 8435 [ASM_MESON_TAC[cauchy, GE, SUBSET_DEF, LESS_EQ_TRANS, LESS_EQ_REFL, 8436 complete, COMPLETE_UNIV, IN_UNIV], 8437 ASM_MESON_TAC[LIM_SEQUENTIALLY, CLOSED_APPROACHABLE, 8438 SUBSET_DEF, LESS_EQ_REFL, LESS_EQ_TRANS, LE_CASES]]); 8439 8440(* ------------------------------------------------------------------------- *) 8441(* Strengthen it to the intersection actually being a singleton. *) 8442(* ------------------------------------------------------------------------- *) 8443 8444val DECREASING_CLOSED_NEST_SING = store_thm ("DECREASING_CLOSED_NEST_SING", 8445 ``!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\ 8446 (!m n. m <= n ==> s(n) SUBSET s(m)) /\ 8447 (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e) 8448 ==> ?a:real. BIGINTER {t | ?n:num. t = s n} = {a}``, 8449 GEN_TAC THEN DISCH_TAC THEN 8450 FIRST_ASSUM(MP_TAC o MATCH_MP DECREASING_CLOSED_NEST) THEN 8451 STRIP_TAC THEN EXISTS_TAC ``a:real`` THEN 8452 SIMP_TAC std_ss [EXTENSION, IN_BIGINTER, IN_SING, GSPECIFICATION] THEN 8453 METIS_TAC[DIST_POS_LT, REAL_LT_REFL, SUBSET_DEF, LE_CASES]); 8454 8455(* ------------------------------------------------------------------------- *) 8456(* A version for a more general chain, not indexed by N. *) 8457(* ------------------------------------------------------------------------- *) 8458 8459val BOUNDED_CLOSED_CHAIN = store_thm ("BOUNDED_CLOSED_CHAIN", 8460 ``!f b:real->bool. 8461 (!s. s IN f ==> closed s /\ ~(s = {})) /\ 8462 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) /\ 8463 b IN f /\ bounded b 8464 ==> ~(BIGINTER f = {})``, 8465 REPEAT GEN_TAC THEN STRIP_TAC THEN 8466 SUBGOAL_THEN ``~(b INTER (BIGINTER f):real->bool = {})`` MP_TAC THENL 8467 [ALL_TAC, SET_TAC[]] THEN 8468 MATCH_MP_TAC COMPACT_IMP_FIP THEN 8469 ASM_SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED] THEN 8470 X_GEN_TAC ``u:(real->bool)->bool`` THEN STRIP_TAC THEN 8471 SUBGOAL_THEN ``?s:real->bool. s IN f /\ !t. t IN u ==> s SUBSET t`` 8472 MP_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 8473 UNDISCH_TAC ``(u:(real->bool)->bool) SUBSET f`` THEN 8474 UNDISCH_TAC ``FINITE(u:(real->bool)->bool)`` THEN 8475 SPEC_TAC(``u:(real->bool)->bool``,``u:(real->bool)->bool``) THEN 8476 ONCE_REWRITE_TAC [METIS [] ``!u. (u SUBSET f ==> ?s. s IN f /\ !t. t IN u ==> s SUBSET t) = 8477 (\u. u SUBSET f ==> ?s. s IN f /\ !t. t IN u ==> s SUBSET t) u``] THEN 8478 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 8479 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 8480 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN 8481 MAP_EVERY X_GEN_TAC [``u:(real->bool)->bool``, ``t:real->bool``] THEN 8482 REWRITE_TAC[INSERT_SUBSET] THEN 8483 ONCE_REWRITE_TAC [AND_IMP_INTRO] THEN 8484 DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN 8485 ASM_REWRITE_TAC[] THEN 8486 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 8487 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN 8488 DISCH_THEN(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN 8489 FIRST_X_ASSUM(MP_TAC o SPECL [``s:real->bool``, ``t:real->bool``]) THEN 8490 ASM_SET_TAC[]); 8491 8492(* ------------------------------------------------------------------------- *) 8493(* Analogous things directly for compactness. *) 8494(* ------------------------------------------------------------------------- *) 8495 8496val COMPACT_CHAIN = store_thm ("COMPACT_CHAIN", 8497 ``!f:(real->bool)->bool. 8498 (!s. s IN f ==> compact s /\ ~(s = {})) /\ 8499 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) 8500 ==> ~(BIGINTER f = {})``, 8501 GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN STRIP_TAC THEN 8502 ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THENL 8503 [ASM_REWRITE_TAC[BIGINTER_EMPTY] THEN SET_TAC[], 8504 MATCH_MP_TAC BOUNDED_CLOSED_CHAIN THEN ASM_SET_TAC[]]); 8505 8506val COMPACT_NEST = store_thm ("COMPACT_NEST", 8507 ``!s. (!n. compact(s n) /\ ~(s n = {})) /\ 8508 (!m n. m <= n ==> s n SUBSET s m) 8509 ==> ~(BIGINTER {s n | n IN univ(:num)} = {})``, 8510 GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC COMPACT_CHAIN THEN 8511 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 8512 ONCE_REWRITE_TAC [METIS [] ``!n n'. (s n SUBSET s n' \/ s n' SUBSET s n) = 8513 (\n n'. s n SUBSET s n' \/ s n' SUBSET s n) n n'``] THEN 8514 MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]); 8515 8516(* ------------------------------------------------------------------------- *) 8517(* Cauchy-type criteria for *uniform* convergence. *) 8518(* ------------------------------------------------------------------------- *) 8519 8520val UNIFORMLY_CONVERGENT_EQ_CAUCHY = store_thm ("UNIFORMLY_CONVERGENT_EQ_CAUCHY", 8521 ``!P s:num->'a->real. 8522 (?l. !e. &0 < e 8523 ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e) <=> 8524 (!e. &0 < e 8525 ==> ?N. !m n x. N <= m /\ N <= n /\ P x 8526 ==> dist(s m x,s n x) < e)``, 8527 REPEAT GEN_TAC THEN EQ_TAC THENL 8528 [DISCH_THEN(X_CHOOSE_TAC ``l:'a->real``) THEN X_GEN_TAC ``e:real`` THEN 8529 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 8530 ASM_REWRITE_TAC[REAL_HALF] THEN MESON_TAC[DIST_TRIANGLE_HALF_L], 8531 ALL_TAC] THEN 8532 DISCH_TAC THEN 8533 SUBGOAL_THEN ``!x:'a. P x ==> cauchy (\n. s n x :real)`` MP_TAC THENL 8534 [REWRITE_TAC[cauchy, GE] THEN ASM_MESON_TAC[], ALL_TAC] THEN 8535 REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY, LIM_SEQUENTIALLY] THEN 8536 DISCH_TAC THEN KNOW_TAC ``(!(x :'a). ?(l :real). (P :'a -> bool) x ==> 8537 (!(e :real). (0 :real) < e ==> 8538 (?(N :num). !(n :num). N <= n ==> 8539 (dist ((\(n :num). (s :num -> 'a -> real) n x) n,l) :real) < e)))`` THENL 8540 [METIS_TAC [], POP_ASSUM K_TAC] THEN SIMP_TAC std_ss [SKOLEM_THM] THEN 8541 DISCH_THEN (X_CHOOSE_TAC ``l:'a->real``) THEN 8542 EXISTS_TAC ``l:'a->real`` THEN POP_ASSUM MP_TAC THEN 8543 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN 8544 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 8545 ASM_REWRITE_TAC[REAL_HALF] THEN 8546 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 8547 POP_ASSUM MP_TAC THEN STRIP_TAC THEN 8548 MAP_EVERY X_GEN_TAC [``n:num``, ``x:'a``] THEN STRIP_TAC THEN 8549 FIRST_X_ASSUM(MP_TAC o SPEC ``x:'a``) THEN ASM_REWRITE_TAC[] THEN 8550 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_HALF] THEN 8551 DISCH_THEN(X_CHOOSE_TAC ``M:num``) THEN 8552 UNDISCH_TAC ``!m n x. N:num <= m /\ N <= n /\ P x 8553 ==> dist (s m x,s n x) < e / 2:real`` THEN DISCH_TAC THEN 8554 POP_ASSUM (MP_TAC o Q.SPECL [`n:num`, `N + M:num`, `x:'a`]) THEN 8555 ASM_REWRITE_TAC[LE_ADD] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN 8556 FIRST_X_ASSUM(MP_TAC o SPEC ``M + N:num``) THEN REWRITE_TAC[LE_ADD] THEN 8557 ASM_MESON_TAC[DIST_TRIANGLE_HALF_L, DIST_SYM]); 8558 8559Theorem UNIFORMLY_CONVERGENT_EQ_CAUCHY_ALT: 8560 !P s:num->'a->real. 8561 (?l. !e. &0 < e ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e) <=> 8562 (!e. &0 < e ==> 8563 ?N. !m n x. N <= m /\ N <= n /\ m < n /\ P x ==> 8564 dist(s m x,s n x) < e) 8565Proof 8566 REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN 8567 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 8568 FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN 8569 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 8570 ASM_SIMP_TAC std_ss [] THEN 8571 HO_MATCH_MP_TAC WLOG_LT THEN 8572 ASM_SIMP_TAC std_ss [DIST_REFL] THEN MESON_TAC[DIST_SYM] 8573QED 8574 8575val UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT = store_thm ("UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT", 8576 ``!P (s:num->'a->real) l. 8577 (!e. &0 < e 8578 ==> ?N. !m n x. N <= m /\ N <= n /\ P x ==> dist(s m x,s n x) < e) /\ 8579 (!x. P x ==> !e. &0 < e ==> ?N. !n. N <= n ==> dist(s n x,l x) < e) 8580 ==> (!e. &0 < e ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e)``, 8581 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN 8582 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC ``l':'a->real``) ASSUME_TAC) THEN 8583 SUBGOAL_THEN ``!x. P x ==> ((l:'a->real) x = l' x)`` MP_TAC THENL 8584 [ALL_TAC, METIS_TAC[]] THEN 8585 REPEAT STRIP_TAC THEN MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN 8586 EXISTS_TAC ``\n. (s:num->'a->real) n x`` THEN 8587 REWRITE_TAC[LIM_SEQUENTIALLY, TRIVIAL_LIMIT_SEQUENTIALLY] THEN 8588 ASM_MESON_TAC[]); 8589 8590(* ------------------------------------------------------------------------- *) 8591(* Define continuity over a net to take in restrictions of the set. *) 8592(* ------------------------------------------------------------------------- *) 8593 8594val _ = set_fixity "continuous" (Infix(NONASSOC, 450)); 8595 8596val continuous = new_definition ("continuous", 8597 ``f continuous net <=> (f --> f(netlimit net)) net``); 8598 8599val CONTINUOUS_TRIVIAL_LIMIT = store_thm ("CONTINUOUS_TRIVIAL_LIMIT", 8600 ``!f net. trivial_limit net ==> f continuous net``, 8601 SIMP_TAC std_ss [continuous, LIM]); 8602 8603val CONTINUOUS_WITHIN = store_thm ("CONTINUOUS_WITHIN", 8604 ``!f x:real. f continuous (at x within s) <=> (f --> f(x)) (at x within s)``, 8605 REPEAT GEN_TAC THEN REWRITE_TAC[continuous] THEN 8606 ASM_CASES_TAC ``trivial_limit(at (x:real) within s)`` THENL 8607 [ASM_REWRITE_TAC[LIM], ASM_SIMP_TAC std_ss [NETLIMIT_WITHIN]]); 8608 8609val CONTINUOUS_AT = store_thm ("CONTINUOUS_AT", 8610 ``!f (x:real). f continuous (at x) <=> (f --> f(x)) (at x)``, 8611 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 8612 REWRITE_TAC[CONTINUOUS_WITHIN, IN_UNIV]); 8613 8614val CONTINUOUS_AT_WITHIN = store_thm ("CONTINUOUS_AT_WITHIN", 8615 ``!f:real->real x s. 8616 f continuous (at x) ==> f continuous (at x within s)``, 8617 SIMP_TAC std_ss [LIM_AT_WITHIN, CONTINUOUS_AT, CONTINUOUS_WITHIN]); 8618 8619val CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL = store_thm ("CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL", 8620 ``!a s. closed s /\ ~(a IN s) ==> f continuous (at a within s)``, 8621 ASM_SIMP_TAC std_ss [continuous, LIM, LIM_WITHIN_CLOSED_TRIVIAL]); 8622 8623val CONTINUOUS_TRANSFORM_WITHIN = store_thm ("CONTINUOUS_TRANSFORM_WITHIN", 8624 ``!f g:real->real s x d. &0 < d /\ x IN s /\ 8625 (!x'. x' IN s /\ dist(x',x) < d ==> (f(x') = g(x'))) /\ 8626 f continuous (at x within s) ==> g continuous (at x within s)``, 8627 SIMP_TAC std_ss [CONTINUOUS_WITHIN] THEN 8628 METIS_TAC[LIM_TRANSFORM_WITHIN, DIST_REFL]); 8629 8630val CONTINUOUS_TRANSFORM_AT = store_thm ("CONTINUOUS_TRANSFORM_AT", 8631 ``!f g:real->real x d. 8632 &0 < d /\ (!x'. dist(x',x) < d ==> (f(x') = g(x'))) /\ 8633 f continuous (at x) ==> g continuous (at x)``, 8634 REWRITE_TAC[CONTINUOUS_AT] THEN 8635 METIS_TAC[LIM_TRANSFORM_AT, DIST_REFL]); 8636 8637val CONTINUOUS_TRANSFORM_WITHIN_OPEN = store_thm ("CONTINUOUS_TRANSFORM_WITHIN_OPEN", 8638 ``!f g:real->real s a. open s /\ a IN s /\ 8639 (!x. x IN s ==> (f x = g x)) /\ 8640 f continuous at a ==> g continuous at a``, 8641 METIS_TAC[CONTINUOUS_AT, LIM_TRANSFORM_WITHIN_OPEN]); 8642 8643val CONTINUOUS_TRANSFORM_WITHIN_OPEN_IN = store_thm ("CONTINUOUS_TRANSFORM_WITHIN_OPEN_IN", 8644 ``!f g:real->real s t a. 8645 open_in (subtopology euclidean t) s /\ a IN s /\ 8646 (!x. x IN s ==> (f x = g x)) /\ 8647 f continuous (at a within t) ==> g continuous (at a within t)``, 8648 METIS_TAC[CONTINUOUS_WITHIN, LIM_TRANSFORM_WITHIN_OPEN_IN]); 8649 8650val CONTINUOUS_TRANSFORM_WITHIN_SET_IMP = store_thm ("CONTINUOUS_TRANSFORM_WITHIN_SET_IMP", 8651 ``!f a s t. eventually (\x. x IN t ==> x IN s) (at a) /\ 8652 f continuous (at a within s) ==> f continuous (at a within t)``, 8653 REWRITE_TAC[CONTINUOUS_WITHIN, LIM_TRANSFORM_WITHIN_SET_IMP]); 8654 8655(* ------------------------------------------------------------------------- *) 8656(* Derive the epsilon-delta forms, which we often use as "definitions" *) 8657(* ------------------------------------------------------------------------- *) 8658 8659val continuous_within = store_thm ("continuous_within", 8660 ``f continuous (at x within s) <=> !e. &0 < e 8661 ==> ?d. &0 < d /\ !x'. x' IN s /\ dist(x',x) < d 8662 ==> dist(f(x'),f(x)) < e``, 8663 SIMP_TAC std_ss [CONTINUOUS_WITHIN, LIM_WITHIN] THEN 8664 SIMP_TAC std_ss [GSYM DIST_NZ] THEN MESON_TAC[DIST_REFL]); 8665 8666val continuous_at = store_thm ("continuous_at", 8667 ``f continuous (at x) <=> 8668 !e. &0 < e ==> ?d. &0 < d /\ 8669 !x'. dist(x',x) < d ==> dist(f(x'),f(x)) < e``, 8670 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 8671 SIMP_TAC std_ss [continuous_within, IN_UNIV]); 8672 8673(* ------------------------------------------------------------------------- *) 8674(* Versions in terms of open balls. *) 8675(* ------------------------------------------------------------------------- *) 8676 8677val CONTINUOUS_WITHIN_BALL = store_thm ("CONTINUOUS_WITHIN_BALL", 8678 ``!f s x. f continuous (at x within s) <=> 8679 !e. &0 < e ==> ?d. &0 < d /\ 8680 IMAGE f (ball(x,d) INTER s) SUBSET ball(f x,e)``, 8681 SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE, IN_BALL, continuous_within, IN_INTER] THEN 8682 MESON_TAC[DIST_SYM]); 8683 8684val CONTINUOUS_AT_BALL = store_thm ("CONTINUOUS_AT_BALL", 8685 ``!f x. f continuous (at x) <=> 8686 !e. &0 < e ==> ?d. &0 < d /\ 8687 IMAGE f (ball(x,d)) SUBSET ball(f x,e)``, 8688 SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE, IN_BALL, continuous_at] THEN 8689 MESON_TAC[DIST_SYM]); 8690 8691(* ------------------------------------------------------------------------- *) 8692(* *) 8693(* ------------------------------------------------------------------------- *) 8694 8695val CONTINUOUS_WITHIN_COMPARISON = store_thm ("CONTINUOUS_WITHIN_COMPARISON", 8696 ``!f:real->real g:real->real s a. 8697 g continuous (at a within s) /\ 8698 (!x. x IN s ==> dist(f a,f x) <= dist(g a,g x)) 8699 ==> f continuous (at a within s)``, 8700 ONCE_REWRITE_TAC[DIST_SYM] THEN 8701 REWRITE_TAC[continuous_within] THEN MESON_TAC[REAL_LET_TRANS]); 8702 8703(* ------------------------------------------------------------------------- *) 8704(* For setwise continuity, just start from the epsilon-delta definitions. *) 8705(* ------------------------------------------------------------------------- *) 8706 8707val _ = set_fixity "continuous_on" (Infix(NONASSOC, 450)); 8708val _ = set_fixity "uniformly_continuous_on" (Infix(NONASSOC, 450)); 8709 8710val continuous_on = new_definition ("continuous_on", 8711 ``f continuous_on s <=> 8712 !x. x IN s ==> !e. &0 < e 8713 ==> ?d. &0 < d /\ !x'. x' IN s /\ dist(x',x) < d 8714 ==> dist(f(x'),f(x)) < e``); 8715 8716val uniformly_continuous_on = new_definition ("uniformly_continuous_on", 8717 ``f uniformly_continuous_on s <=> 8718 !e. &0 < e 8719 ==> ?d. &0 < d /\ !x x'. x IN s /\ x' IN s /\ dist(x',x) < d 8720 ==> dist(f(x'),f(x)) < e``); 8721 8722(* ------------------------------------------------------------------------- *) 8723(* Some simple consequential lemmas. *) 8724(* ------------------------------------------------------------------------- *) 8725 8726val UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS = store_thm ("UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS", 8727 ``!f s. f uniformly_continuous_on s ==> f continuous_on s``, 8728 REWRITE_TAC[uniformly_continuous_on, continuous_on] THEN MESON_TAC[]); 8729 8730val CONTINUOUS_AT_IMP_CONTINUOUS_ON = store_thm ("CONTINUOUS_AT_IMP_CONTINUOUS_ON", 8731 ``!f s. (!x. x IN s ==> f continuous (at x)) ==> f continuous_on s``, 8732 REWRITE_TAC[continuous_at, continuous_on] THEN MESON_TAC[]); 8733 8734val CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN = store_thm ("CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN", 8735 ``!f s. f continuous_on s <=> !x. x IN s ==> f continuous (at x within s)``, 8736 REWRITE_TAC[continuous_on, continuous_within]); 8737 8738val CONTINUOUS_ON = store_thm ("CONTINUOUS_ON", 8739 ``!f (s:real->bool). 8740 f continuous_on s <=> !x. x IN s ==> (f --> f(x)) (at x within s)``, 8741 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_WITHIN]); 8742 8743val CONTINUOUS_ON_EQ_CONTINUOUS_AT = store_thm ("CONTINUOUS_ON_EQ_CONTINUOUS_AT", 8744 ``!f:real->real s. 8745 open s ==> (f continuous_on s <=> (!x. x IN s ==> f continuous (at x)))``, 8746 SIMP_TAC std_ss [CONTINUOUS_ON, CONTINUOUS_AT, LIM_WITHIN_OPEN]); 8747 8748val CONTINUOUS_WITHIN_SUBSET = store_thm ("CONTINUOUS_WITHIN_SUBSET", 8749 ``!f s t x. f continuous (at x within s) /\ t SUBSET s 8750 ==> f continuous (at x within t)``, 8751 REWRITE_TAC[CONTINUOUS_WITHIN] THEN MESON_TAC[LIM_WITHIN_SUBSET]); 8752 8753val CONTINUOUS_ON_SUBSET = store_thm ("CONTINUOUS_ON_SUBSET", 8754 ``!f s t. f continuous_on s /\ t SUBSET s ==> f continuous_on t``, 8755 REWRITE_TAC[CONTINUOUS_ON] THEN MESON_TAC[SUBSET_DEF, LIM_WITHIN_SUBSET]); 8756 8757val UNIFORMLY_CONTINUOUS_ON_SUBSET = store_thm ("UNIFORMLY_CONTINUOUS_ON_SUBSET", 8758 ``!f s t. f uniformly_continuous_on s /\ t SUBSET s 8759 ==> f uniformly_continuous_on t``, 8760 REWRITE_TAC[uniformly_continuous_on] THEN 8761 MESON_TAC[SUBSET_DEF, LIM_WITHIN_SUBSET]); 8762 8763val CONTINUOUS_ON_INTERIOR = store_thm ("CONTINUOUS_ON_INTERIOR", 8764 ``!f:real->real s x. 8765 f continuous_on s /\ x IN interior(s) ==> f continuous at x``, 8766 SIMP_TAC std_ss [interior, GSPECIFICATION] THEN 8767 MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT, CONTINUOUS_ON_SUBSET]); 8768 8769val CONTINUOUS_ON_EQ = store_thm ("CONTINUOUS_ON_EQ", 8770 ``!f g s. (!x. x IN s ==> (f(x) = g(x))) /\ f continuous_on s 8771 ==> g continuous_on s``, 8772 SIMP_TAC std_ss [continuous_on, CONJ_EQ_IMP]); 8773 8774val UNIFORMLY_CONTINUOUS_ON_EQ = store_thm ("UNIFORMLY_CONTINUOUS_ON_EQ", 8775 ``!f g s. (!x. x IN s ==> (f x = g x)) /\ f uniformly_continuous_on s 8776 ==> g uniformly_continuous_on s``, 8777 SIMP_TAC std_ss [uniformly_continuous_on, CONJ_EQ_IMP]); 8778 8779val CONTINUOUS_ON_SING = store_thm ("CONTINUOUS_ON_SING", 8780 ``!f:real->real a. f continuous_on {a}``, 8781 SIMP_TAC std_ss [continuous_on, IN_SING, DIST_REFL] THEN 8782 METIS_TAC[]); 8783 8784val CONTINUOUS_ON_EMPTY = store_thm ("CONTINUOUS_ON_EMPTY", 8785 ``!f:real->real. f continuous_on {}``, 8786 MESON_TAC[CONTINUOUS_ON_SING, EMPTY_SUBSET, CONTINUOUS_ON_SUBSET]); 8787 8788val CONTINUOUS_ON_NO_LIMPT = store_thm ("CONTINUOUS_ON_NO_LIMPT", 8789 ``!f:real->real s. 8790 ~(?x. x limit_point_of s) ==> f continuous_on s``, 8791 REWRITE_TAC[continuous_on, LIMPT_APPROACHABLE] THEN MESON_TAC[DIST_REFL]); 8792 8793val CONTINUOUS_ON_FINITE = store_thm ("CONTINUOUS_ON_FINITE", 8794 ``!f:real->real s. FINITE s ==> f continuous_on s``, 8795 MESON_TAC[CONTINUOUS_ON_NO_LIMPT, LIMIT_POINT_FINITE]); 8796 8797val CONTRACTION_IMP_CONTINUOUS_ON = store_thm ("CONTRACTION_IMP_CONTINUOUS_ON", 8798 ``!f:real->real. 8799 (!x y. x IN s /\ y IN s ==> dist(f x,f y) <= dist(x,y)) 8800 ==> f continuous_on s``, 8801 SIMP_TAC std_ss [continuous_on] THEN MESON_TAC[REAL_LET_TRANS]); 8802 8803val ISOMETRY_ON_IMP_CONTINUOUS_ON = store_thm ("ISOMETRY_ON_IMP_CONTINUOUS_ON", 8804 ``!f:real->real. 8805 (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y))) 8806 ==> f continuous_on s``, 8807 SIMP_TAC std_ss [CONTRACTION_IMP_CONTINUOUS_ON, REAL_LE_REFL]); 8808 8809(* ------------------------------------------------------------------------- *) 8810(* Characterization of various kinds of continuity in terms of sequences. *) 8811(* ------------------------------------------------------------------------- *) 8812 8813val FORALL_POS_MONO_1 = store_thm ("FORALL_POS_MONO_1", 8814 ``!P. (!d e. d < e /\ P d ==> P e) /\ (!n. P(inv(&n + &1))) 8815 ==> !e. (&0:real) < e ==> P e``, 8816 SIMP_TAC std_ss [REAL_OF_NUM_SUC] THEN SIMP_TAC std_ss [GSYM FORALL_SUC] THEN 8817 REWRITE_TAC [FORALL_POS_MONO]); 8818 8819val CONTINUOUS_WITHIN_SEQUENTIALLY = store_thm ("CONTINUOUS_WITHIN_SEQUENTIALLY", 8820 ``!f s a:real. 8821 f continuous (at a within s) <=> 8822 !x. (!n. x(n) IN s) /\ (x --> a) sequentially 8823 ==> ((f o x) --> f(a)) sequentially``, 8824 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL 8825 [SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN MESON_TAC[], ALL_TAC] THEN 8826 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 8827 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN 8828 DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 8829 DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC ``&1 / (&n + &1:real)``) THEN 8830 SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT, REAL_OF_NUM_LE, REAL_POS, 8831 REAL_ARITH ``&0 <= n ==> &0 < n + &1:real``, NOT_FORALL_THM, SKOLEM_THM] THEN 8832 DISCH_THEN (X_CHOOSE_TAC ``y:num->real``) THEN EXISTS_TAC ``y:num->real`` THEN 8833 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IMP, FORALL_AND_THM] THEN 8834 SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN 8835 STRIP_TAC THEN CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[LESS_EQ_REFL]] THEN 8836 KNOW_TAC ``!e. (?N:num. !n. N <= n ==> dist (y n,a) < e) = 8837 (\e. ?N:num. !n. N <= n ==> dist (y n,a) < e) e`` THENL 8838 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 8839 MATCH_MP_TAC FORALL_POS_MONO_1 THEN BETA_TAC THEN 8840 CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS], ALL_TAC] THEN 8841 X_GEN_TAC ``n:num`` THEN EXISTS_TAC ``n:num`` THEN X_GEN_TAC ``m:num`` THEN 8842 DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN 8843 EXISTS_TAC ``&1 / (&m + &1:real)`` THEN ASM_REWRITE_TAC[] THEN 8844 ASM_SIMP_TAC std_ss [REAL_LE_INV2, real_div, REAL_ARITH ``&0 <= x ==> &0 < x + &1:real``, 8845 REAL_POS, REAL_MUL_LID, REAL_LE_RADD, REAL_OF_NUM_LE]); 8846 8847val CONTINUOUS_AT_SEQUENTIALLY = store_thm ("CONTINUOUS_AT_SEQUENTIALLY", 8848 ``!f a:real. f continuous (at a) <=> 8849 !x. (x --> a) sequentially ==> ((f o x) --> f(a)) sequentially``, 8850 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 8851 REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY, IN_UNIV]); 8852 8853val CONTINUOUS_ON_SEQUENTIALLY = store_thm ("CONTINUOUS_ON_SEQUENTIALLY", 8854 ``!f s:real->bool. f continuous_on s <=> 8855 !x a. a IN s /\ (!n. x(n) IN s) /\ (x --> a) sequentially 8856 ==> ((f o x) --> f(a)) sequentially``, 8857 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, 8858 CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]); 8859 8860val UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY = store_thm ("UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY", 8861 ``!f s:real->bool. f uniformly_continuous_on s <=> 8862 !x y. (!n. x(n) IN s) /\ (!n. y(n) IN s) /\ 8863 ((\n. x(n) - y(n)) --> 0) sequentially 8864 ==> ((\n. f(x(n)) - f(y(n))) --> 0) sequentially``, 8865 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN 8866 REWRITE_TAC[LIM_SEQUENTIALLY, dist, REAL_SUB_RZERO] THEN 8867 EQ_TAC THENL [MESON_TAC[], ALL_TAC] THEN 8868 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 8869 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN 8870 DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 8871 DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC ``&1 / (&n + &1:real)``) THEN 8872 SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT, REAL_OF_NUM_LE, REAL_POS, 8873 REAL_ARITH ``&0 <= n ==> &0 < n + &1:real``, NOT_FORALL_THM, SKOLEM_THM] THEN 8874 DISCH_THEN (X_CHOOSE_TAC ``x:num->real``) THEN POP_ASSUM MP_TAC THEN 8875 DISCH_THEN (X_CHOOSE_TAC ``y:num->real``) THEN 8876 EXISTS_TAC ``x:num->real`` THEN EXISTS_TAC ``y:num->real`` THEN 8877 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IMP, FORALL_AND_THM] THEN STRIP_TAC THEN 8878 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[ABS_SUB] THEN CONJ_TAC THENL 8879 [KNOW_TAC ``!e:real. (?N:num. !n. N <= n ==> abs (y n - x n) < e) = 8880 (\e. ?N:num. !n. N <= n ==> abs (y n - x n) < e) e`` THENL 8881 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 8882 MATCH_MP_TAC FORALL_POS_MONO_1 THEN BETA_TAC THEN 8883 CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS], ALL_TAC] THEN 8884 X_GEN_TAC ``n:num`` THEN EXISTS_TAC ``n:num`` THEN X_GEN_TAC ``m:num`` THEN 8885 DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN 8886 EXISTS_TAC ``&1 / (&m + &1:real)`` THEN ASM_REWRITE_TAC[] THEN 8887 ASM_SIMP_TAC std_ss [REAL_LE_INV2, real_div, REAL_ARITH ``&0 <= x ==> &0 < x + &1:real``, 8888 REAL_POS, REAL_MUL_LID, REAL_LE_RADD, REAL_OF_NUM_LE], 8889 EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN 8890 EXISTS_TAC ``\x:num. x`` THEN ASM_SIMP_TAC std_ss [LESS_EQ_REFL]]); 8891 8892val LIM_CONTINUOUS_FUNCTION = store_thm ("LIM_CONTINUOUS_FUNCTION", 8893 ``!f net g l. 8894 f continuous (at l) /\ (g --> l) net ==> ((\x. f(g x)) --> f l) net``, 8895 REWRITE_TAC[tendsto, continuous_at, eventually] THEN MESON_TAC[]); 8896 8897(* ------------------------------------------------------------------------- *) 8898(* Combination results for pointwise continuity. *) 8899(* ------------------------------------------------------------------------- *) 8900 8901val CONTINUOUS_CONST = store_thm ("CONTINUOUS_CONST", 8902 ``!net c. (\x. c) continuous net``, 8903 REWRITE_TAC[continuous, LIM_CONST]); 8904 8905val CONTINUOUS_CMUL = store_thm ("CONTINUOUS_CMUL", 8906 ``!f c net. f continuous net ==> (\x. c * f(x)) continuous net``, 8907 SIMP_TAC std_ss [continuous, LIM_CMUL]); 8908 8909val CONTINUOUS_NEG = store_thm ("CONTINUOUS_NEG", 8910 ``!f net. f continuous net ==> (\x. -(f x)) continuous net``, 8911 SIMP_TAC std_ss [continuous, LIM_NEG]); 8912 8913val CONTINUOUS_ADD = store_thm ("CONTINUOUS_ADD", 8914 ``!f g net. f continuous net /\ g continuous net 8915 ==> (\x. f(x) + g(x)) continuous net``, 8916 SIMP_TAC std_ss [continuous, LIM_ADD]); 8917 8918val CONTINUOUS_SUB = store_thm ("CONTINUOUS_SUB", 8919 ``!f g net. f continuous net /\ g continuous net 8920 ==> (\x. f(x) - g(x)) continuous net``, 8921 SIMP_TAC std_ss [continuous, LIM_SUB]); 8922 8923val CONTINUOUS_ABS = store_thm ("CONTINUOUS_ABS", 8924 ``!(f:'a->real) net. f continuous net 8925 ==> (\x. abs(f(x)):real) continuous net``, 8926 SIMP_TAC std_ss [continuous, LIM_ABS]); 8927 8928val CONTINUOUS_MAX = store_thm ("CONTINUOUS_MAX", 8929 ``!(f:'a->real) (g:'a->real) net. 8930 f continuous net /\ g continuous net 8931 ==> (\x. (max (f(x)) (g(x))):real) continuous net``, 8932 SIMP_TAC std_ss [continuous, LIM_MAX]); 8933 8934val CONTINUOUS_MIN = store_thm ("CONTINUOUS_MIN", 8935 ``!(f:'a->real) (g:'a->real) net. 8936 f continuous net /\ g continuous net 8937 ==> (\x. (min (f(x)) (g(x))):real) continuous net``, 8938 SIMP_TAC std_ss [continuous, LIM_MIN]); 8939 8940val CONTINUOUS_SUM = store_thm ("CONTINUOUS_SUM", 8941 ``!net f s. FINITE s /\ (!a. a IN s ==> (f a) continuous net) 8942 ==> (\x. sum s (\a. f a x)) continuous net``, 8943 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[CONJ_EQ_IMP] THEN 8944 KNOW_TAC ``!s. ((!a:'b. a IN s ==> f a continuous net) ==> 8945 (\x:'a. sum s (\a. f a x)) continuous net) = 8946 (\s. (!a. a IN s ==> f a continuous net) ==> 8947 (\x. sum s (\a. f a x)) continuous net) s`` THENL 8948 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 8949 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 8950 SIMP_TAC std_ss [FORALL_IN_INSERT, NOT_IN_EMPTY, SUM_CLAUSES, 8951 CONTINUOUS_CONST, CONTINUOUS_ADD, ETA_AX] THEN 8952 METIS_TAC [FORALL_IN_INSERT, NOT_IN_EMPTY, SUM_CLAUSES, 8953 CONTINUOUS_CONST, CONTINUOUS_ADD, ETA_AX]); 8954 8955(* ------------------------------------------------------------------------- *) 8956(* Same thing for setwise continuity. *) 8957(* ------------------------------------------------------------------------- *) 8958 8959val CONTINUOUS_ON_CONST = store_thm ("CONTINUOUS_ON_CONST", 8960 ``!s c. (\x. c) continuous_on s``, 8961 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_CONST]); 8962 8963val CONTINUOUS_ON_CMUL = store_thm ("CONTINUOUS_ON_CMUL", 8964 ``!f c s. f continuous_on s ==> (\x. c * f(x)) continuous_on s``, 8965 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_CMUL]); 8966 8967val CONTINUOUS_ON_NEG = store_thm ("CONTINUOUS_ON_NEG", 8968 ``!f s. f continuous_on s 8969 ==> (\x. -(f x)) continuous_on s``, 8970 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_NEG]); 8971 8972val CONTINUOUS_ON_ADD = store_thm ("CONTINUOUS_ON_ADD", 8973 ``!f g s. f continuous_on s /\ g continuous_on s 8974 ==> (\x. f(x) + g(x)) continuous_on s``, 8975 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_ADD]); 8976 8977val CONTINUOUS_ON_SUB = store_thm ("CONTINUOUS_ON_SUB", 8978 ``!f g s. f continuous_on s /\ g continuous_on s 8979 ==> (\x. f(x) - g(x)) continuous_on s``, 8980 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_SUB]); 8981 8982val CONTINUOUS_ON_ABS = store_thm ("CONTINUOUS_ON_ABS", 8983 ``!f:real->real s. f continuous_on s 8984 ==> (\x. (abs(f(x))):real) continuous_on s``, 8985 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_ABS]); 8986 8987val CONTINUOUS_ON_MAX = store_thm ("CONTINUOUS_ON_MAX", 8988 ``!f:real->real g:real->real s. 8989 f continuous_on s /\ g continuous_on s 8990 ==> (\x. (max (f(x)) (g(x))):real) 8991 continuous_on s``, 8992 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_MAX]); 8993 8994val CONTINUOUS_ON_MIN = store_thm ("CONTINUOUS_ON_MIN", 8995 ``!f:real->real g:real->real s. 8996 f continuous_on s /\ g continuous_on s 8997 ==> (\x. (min (f(x)) (g(x))):real) 8998 continuous_on s``, 8999 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_MIN]); 9000 9001val CONTINUOUS_ON_SUM = store_thm ("CONTINUOUS_ON_SUM", 9002 ``!t f s. FINITE s /\ (!a. a IN s ==> (f a) continuous_on t) 9003 ==> (\x. sum s (\a. f a x)) continuous_on t``, 9004 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_SUM]); 9005 9006(* ------------------------------------------------------------------------- *) 9007(* Same thing for uniform continuity, using sequential formulations. *) 9008(* ------------------------------------------------------------------------- *) 9009 9010val UNIFORMLY_CONTINUOUS_ON_CONST = store_thm ("UNIFORMLY_CONTINUOUS_ON_CONST", 9011 ``!s c. (\x. c) uniformly_continuous_on s``, 9012 SIMP_TAC std_ss [UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY, o_DEF, 9013 REAL_SUB_REFL, LIM_CONST]); 9014 9015val LINEAR_UNIFORMLY_CONTINUOUS_ON = store_thm ("LINEAR_UNIFORMLY_CONTINUOUS_ON", 9016 ``!f:real->real s. linear f ==> f uniformly_continuous_on s``, 9017 REPEAT STRIP_TAC THEN 9018 ASM_SIMP_TAC std_ss [uniformly_continuous_on, dist, GSYM LINEAR_SUB] THEN 9019 FIRST_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o 9020 MATCH_MP LINEAR_BOUNDED_POS) THEN 9021 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN EXISTS_TAC ``e / B:real`` THEN 9022 ASM_SIMP_TAC std_ss [REAL_LT_DIV] THEN 9023 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 9024 MATCH_MP_TAC REAL_LET_TRANS THEN 9025 EXISTS_TAC ``B * abs(y - x:real)`` THEN ASM_REWRITE_TAC[] THEN 9026 ASM_MESON_TAC[REAL_LT_RDIV_EQ, REAL_MUL_SYM]); 9027 9028val lemma = prove ( 9029 ``(!y. ((?x. (y = f x) /\ P x) /\ Q y ==> R y)) <=> 9030 (!x. P x /\ Q (f x) ==> R (f x))``, 9031 MESON_TAC[]); 9032 9033val UNIFORMLY_CONTINUOUS_ON_COMPOSE = store_thm ("UNIFORMLY_CONTINUOUS_ON_COMPOSE", 9034 ``!f g s. f uniformly_continuous_on s /\ 9035 g uniformly_continuous_on (IMAGE f s) 9036 ==> (g o f) uniformly_continuous_on s``, 9037 REPEAT GEN_TAC THEN 9038 SIMP_TAC std_ss [uniformly_continuous_on, o_THM, IN_IMAGE] THEN 9039 KNOW_TAC ``((!e:real. 0 < e ==> ?d. 0 < d /\ 9040 !x x'. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9041 (!e:real. 0 < e ==> ?d. 0 < d /\ 9042 !x x'. (?x'. (x = f x') /\ x' IN s) /\ (?x. (x' = f x) /\ x IN s) /\ 9043 dist (x',x) < d ==> dist (g x',g x) < e) ==> 9044 !e:real. 0 < e ==> ?d. 0 < d /\ 9045 !x x'. x IN s /\ x' IN s /\ dist (x',x) < d ==> 9046 dist (g (f x'),g (f x)) < e) = 9047 ((!e:real. 0 < e ==> ?d. 0 < d /\ 9048 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9049 (!e:real. 0 < e ==> ?d. 0 < d /\ 9050 !x' x. (?x'. (x = f x') /\ x' IN s) /\ (?x. (x' = f x) /\ x IN s) /\ 9051 dist (x',x) < d ==> dist (g x',g x) < e) ==> 9052 !e:real. 0 < e ==> ?d. 0 < d /\ 9053 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> 9054 dist (g (f x'),g (f x)) < e)`` THENL 9055 [METIS_TAC [SWAP_FORALL_THM], ALL_TAC] THEN DISC_RW_KILL THEN 9056 KNOW_TAC `` ((!e:real. 0 < e ==> ?d. 0 < d /\ 9057 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9058 (!e:real. 0 < e ==> ?d. 0 < d /\ 9059 !x' x. (?x'. (x = f x') /\ x' IN s) /\ (?x. (x' = f x) /\ x IN s) /\ 9060 dist (x',x) < d ==> dist (g x',g x) < e) ==> 9061 !e:real. 0 < e ==> ?d. 0 < d /\ 9062 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> 9063 dist (g (f x'),g (f x)) < e) = 9064 ((!e:real. 0 < e ==> ?d. 0 < d /\ 9065 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9066 (!e:real. 0 < e ==> ?d. 0 < d /\ 9067 !x' x. x IN s /\ (?x. (x' = f x) /\ x IN s) /\ dist (x',f x) < d 9068 ==> dist (g x',g (f x)) < e) ==> 9069 !e:real. 0 < e ==> ?d. 0 < d /\ 9070 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> 9071 dist (g (f x'),g (f x)) < e)`` THENL 9072 [METIS_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN 9073 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN 9074 KNOW_TAC ``((!e. 0 < e ==> ?d. 0 < d /\ 9075 !x' x. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9076 (!e. 0 < e ==> ?d. 0 < d /\ 9077 !x' x. (?x. (x' = f x) /\ x IN s) /\ x IN s /\ dist (x',f x) < d ==> 9078 dist (g x',g (f x)) < e) ==> 9079 !e. 0 < e ==> ?d. 0 < d /\ 9080 !x' x. x' IN s /\ x IN s /\ dist (x',x) < d ==> 9081 dist (g (f x'),g (f x)) < e) = 9082 ((!e. 0 < e ==> ?d. 0 < d /\ 9083 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9084 (!e. 0 < e ==> ?d. 0 < d /\ 9085 !x x'. (?x. (x' = f x) /\ x IN s) /\ x IN s /\ dist (x',f x) < d ==> 9086 dist (g x',g (f x)) < e) ==> 9087 !e. 0 < e ==> ?d. 0 < d /\ 9088 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> 9089 dist (g (f x'),g (f x)) < e)`` THENL 9090 [METIS_TAC [SWAP_FORALL_THM], ALL_TAC] THEN DISC_RW_KILL THEN 9091 KNOW_TAC ``((!e. 0 < e ==> ?d. 0 < d /\ 9092 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9093 (!e. 0 < e ==> ?d. 0 < d /\ 9094 !x x'. (?x. (x' = f x) /\ x IN s) /\ x IN s /\ dist (x',f x) < d ==> 9095 dist (g x',g (f x)) < e) ==> 9096 !e. 0 < e ==> ?d. 0 < d /\ 9097 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> 9098 dist (g (f x'),g (f x)) < e) = 9099 ((!e. 0 < e ==> ?d. 0 < d /\ 9100 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9101 (!e. 0 < e ==> ?d. 0 < d /\ 9102 !x x'. x' IN s /\ x IN s /\ dist (f x',f x) < d ==> 9103 dist (g (f x'),g (f x)) < e) ==> 9104 !e. 0 < e ==> ?d. 0 < d /\ 9105 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> 9106 dist (g (f x'),g (f x)) < e)`` THENL 9107 [METIS_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN 9108 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 9109 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN 9110 POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 9111 ASM_CASES_TAC ``&0 < e`` THEN ASM_REWRITE_TAC[] THEN 9112 ASM_MESON_TAC[]); 9113 9114val BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE = store_thm ("BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE", 9115 ``!f:real->real g (h:real->real->real) s. 9116 f uniformly_continuous_on s /\ g uniformly_continuous_on s /\ 9117 bilinear h /\ bounded(IMAGE f s) /\ bounded(IMAGE g s) 9118 ==> (\x. h (f x) (g x)) uniformly_continuous_on s``, 9119 REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on, dist] THEN 9120 BETA_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 9121 SUBGOAL_THEN 9122 ``!a b c d. (h:real->real->real) a b - h c d = 9123 h (a - c) b + h c (b - d)`` (fn th => ONCE_REWRITE_TAC[th]) THENL 9124 [FIRST_ASSUM(fn th => REWRITE_TAC[MATCH_MP BILINEAR_LSUB th]) THEN 9125 FIRST_ASSUM(fn th => REWRITE_TAC[MATCH_MP BILINEAR_RSUB th]) THEN 9126 REAL_ARITH_TAC, ALL_TAC] THEN 9127 FIRST_X_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o 9128 MATCH_MP BILINEAR_BOUNDED_POS) THEN 9129 UNDISCH_TAC ``bounded(IMAGE (g:real->real) s)`` THEN 9130 UNDISCH_TAC ``bounded(IMAGE (f:real->real) s)`` THEN 9131 SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE] THEN 9132 DISCH_THEN(X_CHOOSE_THEN ``B1:real`` STRIP_ASSUME_TAC) THEN 9133 DISCH_THEN(X_CHOOSE_THEN ``B2:real`` STRIP_ASSUME_TAC) THEN 9134 UNDISCH_TAC ``(g:real->real) uniformly_continuous_on s`` THEN 9135 UNDISCH_TAC ``(f:real->real) uniformly_continuous_on s`` THEN 9136 REWRITE_TAC[uniformly_continuous_on] THEN 9137 DISCH_THEN(MP_TAC o SPEC ``e:real / &2 / &2 / B / B2``) THEN 9138 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_HALF, dist] THEN 9139 DISCH_THEN(X_CHOOSE_THEN ``d1:real`` STRIP_ASSUME_TAC) THEN 9140 DISCH_THEN(MP_TAC o SPEC ``e:real / &2 / &2 / B / B1``) THEN 9141 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_HALF, dist] THEN 9142 DISCH_THEN(X_CHOOSE_THEN ``d2:real`` STRIP_ASSUME_TAC) THEN 9143 EXISTS_TAC ``min d1 d2:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 9144 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 9145 FIRST_X_ASSUM(MP_TAC o SPECL [``x:real``, ``y:real``]) THEN 9146 FIRST_X_ASSUM(MP_TAC o SPECL [``x:real``, ``y:real``]) THEN 9147 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN 9148 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC 9149 ``B * e / &2 / &2 / B / B2 * B2 + B * B1 * e / &2 / &2 / B / B1:real`` THEN 9150 CONJ_TAC THENL 9151 [MATCH_MP_TAC(REAL_ARITH 9152 ``abs(x) <= a /\ abs(y) <= b ==> abs(x + y:real) <= a + b``) THEN 9153 CONJ_TAC THEN 9154 FIRST_X_ASSUM(fn th => W(MP_TAC o PART_MATCH lhand th o lhand o snd)) THEN 9155 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN 9156 REWRITE_TAC [real_div] THEN REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN 9157 MATCH_MP_TAC REAL_LE_LMUL1 THEN ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE] THENL 9158 [REWRITE_TAC [GSYM real_div, REAL_MUL_ASSOC],ALL_TAC] THEN 9159 MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC [GSYM real_div, REAL_MUL_ASSOC] THEN 9160 ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE, ABS_POS], 9161 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN 9162 REWRITE_TAC [real_div, GSYM REAL_MUL_ASSOC] THEN 9163 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 9164 REWRITE_TAC [GSYM real_div, REAL_MUL_ASSOC] THEN 9165 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN 9166 REWRITE_TAC [real_div] THEN 9167 REWRITE_TAC [REAL_ARITH `` B1 * e * inv 2 * inv 2 * inv B * inv B1 * B = 9168 e * inv 2 * inv 2 * inv B * inv B1 * B1 * B:real``] THEN 9169 REWRITE_TAC [GSYM real_div] THEN 9170 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN 9171 REWRITE_TAC [REAL_HALF_DOUBLE] THEN ASM_SIMP_TAC std_ss [REAL_LT_HALF2]]); 9172 9173val UNIFORMLY_CONTINUOUS_ON_MUL = store_thm ("UNIFORMLY_CONTINUOUS_ON_MUL", 9174 ``!f g:real->real s. 9175 f uniformly_continuous_on s /\ g uniformly_continuous_on s /\ 9176 bounded(IMAGE f s) /\ bounded(IMAGE g s) 9177 ==> (\x. f x * g x) uniformly_continuous_on s``, 9178 REPEAT STRIP_TAC THEN 9179 MP_TAC(ISPECL [``(f:real->real)``, ``g:real->real``, 9180 ``\c (v:real). c * v``, ``s:real->bool``] 9181 BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE) THEN 9182 ASM_SIMP_TAC std_ss [o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN 9183 REWRITE_TAC[bilinear, linear] THEN BETA_TAC THEN REAL_ARITH_TAC); 9184 9185val UNIFORMLY_CONTINUOUS_ON_CMUL = store_thm ("UNIFORMLY_CONTINUOUS_ON_CMUL", 9186 ``!f c s. f uniformly_continuous_on s 9187 ==> (\x. c * f(x)) uniformly_continuous_on s``, 9188 REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN 9189 DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN 9190 POP_ASSUM (MP_TAC o Q.SPECL [`x:num->real`, `y:num->real`]) THEN 9191 DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN 9192 ASM_REWRITE_TAC[] THEN 9193 DISCH_THEN(MP_TAC o MATCH_MP LIM_CMUL) THEN 9194 ASM_SIMP_TAC std_ss [REAL_SUB_LDISTRIB, REAL_MUL_RZERO]); 9195 9196val UNIFORMLY_CONTINUOUS_ON_VMUL = store_thm ("UNIFORMLY_CONTINUOUS_ON_VMUL", 9197 ``!s:real->bool c v:real. 9198 c uniformly_continuous_on s 9199 ==> (\x. c x * v) uniformly_continuous_on s``, 9200 REPEAT GEN_TAC THEN 9201 DISCH_THEN(MP_TAC o ISPEC ``\x. (x * v:real)`` o MATCH_MP 9202 (REWRITE_RULE[CONJ_EQ_IMP] UNIFORMLY_CONTINUOUS_ON_COMPOSE)) THEN 9203 SIMP_TAC std_ss [o_DEF] THEN DISCH_THEN MATCH_MP_TAC THEN 9204 MATCH_MP_TAC LINEAR_UNIFORMLY_CONTINUOUS_ON THEN 9205 REWRITE_TAC [linear] THEN BETA_TAC THEN REAL_ARITH_TAC); 9206 9207val UNIFORMLY_CONTINUOUS_ON_NEG = store_thm ("UNIFORMLY_CONTINUOUS_ON_NEG", 9208 ``!f s. f uniformly_continuous_on s 9209 ==> (\x. -(f x)) uniformly_continuous_on s``, 9210 ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN 9211 REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_CMUL]); 9212 9213val UNIFORMLY_CONTINUOUS_ON_ADD = store_thm ("UNIFORMLY_CONTINUOUS_ON_ADD", 9214 ``!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s 9215 ==> (\x. f(x) + g(x)) uniformly_continuous_on s``, 9216 REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN 9217 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN 9218 DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN 9219 POP_ASSUM (MP_TAC o Q.SPECL [`x:num->real`, `y:num->real`]) THEN 9220 DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN 9221 ASM_SIMP_TAC std_ss [o_DEF] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN 9222 MATCH_MP_TAC EQ_IMPLIES THEN BETA_TAC THEN 9223 REWRITE_TAC[REAL_ADD_LID] THEN AP_THM_TAC THEN BINOP_TAC THEN 9224 REWRITE_TAC[FUN_EQ_THM] THEN BETA_TAC THEN REAL_ARITH_TAC); 9225 9226val UNIFORMLY_CONTINUOUS_ON_SUB = store_thm ("UNIFORMLY_CONTINUOUS_ON_SUB", 9227 ``!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s 9228 ==> (\x. f(x) - g(x)) uniformly_continuous_on s``, 9229 REWRITE_TAC[real_sub] THEN 9230 SIMP_TAC std_ss [UNIFORMLY_CONTINUOUS_ON_NEG, UNIFORMLY_CONTINUOUS_ON_ADD]); 9231 9232val UNIFORMLY_CONTINUOUS_ON_SUM = store_thm ("UNIFORMLY_CONTINUOUS_ON_SUM", 9233 ``!t f s. FINITE s /\ (!a. a IN s ==> (f a) uniformly_continuous_on t) 9234 ==> (\x. sum s (\a. f a x)) uniformly_continuous_on t``, 9235 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[CONJ_EQ_IMP] THEN 9236 KNOW_TAC ``!s. ((!a. a IN s ==> f a uniformly_continuous_on t) ==> 9237 (\x. sum s (\a. f a x)) uniformly_continuous_on t) = 9238 (\s. (!a. a IN s ==> f a uniformly_continuous_on t) ==> 9239 (\x. sum s (\a. f a x)) uniformly_continuous_on t) s`` THENL 9240 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 9241 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 9242 SIMP_TAC std_ss [FORALL_IN_INSERT, NOT_IN_EMPTY, SUM_CLAUSES, 9243 UNIFORMLY_CONTINUOUS_ON_CONST, ETA_AX] THEN REPEAT STRIP_TAC THEN 9244 METIS_TAC [UNIFORMLY_CONTINUOUS_ON_ADD]); 9245 9246(* ------------------------------------------------------------------------- *) 9247(* Identity function is continuous in every sense. *) 9248(* ------------------------------------------------------------------------- *) 9249 9250val CONTINUOUS_WITHIN_ID = store_thm ("CONTINUOUS_WITHIN_ID", 9251 ``!a s. (\x. x) continuous (at a within s)``, 9252 REWRITE_TAC[continuous_within] THEN MESON_TAC[]); 9253 9254val CONTINUOUS_AT_ID = store_thm ("CONTINUOUS_AT_ID", 9255 ``!a. (\x. x) continuous (at a)``, 9256 REWRITE_TAC[continuous_at] THEN MESON_TAC[]); 9257 9258val CONTINUOUS_ON_ID = store_thm ("CONTINUOUS_ON_ID", 9259 ``!s. (\x. x) continuous_on s``, 9260 REWRITE_TAC[continuous_on] THEN MESON_TAC[]); 9261 9262val UNIFORMLY_CONTINUOUS_ON_ID = store_thm ("UNIFORMLY_CONTINUOUS_ON_ID", 9263 ``!s. (\x. x) uniformly_continuous_on s``, 9264 REWRITE_TAC[uniformly_continuous_on] THEN MESON_TAC[]); 9265 9266(* ------------------------------------------------------------------------- *) 9267(* Continuity of all kinds is preserved under composition. *) 9268(* ------------------------------------------------------------------------- *) 9269 9270val CONTINUOUS_WITHIN_COMPOSE = store_thm ("CONTINUOUS_WITHIN_COMPOSE", 9271 ``!f g x s. f continuous (at x within s) /\ 9272 g continuous (at (f x) within IMAGE f s) 9273 ==> (g o f) continuous (at x within s)``, 9274 REPEAT GEN_TAC THEN SIMP_TAC std_ss [continuous_within, o_THM, IN_IMAGE] THEN 9275 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 9276 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 9277 ASM_MESON_TAC[]); 9278 9279val CONTINUOUS_AT_COMPOSE = store_thm ("CONTINUOUS_AT_COMPOSE", 9280 ``!f g x. f continuous (at x) /\ g continuous (at (f x)) 9281 ==> (g o f) continuous (at x)``, 9282 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 9283 MESON_TAC[CONTINUOUS_WITHIN_COMPOSE, IN_IMAGE, CONTINUOUS_WITHIN_SUBSET, 9284 SUBSET_UNIV, IN_UNIV]); 9285 9286val CONTINUOUS_ON_COMPOSE = store_thm ("CONTINUOUS_ON_COMPOSE", 9287 ``!f g s. f continuous_on s /\ g continuous_on (IMAGE f s) 9288 ==> (g o f) continuous_on s``, 9289 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 9290 MESON_TAC[IN_IMAGE, CONTINUOUS_WITHIN_COMPOSE]); 9291 9292(* ------------------------------------------------------------------------- *) 9293(* Continuity in terms of open preimages. *) 9294(* ------------------------------------------------------------------------- *) 9295 9296val CONTINUOUS_WITHIN_OPEN = store_thm ("CONTINUOUS_WITHIN_OPEN", 9297 ``!f:real->real x u. 9298 f continuous (at x within u) <=> 9299 !t. open t /\ f(x) IN t 9300 ==> ?s. open s /\ x IN s /\ 9301 !x'. x' IN s /\ x' IN u ==> f(x') IN t``, 9302 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL 9303 [DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN 9304 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 9305 GEN_REWR_TAC LAND_CONV [open_def] THEN 9306 DISCH_THEN(MP_TAC o SPEC ``(f:real->real) x``) THEN 9307 ASM_MESON_TAC[IN_BALL, DIST_SYM, OPEN_BALL, CENTRE_IN_BALL, DIST_SYM], 9308 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 9309 FIRST_X_ASSUM(MP_TAC o SPEC ``ball((f:real->real) x,e)``) THEN 9310 ASM_SIMP_TAC std_ss [OPEN_BALL, CENTRE_IN_BALL] THEN 9311 MESON_TAC[open_def, IN_BALL, REAL_LT_TRANS, DIST_SYM]]); 9312 9313val CONTINUOUS_AT_OPEN = store_thm ("CONTINUOUS_AT_OPEN", 9314 ``!f:real->real x. 9315 f continuous (at x) <=> 9316 !t. open t /\ f(x) IN t 9317 ==> ?s. open s /\ x IN s /\ 9318 !x'. x' IN s ==> f(x') IN t``, 9319 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_at] THEN EQ_TAC THENL 9320 [DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN 9321 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 9322 GEN_REWR_TAC LAND_CONV [open_def] THEN 9323 DISCH_THEN(MP_TAC o SPEC ``(f:real->real) x``) THEN 9324 ASM_MESON_TAC[IN_BALL, DIST_SYM, OPEN_BALL, CENTRE_IN_BALL], 9325 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 9326 FIRST_X_ASSUM(MP_TAC o SPEC ``ball((f:real->real) x,e)``) THEN 9327 ASM_SIMP_TAC std_ss [OPEN_BALL, CENTRE_IN_BALL] THEN 9328 MESON_TAC[open_def, IN_BALL, REAL_LT_TRANS, DIST_SYM]]); 9329 9330val CONTINUOUS_ON_OPEN_GEN = store_thm ("CONTINUOUS_ON_OPEN_GEN", 9331 ``!f:real->real s t. 9332 IMAGE f s SUBSET t 9333 ==> (f continuous_on s <=> 9334 !u. open_in (subtopology euclidean t) u 9335 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u})``, 9336 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_on] THEN EQ_TAC THENL 9337 [SIMP_TAC std_ss [open_in, SUBSET_DEF, GSPECIFICATION] THEN 9338 DISCH_TAC THEN X_GEN_TAC ``u:real->bool`` THEN STRIP_TAC THEN 9339 X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN 9340 FIRST_X_ASSUM(MP_TAC o SPEC ``(f:real->real) x``) THEN ASM_SET_TAC[], 9341 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN 9342 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 9343 FIRST_X_ASSUM(MP_TAC o 9344 SPEC ``ball((f:real->real) x,e) INTER t``) THEN 9345 KNOW_TAC ``open_in (subtopology euclidean t) (ball ((f:real->real) x,e) INTER t)`` THENL 9346 [ASM_MESON_TAC[OPEN_IN_OPEN, INTER_COMM, OPEN_BALL], ALL_TAC] THEN 9347 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 9348 SIMP_TAC std_ss [open_in, SUBSET_DEF, IN_INTER, GSPECIFICATION, IN_BALL, IN_IMAGE] THEN 9349 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 9350 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF, FORALL_IN_IMAGE]) THEN 9351 FULL_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 9352 ASM_MESON_TAC[DIST_REFL, DIST_SYM]]); 9353 9354val CONTINUOUS_ON_OPEN = store_thm ("CONTINUOUS_ON_OPEN", 9355 ``!f:real->real s. 9356 f continuous_on s <=> 9357 !t. open_in (subtopology euclidean (IMAGE f s)) t 9358 ==> open_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}``, 9359 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_OPEN_GEN THEN 9360 REWRITE_TAC[SUBSET_REFL]); 9361 9362val CONTINUOUS_OPEN_IN_PREIMAGE_GEN = store_thm ("CONTINUOUS_OPEN_IN_PREIMAGE_GEN", 9363 ``!f:real->real s t u. 9364 f continuous_on s /\ IMAGE f s SUBSET t /\ 9365 open_in (subtopology euclidean t) u 9366 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u}``, 9367 METIS_TAC[CONTINUOUS_ON_OPEN_GEN]); 9368 9369val CONTINUOUS_ON_IMP_OPEN_IN = store_thm ("CONTINUOUS_ON_IMP_OPEN_IN", 9370 ``!f:real->real s t. f continuous_on s /\ 9371 open_in (subtopology euclidean (IMAGE f s)) t 9372 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9373 METIS_TAC[CONTINUOUS_ON_OPEN]); 9374 9375(* ------------------------------------------------------------------------- *) 9376(* Similarly in terms of closed sets. *) 9377(* ------------------------------------------------------------------------- *) 9378 9379val CONTINUOUS_ON_CLOSED_GEN = store_thm ("CONTINUOUS_ON_CLOSED_GEN", 9380 ``!f:real->real s t. 9381 IMAGE f s SUBSET t 9382 ==> (f continuous_on s <=> 9383 !u. closed_in (subtopology euclidean t) u 9384 ==> closed_in (subtopology euclidean s) 9385 {x | x IN s /\ f x IN u})``, 9386 REPEAT STRIP_TAC THEN FIRST_ASSUM(fn th => 9387 ONCE_REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THEN 9388 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``u:real->bool`` THEN 9389 FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THENL 9390 [REWRITE_TAC[closed_in], REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ]] THEN 9391 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 9392 DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN 9393 ASM_SIMP_TAC std_ss [SUBSET_RESTRICT] THEN 9394 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]); 9395 9396val CONTINUOUS_ON_CLOSED = store_thm ("CONTINUOUS_ON_CLOSED", 9397 ``!f:real->real s. 9398 f continuous_on s <=> 9399 !t. closed_in (subtopology euclidean (IMAGE f s)) t 9400 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}``, 9401 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CLOSED_GEN THEN 9402 REWRITE_TAC[SUBSET_REFL]); 9403 9404val CONTINUOUS_CLOSED_IN_PREIMAGE_GEN = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE_GEN", 9405 ``!f:real->real s t u. 9406 f continuous_on s /\ IMAGE f s SUBSET t /\ 9407 closed_in (subtopology euclidean t) u 9408 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN u}``, 9409 METIS_TAC[CONTINUOUS_ON_CLOSED_GEN]); 9410 9411val CONTINUOUS_ON_IMP_CLOSED_IN = store_thm ("CONTINUOUS_ON_IMP_CLOSED_IN", 9412 ``!f:real->real s t. f continuous_on s /\ 9413 closed_in (subtopology euclidean (IMAGE f s)) t 9414 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9415 METIS_TAC[CONTINUOUS_ON_CLOSED]); 9416 9417(* ------------------------------------------------------------------------- *) 9418(* Half-global and completely global cases. *) 9419(* ------------------------------------------------------------------------- *) 9420 9421val CONTINUOUS_OPEN_IN_PREIMAGE = store_thm ("CONTINUOUS_OPEN_IN_PREIMAGE", 9422 ``!f s t. 9423 f continuous_on s /\ open t 9424 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9425 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE 9426 ``x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)``] THEN 9427 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_OPEN]) THEN 9428 ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN 9429 ASM_REWRITE_TAC[]); 9430 9431val CONTINUOUS_CLOSED_IN_PREIMAGE = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE", 9432 ``!f s t. 9433 f continuous_on s /\ closed t 9434 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9435 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE 9436 ``x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)``] THEN 9437 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_CLOSED]) THEN 9438 ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC CLOSED_IN_CLOSED_INTER THEN 9439 ASM_REWRITE_TAC[]); 9440 9441val CONTINUOUS_OPEN_PREIMAGE = store_thm ("CONTINUOUS_OPEN_PREIMAGE", 9442 ``!f:real->real s t. 9443 f continuous_on s /\ open s /\ open t 9444 ==> open {x | x IN s /\ f(x) IN t}``, 9445 REPEAT STRIP_TAC THEN 9446 UNDISCH_TAC ``f continuous_on s`` THEN GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_OPEN] THEN 9447 REWRITE_TAC [OPEN_IN_OPEN] THEN 9448 DISCH_THEN(MP_TAC o SPEC ``IMAGE (f:real->real) s INTER t``) THEN 9449 KNOW_TAC ``(?t'. open t' /\ (IMAGE (f:real->real) s INTER t = IMAGE f s INTER t'))`` THENL 9450 [EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC [], 9451 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN 9452 SUBGOAL_THEN ``{x | x IN s /\ (f:real->real) x IN t} = 9453 s INTER t'`` SUBST1_TAC THENL 9454 [ASM_SET_TAC [], ASM_MESON_TAC [OPEN_INTER]]]); 9455 9456val CONTINUOUS_CLOSED_PREIMAGE = store_thm ("CONTINUOUS_CLOSED_PREIMAGE", 9457 ``!f:real->real s t. 9458 f continuous_on s /\ closed s /\ closed t 9459 ==> closed {x | x IN s /\ f(x) IN t}``, 9460 REPEAT STRIP_TAC THEN UNDISCH_TAC ``f continuous_on s`` THEN 9461 GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_CLOSED] THEN 9462 REWRITE_TAC [CLOSED_IN_CLOSED] THEN 9463 DISCH_THEN(MP_TAC o SPEC ``IMAGE (f:real->real) s INTER t``) THEN 9464 KNOW_TAC ``(?t'. closed t' /\ (IMAGE (f:real->real) s INTER t = IMAGE f s INTER t'))`` THENL 9465 [EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC [], 9466 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN 9467 SUBGOAL_THEN ``{x | x IN s /\ (f:real->real) x IN t} = 9468 s INTER t'`` SUBST1_TAC THENL 9469 [ASM_SET_TAC [], ASM_MESON_TAC [CLOSED_INTER]]]); 9470 9471val CONTINUOUS_OPEN_PREIMAGE_UNIV = store_thm ("CONTINUOUS_OPEN_PREIMAGE_UNIV", 9472 ``!f:real->real s. 9473 (!x. f continuous (at x)) /\ open s ==> open {x | f(x) IN s}``, 9474 REPEAT STRIP_TAC THEN 9475 MP_TAC(SPECL [``f:real->real``, ``univ(:real)``, ``s:real->bool``] 9476 CONTINUOUS_OPEN_PREIMAGE) THEN 9477 ASM_SIMP_TAC std_ss [OPEN_UNIV, IN_UNIV, CONTINUOUS_AT_IMP_CONTINUOUS_ON]); 9478 9479val CONTINUOUS_CLOSED_PREIMAGE_UNIV = store_thm ("CONTINUOUS_CLOSED_PREIMAGE_UNIV", 9480 ``!f:real->real s. 9481 (!x. f continuous (at x)) /\ closed s ==> closed {x | f(x) IN s}``, 9482 REPEAT STRIP_TAC THEN 9483 MP_TAC(SPECL [``f:real->real``, ``univ(:real)``, ``s:real->bool``] 9484 CONTINUOUS_CLOSED_PREIMAGE) THEN 9485 ASM_SIMP_TAC std_ss [CLOSED_UNIV, IN_UNIV, CONTINUOUS_AT_IMP_CONTINUOUS_ON]); 9486 9487val CONTINUOUS_OPEN_IN_PREIMAGE_EQ = store_thm ("CONTINUOUS_OPEN_IN_PREIMAGE_EQ", 9488 ``!f:real->real s. f continuous_on s <=> 9489 !t. open t ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9490 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CONTINUOUS_OPEN_IN_PREIMAGE] THEN 9491 REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN DISCH_TAC THEN 9492 X_GEN_TAC ``t:real->bool`` THEN GEN_REWR_TAC LAND_CONV [OPEN_IN_OPEN] THEN 9493 DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 9494 FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN 9495 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN SET_TAC[]); 9496 9497val CONTINUOUS_CLOSED_IN_PREIMAGE_EQ = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE_EQ", 9498 ``!f:real->real s. f continuous_on s <=> !t. closed t 9499 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9500 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CONTINUOUS_CLOSED_IN_PREIMAGE] THEN 9501 REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN DISCH_TAC THEN 9502 X_GEN_TAC ``t:real->bool`` THEN 9503 GEN_REWR_TAC LAND_CONV [CLOSED_IN_CLOSED] THEN 9504 DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 9505 FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN 9506 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN SET_TAC[]); 9507 9508(* ------------------------------------------------------------------------- *) 9509(* Linear functions are (uniformly) continuous on any set. *) 9510(* ------------------------------------------------------------------------- *) 9511 9512val LINEAR_LIM_0 = store_thm ("LINEAR_LIM_0", 9513 ``!f. linear f ==> (f --> 0) (at (0))``, 9514 REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_AT] THEN 9515 FIRST_X_ASSUM(MP_TAC o MATCH_MP LINEAR_BOUNDED_POS) THEN 9516 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 9517 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN EXISTS_TAC ``e / B:real`` THEN 9518 ASM_SIMP_TAC std_ss [REAL_LT_DIV] THEN REWRITE_TAC[dist, REAL_SUB_RZERO] THEN 9519 ASM_MESON_TAC[REAL_MUL_SYM, REAL_LET_TRANS, REAL_LT_RDIV_EQ]); 9520 9521val LINEAR_CONTINUOUS_AT = store_thm ("LINEAR_CONTINUOUS_AT", 9522 ``!f:real->real a. linear f ==> f continuous (at a)``, 9523 REPEAT STRIP_TAC THEN 9524 MP_TAC(ISPEC ``\x. (f:real->real) (a + x) - f(a)`` LINEAR_LIM_0) THEN 9525 KNOW_TAC ``linear (\x. f (a + x) - f a)`` THENL 9526 [POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [linear] THEN 9527 REPEAT STRIP_TAC THEN REAL_ARITH_TAC, ALL_TAC] THEN 9528 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 9529 SIMP_TAC std_ss [GSYM LIM_NULL, CONTINUOUS_AT] THEN 9530 GEN_REWR_TAC RAND_CONV [LIM_AT_ZERO] THEN SIMP_TAC std_ss []); 9531 9532val LINEAR_CONTINUOUS_WITHIN = store_thm ("LINEAR_CONTINUOUS_WITHIN", 9533 ``!f:real->real s x. linear f ==> f continuous (at x within s)``, 9534 SIMP_TAC std_ss [CONTINUOUS_AT_WITHIN, LINEAR_CONTINUOUS_AT]); 9535 9536val LINEAR_CONTINUOUS_ON = store_thm ("LINEAR_CONTINUOUS_ON", 9537 ``!f:real->real s. linear f ==> f continuous_on s``, 9538 MESON_TAC[LINEAR_CONTINUOUS_AT, CONTINUOUS_AT_IMP_CONTINUOUS_ON]); 9539 9540val LINEAR_CONTINUOUS_COMPOSE = store_thm ("LINEAR_CONTINUOUS_COMPOSE", 9541 ``!net f:'a->real g:real->real. 9542 f continuous net /\ linear g ==> (\x. g(f x)) continuous net``, 9543 SIMP_TAC std_ss [continuous, LIM_LINEAR]); 9544 9545val LINEAR_CONTINUOUS_ON_COMPOSE = store_thm ("LINEAR_CONTINUOUS_ON_COMPOSE", 9546 ``!f:real->real g:real->real s. 9547 f continuous_on s /\ linear g ==> (\x. g(f x)) continuous_on s``, 9548 SIMP_TAC std_ss[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, 9549 LINEAR_CONTINUOUS_COMPOSE]); 9550 9551val CONTINUOUS_COMPONENT_COMPOSE = store_thm ("CONTINUOUS_COMPONENT_COMPOSE", 9552 ``!net f:'a->real i. f continuous net ==> (\x. f x) continuous net``, 9553 REPEAT GEN_TAC THEN 9554 SUBGOAL_THEN ``linear(\x:real. x)`` MP_TAC THENL 9555 [REWRITE_TAC[LINEAR_ID], REWRITE_TAC[GSYM IMP_CONJ_ALT]] THEN 9556 METIS_TAC [LINEAR_CONTINUOUS_COMPOSE]); 9557 9558val CONTINUOUS_ON_COMPONENT_COMPOSE = store_thm ("CONTINUOUS_ON_COMPONENT_COMPOSE", 9559 ``!f:real->real s. f continuous_on s 9560 ==> (\x. f x) continuous_on s``, 9561 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, 9562 CONTINUOUS_COMPONENT_COMPOSE]); 9563 9564(* ------------------------------------------------------------------------- *) 9565(* Also bilinear functions, in composition form. *) 9566(* ------------------------------------------------------------------------- *) 9567 9568val BILINEAR_CONTINUOUS_COMPOSE = store_thm ("BILINEAR_CONTINUOUS_COMPOSE", 9569 ``!net f:'a->real g:'a->real h:real->real->real. 9570 f continuous net /\ g continuous net /\ bilinear h 9571 ==> (\x. h (f x) (g x)) continuous net``, 9572 SIMP_TAC std_ss [continuous, LIM_BILINEAR]); 9573 9574val BILINEAR_CONTINUOUS_ON_COMPOSE = store_thm ("BILINEAR_CONTINUOUS_ON_COMPOSE", 9575 ``!f g h s. f continuous_on s /\ g continuous_on s /\ bilinear h 9576 ==> (\x. h (f x) (g x)) continuous_on s``, 9577 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, 9578 BILINEAR_CONTINUOUS_COMPOSE]); 9579 9580val BILINEAR_DOT = store_thm ("BILINEAR_DOT", 9581 ``bilinear (\x y:real. (x * y))``, 9582SIMP_TAC std_ss [bilinear, linear] THEN REAL_ARITH_TAC); 9583 9584val CONTINUOUS_DOT2 = store_thm ("CONTINUOUS_DOT2", 9585 ``!net f g:'a->real. 9586 f continuous net /\ g continuous net 9587 ==> (\x. f x * g x) continuous net``, 9588 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE 9589 [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`] 9590 BILINEAR_CONTINUOUS_COMPOSE) BILINEAR_DOT)) THEN BETA_TAC THEN REWRITE_TAC[]); 9591 9592val CONTINUOUS_ON_DOT2 = store_thm ("CONTINUOUS_ON_DOT2", 9593 ``!f:real->real g s. 9594 f continuous_on s /\ g continuous_on s 9595 ==> (\x. f x * g x) continuous_on s``, 9596 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE 9597 [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`] 9598 BILINEAR_CONTINUOUS_ON_COMPOSE) BILINEAR_DOT)) THEN BETA_TAC THEN REWRITE_TAC[]); 9599 9600(* ------------------------------------------------------------------------- *) 9601(* Preservation of compactness and connectedness under continuous function. *) 9602(* ------------------------------------------------------------------------- *) 9603 9604val COMPACT_CONTINUOUS_IMAGE = store_thm ("COMPACT_CONTINUOUS_IMAGE", 9605 ``!f:real->real s. 9606 f continuous_on s /\ compact s ==> compact(IMAGE f s)``, 9607 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on, compact] THEN 9608 STRIP_TAC THEN X_GEN_TAC ``y:num->real`` THEN 9609 SIMP_TAC std_ss [IN_IMAGE, SKOLEM_THM, FORALL_AND_THM] THEN 9610 DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN 9611 FIRST_X_ASSUM(MP_TAC o SPEC ``x:num->real``) THEN ASM_REWRITE_TAC[] THEN 9612 KNOW_TAC ``((?(l :real) (r :num -> num). 9613 l IN s /\ (!(m :num) (n :num). m < n ==> r m < r n) /\ 9614 ((x :num -> real) o r --> l) sequentially) ==> 9615 ?(l :real) (r :num -> num). 9616 (?(x :real). (l = f x) /\ x IN s) /\ 9617 (!(m :num) (n :num). m < n ==> r m < r n) /\ 9618 ((y :num -> real) o r --> l) sequentially) = 9619 ((?(r :num -> num) (l :real). 9620 l IN s /\ (!(m :num) (n :num). m < n ==> r m < r n) /\ 9621 ((x :num -> real) o r --> l) sequentially) ==> 9622 ?(r :num -> num) (l :real). 9623 (?(x :real). (l = f x) /\ x IN s) /\ 9624 (!(m :num) (n :num). m < n ==> r m < r n) /\ 9625 ((y :num -> real) o r --> l) sequentially)`` THENL 9626 [METIS_TAC [SWAP_EXISTS_THM], DISC_RW_KILL] THEN 9627 STRIP_TAC THEN EXISTS_TAC ``r:num->num`` THEN 9628 EXISTS_TAC ``(f:real->real) l`` THEN ASM_REWRITE_TAC[] THEN 9629 CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC] THEN 9630 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 9631 FIRST_X_ASSUM(MP_TAC o SPEC ``l:real``) THEN 9632 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN GEN_TAC THEN 9633 POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 9634 DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN 9635 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 9636 UNDISCH_TAC `` ((x :num -> real) o (r :num -> num) --> l) sequentially`` THEN 9637 GEN_REWR_TAC LAND_CONV [LIM_SEQUENTIALLY] THEN 9638 DISCH_THEN(MP_TAC o SPEC ``d:real``) THEN ASM_SIMP_TAC std_ss [o_THM] THEN 9639 ASM_MESON_TAC[]); 9640 9641val COMPACT_TRANSLATION = store_thm ("COMPACT_TRANSLATION", 9642 ``!s a:real. compact s ==> compact (IMAGE (\x. a + x) s)``, 9643 SIMP_TAC std_ss [COMPACT_CONTINUOUS_IMAGE, CONTINUOUS_ON_ADD, 9644 CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID]); 9645 9646val COMPACT_TRANSLATION_EQ = store_thm ("COMPACT_TRANSLATION_EQ", 9647 ``!a s. compact (IMAGE (\x:real. a + x) s) <=> compact s``, 9648 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[COMPACT_TRANSLATION] THEN 9649 DISCH_THEN(MP_TAC o ISPEC ``-a:real`` o MATCH_MP COMPACT_TRANSLATION) THEN 9650 SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID, 9651 REAL_ARITH ``-a + (a + x:real) = x``]); 9652 9653val COMPACT_LINEAR_IMAGE = store_thm ("COMPACT_LINEAR_IMAGE", 9654 ``!f:real->real s. compact s /\ linear f ==> compact(IMAGE f s)``, 9655 SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON, COMPACT_CONTINUOUS_IMAGE]); 9656 9657val CONNECTED_CONTINUOUS_IMAGE = store_thm ("CONNECTED_CONTINUOUS_IMAGE", 9658 ``!f:real->real s. 9659 f continuous_on s /\ connected s ==> connected(IMAGE f s)``, 9660 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN 9661 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 9662 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 9663 SIMP_TAC std_ss [CONNECTED_CLOPEN, NOT_FORALL_THM, NOT_IMP, DE_MORGAN_THM] THEN 9664 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 9665 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 9666 FIRST_X_ASSUM(fn th => MP_TAC(SPEC ``t:real->bool`` th) THEN 9667 MP_TAC(SPEC ``IMAGE (f:real->real) s DIFF t`` th)) THEN 9668 ASM_REWRITE_TAC[] THEN 9669 SUBGOAL_THEN ``{x | x IN s /\ (f:real->real) x IN IMAGE f s DIFF t} = 9670 s DIFF {x | x IN s /\ f x IN t}`` SUBST1_TAC THENL 9671 [UNDISCH_TAC ``t SUBSET IMAGE (f:real->real) s`` THEN 9672 SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_DIFF, GSPECIFICATION, SUBSET_DEF] THEN 9673 MESON_TAC[], 9674 REPEAT STRIP_TAC THEN 9675 EXISTS_TAC ``{x | x IN s /\ (f:real->real) x IN t}`` THEN 9676 ASM_REWRITE_TAC[] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 9677 SIMP_TAC std_ss [IN_IMAGE, SUBSET_DEF, GSPECIFICATION, NOT_IN_EMPTY, EXTENSION] THEN 9678 MESON_TAC[]]); 9679 9680val CONNECTED_TRANSLATION = store_thm ("CONNECTED_TRANSLATION", 9681 ``!a s. connected s ==> connected (IMAGE (\x:real. a + x) s)``, 9682 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN 9683 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_ID, CONTINUOUS_ON_CONST]); 9684 9685val CONNECTED_TRANSLATION_EQ = store_thm ("CONNECTED_TRANSLATION_EQ", 9686 ``!a s. connected (IMAGE (\x:real. a + x) s) <=> connected s``, 9687 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONNECTED_TRANSLATION] THEN 9688 DISCH_THEN(MP_TAC o ISPEC ``-a:real`` o MATCH_MP CONNECTED_TRANSLATION) THEN 9689 SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID, 9690 REAL_ARITH ``-a + (a + x:real) = x``]); 9691 9692val CONNECTED_LINEAR_IMAGE = store_thm ("CONNECTED_LINEAR_IMAGE", 9693 ``!f:real->real s. connected s /\ linear f ==> connected(IMAGE f s)``, 9694 SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON, CONNECTED_CONTINUOUS_IMAGE]); 9695 9696(* ------------------------------------------------------------------------- *) 9697(* Quotient maps are occasionally useful. *) 9698(* ------------------------------------------------------------------------- *) 9699 9700val QUASICOMPACT_OPEN_CLOSED = store_thm ("QUASICOMPACT_OPEN_CLOSED", 9701 ``!f:real->real s t. 9702 IMAGE f s SUBSET t 9703 ==> ((!u. u SUBSET t 9704 ==> (open_in (subtopology euclidean s) 9705 {x | x IN s /\ f x IN u} 9706 ==> open_in (subtopology euclidean t) u)) <=> 9707 (!u. u SUBSET t 9708 ==> (closed_in (subtopology euclidean s) 9709 {x | x IN s /\ f x IN u} 9710 ==> closed_in (subtopology euclidean t) u)))``, 9711 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 9712 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN 9713 X_GEN_TAC ``u:real->bool`` THEN 9714 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN 9715 ASM_SIMP_TAC std_ss [SET_RULE ``u SUBSET t ==> (t DIFF (t DIFF u) = u)``] THEN 9716 REWRITE_TAC [DIFF_SUBSET] THEN REPEAT STRIP_TAC THEN 9717 FIRST_X_ASSUM MATCH_MP_TAC THEN SIMP_TAC std_ss [SUBSET_RESTRICT] THEN 9718 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] 9719 ``open_in top x ==> (x = y) ==> open_in top y``)) THEN 9720 ASM_SET_TAC[]); 9721 9722val QUOTIENT_MAP_IMP_CONTINUOUS_OPEN = store_thm ("QUOTIENT_MAP_IMP_CONTINUOUS_OPEN", 9723 ``!f:real->real s t. 9724 IMAGE f s SUBSET t /\ 9725 (!u. u SUBSET t 9726 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 9727 open_in (subtopology euclidean t) u)) 9728 ==> f continuous_on s``, 9729 METIS_TAC[OPEN_IN_IMP_SUBSET, CONTINUOUS_ON_OPEN_GEN]); 9730 9731val QUOTIENT_MAP_IMP_CONTINUOUS_CLOSED = store_thm ("QUOTIENT_MAP_IMP_CONTINUOUS_CLOSED", 9732 ``!f:real->real s t. 9733 IMAGE f s SUBSET t /\ 9734 (!u. u SUBSET t 9735 ==> (closed_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 9736 closed_in (subtopology euclidean t) u)) 9737 ==> f continuous_on s``, 9738 METIS_TAC[CLOSED_IN_IMP_SUBSET, CONTINUOUS_ON_CLOSED_GEN]); 9739 9740val OPEN_MAP_IMP_QUOTIENT_MAP = store_thm ("OPEN_MAP_IMP_QUOTIENT_MAP", 9741 ``!f:real->real s. f continuous_on s /\ 9742 (!t. open_in (subtopology euclidean s) t 9743 ==> open_in (subtopology euclidean (IMAGE f s)) (IMAGE f t)) 9744 ==> !t. t SUBSET IMAGE f s 9745 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=> 9746 open_in (subtopology euclidean (IMAGE f s)) t)``, 9747 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 9748 [SUBGOAL_THEN 9749 ``(t = IMAGE f {x | x IN s /\ (f:real->real) x IN t})`` 9750 SUBST1_TAC THENL [ASM_SET_TAC[], ASM_SIMP_TAC std_ss []], 9751 UNDISCH_TAC ``f continuous_on s`` THEN GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_OPEN] THEN 9752 ASM_SIMP_TAC std_ss []]); 9753 9754val CLOSED_MAP_IMP_QUOTIENT_MAP = store_thm ("CLOSED_MAP_IMP_QUOTIENT_MAP", 9755 ``!f:real->real s. f continuous_on s /\ 9756 (!t. closed_in (subtopology euclidean s) t 9757 ==> closed_in (subtopology euclidean (IMAGE f s)) (IMAGE f t)) 9758 ==> !t. t SUBSET IMAGE f s 9759 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=> 9760 open_in (subtopology euclidean (IMAGE f s)) t)``, 9761 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 9762 [FIRST_X_ASSUM(MP_TAC o SPEC 9763 ``s DIFF {x | x IN s /\ (f:real->real) x IN t}``) THEN 9764 KNOW_TAC ``closed_in (subtopology euclidean (s :real -> bool)) 9765 (s DIFF {x | x IN s /\ (f :real -> real) x IN (t :real -> bool)})`` THENL 9766 [MATCH_MP_TAC CLOSED_IN_DIFF THEN 9767 ASM_SIMP_TAC std_ss [CLOSED_IN_SUBTOPOLOGY_REFL, 9768 TOPSPACE_EUCLIDEAN, SUBSET_UNIV], 9769 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 9770 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 9771 DISCH_THEN(MP_TAC o CONJUNCT2) THEN MATCH_MP_TAC EQ_IMPLIES THEN 9772 AP_TERM_TAC THEN ASM_SET_TAC[]], 9773 UNDISCH_TAC ``f continuous_on s`` THEN GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_OPEN] THEN 9774 ASM_SIMP_TAC std_ss []]); 9775 9776val CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP = store_thm ("CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP", 9777 ``!f:real->real g s t. 9778 f continuous_on s /\ IMAGE f s SUBSET t /\ 9779 g continuous_on t /\ IMAGE g t SUBSET s /\ 9780 (!y. y IN t ==> (f(g y) = y)) 9781 ==> (!u. u SUBSET t 9782 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 9783 open_in (subtopology euclidean t) u))``, 9784 REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN REPEAT STRIP_TAC THEN EQ_TAC THENL 9785 [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``(IMAGE (g:real->real) t) INTER 9786 {x | x IN s /\ (f:real->real) x IN u}``) THEN 9787 SUBGOAL_THEN ``open_in (subtopology euclidean (IMAGE (g:real->real) t)) 9788 (IMAGE g t INTER {x | x IN s /\ (f:real->real) x IN u})`` 9789 (fn th => REWRITE_TAC[th]) THENL 9790 [POP_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN]) THEN 9791 SIMP_TAC std_ss [OPEN_IN_OPEN] THEN ASM_SET_TAC[], 9792 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]], 9793 DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 9794 SUBGOAL_THEN ``IMAGE (f:real->real) s = t`` 9795 (fn th => ASM_REWRITE_TAC[th]) THEN 9796 ASM_SET_TAC[]]); 9797 9798val CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP = store_thm ("CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP", 9799 ``!f:real->real g s. 9800 f continuous_on s /\ g continuous_on (IMAGE f s) /\ 9801 (!x. x IN s ==> (g(f x) = x)) 9802 ==> (!u. u SUBSET (IMAGE f s) 9803 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 9804 open_in (subtopology euclidean (IMAGE f s)) u))``, 9805 REPEAT GEN_TAC THEN STRIP_TAC THEN 9806 MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN 9807 EXISTS_TAC ``g:real->real`` THEN 9808 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]); 9809 9810val QUOTIENT_MAP_OPEN_CLOSED = store_thm ("QUOTIENT_MAP_OPEN_CLOSED", 9811 ``!f:real->real s t. 9812 IMAGE f s SUBSET t 9813 ==> ((!u. u SUBSET t 9814 ==> (open_in (subtopology euclidean s) 9815 {x | x IN s /\ f x IN u} <=> 9816 open_in (subtopology euclidean t) u)) <=> 9817 (!u. u SUBSET t 9818 ==> (closed_in (subtopology euclidean s) 9819 {x | x IN s /\ f x IN u} <=> 9820 closed_in (subtopology euclidean t) u)))``, 9821 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 9822 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN 9823 X_GEN_TAC ``u:real->bool`` THEN 9824 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN 9825 ASM_SIMP_TAC std_ss [SET_RULE ``u SUBSET t ==> (t DIFF (t DIFF u) = u)``] THEN 9826 REWRITE_TAC [DIFF_SUBSET] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN 9827 SIMP_TAC std_ss [SUBSET_RESTRICT] THEN AP_TERM_TAC THEN ASM_SET_TAC[]); 9828 9829val CONTINUOUS_ON_COMPOSE_QUOTIENT = store_thm ("CONTINUOUS_ON_COMPOSE_QUOTIENT", 9830 ``!f:real->real g:real->real s t u. 9831 IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\ 9832 (!v. v SUBSET t 9833 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=> 9834 open_in (subtopology euclidean t) v)) /\ 9835 (g o f) continuous_on s 9836 ==> g continuous_on t``, 9837 REPEAT GEN_TAC THEN 9838 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 9839 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 9840 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 9841 FIRST_ASSUM(fn th => REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THEN 9842 SUBGOAL_THEN 9843 ``IMAGE ((g:real->real) o (f:real->real)) s SUBSET u`` 9844 (fn th => REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THENL 9845 [REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[], DISCH_TAC] THEN 9846 X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN 9847 FIRST_X_ASSUM(MP_TAC o SPEC ``v:real->bool``) THEN 9848 ASM_REWRITE_TAC[o_THM] THEN DISCH_TAC THEN 9849 FIRST_X_ASSUM(MP_TAC o SPEC ``{x | x IN t /\ (g:real->real) x IN v}``) THEN 9850 ASM_SIMP_TAC std_ss [SUBSET_RESTRICT] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN 9851 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] 9852 ``open_in top s ==> (s = t) ==> open_in top t``)) THEN 9853 ASM_SET_TAC[]); 9854 9855val FUNCTION_FACTORS_LEFT_GEN = store_thm ("FUNCTION_FACTORS_LEFT_GEN", 9856 ``!P f g. (!x y. P x /\ P y /\ (g x = g y) ==> (f x = f y)) <=> 9857 (?h. !x. P x ==> (f(x) = h(g x)))``, 9858 ONCE_REWRITE_TAC[MESON[] 9859 ``(!x. P x ==> (f(x) = g(k x))) <=> (!y x. P x /\ (y = k x) ==> (f x = g y))``] THEN 9860 SIMP_TAC std_ss [GSYM SKOLEM_THM] THEN MESON_TAC[]); 9861 9862val LIFT_TO_QUOTIENT_SPACE = store_thm ("LIFT_TO_QUOTIENT_SPACE", 9863 ``!f:real->real h:real->real s t u. 9864 (IMAGE f s = t) /\ (!v. v SUBSET t 9865 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=> 9866 open_in (subtopology euclidean t) v)) /\ 9867 h continuous_on s /\ (IMAGE h s = u) /\ 9868 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (h x = h y)) 9869 ==> ?g. g continuous_on t /\ (IMAGE g t = u) /\ 9870 !x. x IN s ==> (h(x) = g(f x))``, 9871 REPEAT GEN_TAC THEN 9872 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 9873 SIMP_TAC std_ss [FUNCTION_FACTORS_LEFT_GEN] THEN 9874 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN 9875 EXISTS_TAC ``g:real->real`` THEN 9876 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 9877 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE_QUOTIENT THEN MAP_EVERY EXISTS_TAC 9878 [``f:real->real``, ``s:real->bool``, ``u:real->bool``] THEN 9879 ASM_SIMP_TAC std_ss [SUBSET_REFL] THEN CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 9880 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] 9881 CONTINUOUS_ON_EQ)) THEN ASM_SIMP_TAC std_ss [o_THM]); 9882 9883val QUOTIENT_MAP_COMPOSE = store_thm ("QUOTIENT_MAP_COMPOSE", 9884 ``!f:real->real g:real->real s t u. 9885 IMAGE f s SUBSET t /\ 9886 (!v. v SUBSET t 9887 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=> 9888 open_in (subtopology euclidean t) v)) /\ 9889 (!v. v SUBSET u 9890 ==> (open_in (subtopology euclidean t) {x | x IN t /\ g x IN v} <=> 9891 open_in (subtopology euclidean u) v)) 9892 ==> !v. v SUBSET u 9893 ==> (open_in (subtopology euclidean s) 9894 {x | x IN s /\ (g o f) x IN v} <=> 9895 open_in (subtopology euclidean u) v)``, 9896 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [o_THM] THEN 9897 SUBGOAL_THEN 9898 ``{x | x IN s /\ (g:real->real) ((f:real->real) x) IN v} = 9899 {x | x IN s /\ f x IN {x | x IN t /\ g x IN v}}`` 9900 SUBST1_TAC THENL [ASM_SET_TAC[], ASM_SIMP_TAC std_ss [SUBSET_RESTRICT]]); 9901 9902val QUOTIENT_MAP_FROM_COMPOSITION = store_thm ("QUOTIENT_MAP_FROM_COMPOSITION", 9903 ``!f:real->real g:real->real s t u. 9904 f continuous_on s /\ IMAGE f s SUBSET t /\ 9905 g continuous_on t /\ IMAGE g t SUBSET u /\ 9906 (!v. v SUBSET u 9907 ==> (open_in (subtopology euclidean s) 9908 {x | x IN s /\ (g o f) x IN v} <=> 9909 open_in (subtopology euclidean u) v)) 9910 ==> !v. v SUBSET u 9911 ==> (open_in (subtopology euclidean t) 9912 {x | x IN t /\ g x IN v} <=> 9913 open_in (subtopology euclidean u) v)``, 9914 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL 9915 [FIRST_X_ASSUM(MP_TAC o SPEC ``v:real->bool``) THEN 9916 ASM_SIMP_TAC std_ss [o_THM] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN 9917 SUBGOAL_THEN 9918 ``{x | x IN s /\ (g:real->real) ((f:real->real) x) IN v} = 9919 {x | x IN s /\ f x IN {x | x IN t /\ g x IN v}}`` 9920 SUBST1_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 9921 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN 9922 EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[], 9923 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN 9924 EXISTS_TAC ``u:real->bool`` THEN ASM_REWRITE_TAC[]]); 9925 9926val QUOTIENT_MAP_FROM_SUBSET = store_thm ("QUOTIENT_MAP_FROM_SUBSET", 9927 ``!f:real->real s t u. 9928 f continuous_on t /\ IMAGE f t SUBSET u /\ 9929 s SUBSET t /\ (IMAGE f s = u) /\ 9930 (!v. v SUBSET u 9931 ==> (open_in (subtopology euclidean s) 9932 {x | x IN s /\ f x IN v} <=> 9933 open_in (subtopology euclidean u) v)) 9934 ==> !v. v SUBSET u 9935 ==> (open_in (subtopology euclidean t) 9936 {x | x IN t /\ f x IN v} <=> 9937 open_in (subtopology euclidean u) v)``, 9938 REPEAT GEN_TAC THEN STRIP_TAC THEN 9939 MATCH_MP_TAC QUOTIENT_MAP_FROM_COMPOSITION THEN 9940 MAP_EVERY EXISTS_TAC [``\x:real. x``, ``s:real->bool``] THEN 9941 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ID, IMAGE_ID, o_THM]); 9942 9943val QUOTIENT_MAP_RESTRICT = store_thm ("QUOTIENT_MAP_RESTRICT", 9944 ``!f:real->real s t c. 9945 IMAGE f s SUBSET t /\ 9946 (!u. u SUBSET t 9947 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 9948 open_in (subtopology euclidean t) u)) /\ 9949 (open_in (subtopology euclidean t) c \/ 9950 closed_in (subtopology euclidean t) c) 9951 ==> !u. u SUBSET c 9952 ==> (open_in (subtopology euclidean {x | x IN s /\ f x IN c}) 9953 {x | x IN {x | x IN s /\ f x IN c} /\ f x IN u} <=> 9954 open_in (subtopology euclidean c) u)``, 9955 REPEAT GEN_TAC THEN 9956 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 9957 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 9958 DISCH_THEN(fn th => MP_TAC th THEN MP_TAC (MATCH_MP 9959 (REWRITE_RULE[IMP_CONJ_ALT] QUOTIENT_MAP_IMP_CONTINUOUS_OPEN) th)) THEN 9960 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 9961 SUBGOAL_THEN ``IMAGE (f:real->real) {x | x IN s /\ f x IN c} SUBSET c`` 9962 ASSUME_TAC THENL [SET_TAC[], ALL_TAC] THEN 9963 FIRST_X_ASSUM DISJ_CASES_TAC THENL 9964 [FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET), 9965 ASM_SIMP_TAC std_ss [QUOTIENT_MAP_OPEN_CLOSED] THEN 9966 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET)] THEN 9967 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `u:real->bool`) THEN 9968 DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN 9969 (KNOW_TAC ``(u:real->bool) SUBSET t`` THENL 9970 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []]) THEN 9971 (MATCH_MP_TAC EQ_IMPLIES THEN BINOP_TAC THENL 9972 [MATCH_MP_TAC(MESON[] ``(t = s) /\ (P s <=> Q s) ==> (P s <=> Q t)``) THEN 9973 CONJ_TAC THENL [ASM_SET_TAC[], SIMP_TAC std_ss [GSPECIFICATION]], ALL_TAC]) THEN 9974 (EQ_TAC THENL 9975 [MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] OPEN_IN_SUBSET_TRANS) ORELSE 9976 MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] CLOSED_IN_SUBSET_TRANS), 9977 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] OPEN_IN_TRANS) ORELSE 9978 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CLOSED_IN_TRANS)]) THEN 9979 (MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN ORELSE 9980 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN ORELSE ASM_SIMP_TAC std_ss []) THEN 9981 ASM_SET_TAC[]); 9982 9983val CONNECTED_MONOTONE_QUOTIENT_PREIMAGE = store_thm ("CONNECTED_MONOTONE_QUOTIENT_PREIMAGE", 9984 ``!f:real->real s t. 9985 f continuous_on s /\ (IMAGE f s = t) /\ 9986 (!u. u SUBSET t 9987 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 9988 open_in (subtopology euclidean t) u)) /\ 9989 (!y. y IN t ==> connected {x | x IN s /\ (f x = y)}) /\ 9990 connected t ==> connected s``, 9991 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [connected, NOT_EXISTS_THM] THEN 9992 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN CCONTR_TAC THEN 9993 FULL_SIMP_TAC std_ss [] THEN UNDISCH_TAC ``connected(t:real->bool)`` THEN 9994 SIMP_TAC std_ss [CONNECTED_OPEN_IN] THEN 9995 MAP_EVERY EXISTS_TAC 9996 [``IMAGE (f:real->real) (s INTER u)``, 9997 ``IMAGE (f:real->real) (s INTER v)``] THEN 9998 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY] THEN 9999 SUBGOAL_THEN 10000 ``IMAGE (f:real->real) (s INTER u) INTER IMAGE f (s INTER v) = {}`` 10001 ASSUME_TAC THENL 10002 [REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN 10003 X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 10004 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN 10005 KNOW_TAC ``y IN t:real->bool`` THENL 10006 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN REWRITE_TAC[connected]] THEN 10007 MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN 10008 ASM_SET_TAC[], ALL_TAC] THEN 10009 ONCE_REWRITE_TAC[CONJ_ASSOC] THEN 10010 CONJ_TAC THENL [CONJ_TAC, ASM_SET_TAC[]] THEN 10011 FIRST_X_ASSUM(fn th => 10012 W(MP_TAC o PART_MATCH (rand o rand) th o snd)) THENL 10013 [KNOW_TAC ``IMAGE (f:real->real) (s INTER u) SUBSET t:real->bool`` THENL 10014 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_THEN(SUBST1_TAC o SYM)], 10015 KNOW_TAC ``IMAGE (f:real->real) (s INTER v) SUBSET t:real->bool`` THENL 10016 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_THEN(SUBST1_TAC o SYM)]] THEN 10017 MATCH_MP_TAC(MESON[] 10018 ``({x | x IN s /\ f x IN IMAGE f u} = u) /\ open_in top u 10019 ==> open_in top {x | x IN s /\ f x IN IMAGE f u}``) THEN 10020 ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER] THEN ASM_SET_TAC[]); 10021 10022val CONNECTED_MONOTONE_QUOTIENT_PREIMAGE_GEN = store_thm ("CONNECTED_MONOTONE_QUOTIENT_PREIMAGE_GEN", 10023 ``!f:real->real s t c. 10024 (IMAGE f s = t) /\ (!u. u SUBSET t 10025 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10026 open_in (subtopology euclidean t) u)) /\ 10027 (!y. y IN t ==> connected {x | x IN s /\ (f x = y)}) /\ 10028 (open_in (subtopology euclidean t) c \/ 10029 closed_in (subtopology euclidean t) c) /\ 10030 connected c ==> connected {x | x IN s /\ f x IN c}``, 10031 REPEAT GEN_TAC THEN 10032 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 10033 MATCH_MP_TAC(ONCE_REWRITE_RULE[CONJ_EQ_IMP] 10034 (REWRITE_RULE[CONJ_ASSOC] CONNECTED_MONOTONE_QUOTIENT_PREIMAGE)) THEN 10035 SUBGOAL_THEN ``(c:real->bool) SUBSET t`` ASSUME_TAC THENL 10036 [ASM_MESON_TAC[OPEN_IN_IMP_SUBSET, CLOSED_IN_IMP_SUBSET], ALL_TAC] THEN 10037 EXISTS_TAC ``f:real->real`` THEN REPEAT CONJ_TAC THENL 10038 [FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] 10039 QUOTIENT_MAP_IMP_CONTINUOUS_OPEN)) THEN 10040 ASM_REWRITE_TAC[SUBSET_REFL] THEN 10041 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN 10042 SIMP_TAC std_ss [SUBSET_RESTRICT], 10043 ASM_SET_TAC[], 10044 MATCH_MP_TAC QUOTIENT_MAP_RESTRICT THEN 10045 METIS_TAC[SUBSET_REFL], 10046 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 10047 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN 10048 KNOW_TAC ``y IN t:real->bool`` THENL 10049 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN MATCH_MP_TAC EQ_IMPLIES] THEN 10050 AP_TERM_TAC THEN ASM_SET_TAC[]]); 10051 10052(* ------------------------------------------------------------------------- *) 10053(* More properties of open and closed maps. *) 10054(* ------------------------------------------------------------------------- *) 10055 10056val CLOSED_MAP_CLOSURES = store_thm ("CLOSED_MAP_CLOSURES", 10057 ``!f:real->real. 10058 (!s. closed s ==> closed(IMAGE f s)) <=> 10059 (!s. closure(IMAGE f s) SUBSET IMAGE f (closure s))``, 10060 GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 10061 [MATCH_MP_TAC CLOSURE_MINIMAL THEN 10062 ASM_SIMP_TAC std_ss [CLOSED_CLOSURE, CLOSURE_SUBSET, IMAGE_SUBSET], 10063 REWRITE_TAC[GSYM CLOSURE_SUBSET_EQ] THEN ASM_MESON_TAC[CLOSURE_CLOSED]]); 10064 10065val OPEN_MAP_INTERIORS = store_thm ("OPEN_MAP_INTERIORS", 10066 ``!f:real->real. 10067 (!s. open s ==> open(IMAGE f s)) <=> 10068 (!s. IMAGE f (interior s) SUBSET interior(IMAGE f s))``, 10069 GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 10070 [MATCH_MP_TAC INTERIOR_MAXIMAL THEN 10071 ASM_SIMP_TAC std_ss [OPEN_INTERIOR, INTERIOR_SUBSET, IMAGE_SUBSET], 10072 REWRITE_TAC[GSYM SUBSET_INTERIOR_EQ] THEN ASM_MESON_TAC[INTERIOR_OPEN]]); 10073 10074val OPEN_MAP_RESTRICT = store_thm ("OPEN_MAP_RESTRICT", 10075 ``!f:real->real s t t'. 10076 (!u. open_in (subtopology euclidean s) u 10077 ==> open_in (subtopology euclidean t) (IMAGE f u)) /\ 10078 t' SUBSET t 10079 ==> !u. open_in (subtopology euclidean {x | x IN s /\ f x IN t'}) u 10080 ==> open_in (subtopology euclidean t') (IMAGE f u)``, 10081 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN 10082 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, CONJ_EQ_IMP] THEN 10083 REPEAT DISCH_TAC THEN X_GEN_TAC ``c:real->bool`` THEN 10084 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN 10085ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]); 10086 10087val CLOSED_MAP_RESTRICT = store_thm ("CLOSED_MAP_RESTRICT", 10088 ``!f:real->real s t t'. 10089 (!u. closed_in (subtopology euclidean s) u 10090 ==> closed_in (subtopology euclidean t) (IMAGE f u)) /\ 10091 t' SUBSET t 10092 ==> !u. closed_in (subtopology euclidean {x | x IN s /\ f x IN t'}) u 10093 ==> closed_in (subtopology euclidean t') (IMAGE f u)``, 10094 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN 10095 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, CONJ_EQ_IMP] THEN 10096 REPEAT DISCH_TAC THEN X_GEN_TAC ``c:real->bool`` THEN 10097 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN 10098 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]); 10099 10100val QUOTIENT_MAP_OPEN_MAP_EQ = store_thm ("QUOTIENT_MAP_OPEN_MAP_EQ", 10101 ``!f:real->real s t. 10102 IMAGE f s SUBSET t /\ 10103 (!u. u SUBSET t 10104 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10105 open_in (subtopology euclidean t) u)) 10106 ==> ((!k. open_in (subtopology euclidean s) k 10107 ==> open_in (subtopology euclidean t) (IMAGE f k)) <=> 10108 (!k. open_in (subtopology euclidean s) k 10109 ==> open_in (subtopology euclidean s) 10110 {x | x IN s /\ f x IN IMAGE f k}))``, 10111 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN 10112 X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN 10113 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 10114 UNDISCH_TAC ``!u. u SUBSET t ==> 10115 (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10116 open_in (subtopology euclidean t) u)`` THEN 10117 DISCH_TAC THEN 10118 FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (f:real->real) k``) THEN 10119 ASM_SIMP_TAC std_ss [IMAGE_SUBSET] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_SET_TAC[]); 10120 10121val QUOTIENT_MAP_CLOSED_MAP_EQ = store_thm ("QUOTIENT_MAP_CLOSED_MAP_EQ", 10122 ``!f:real->real s t. 10123 IMAGE f s SUBSET t /\ 10124 (!u. u SUBSET t 10125 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10126 open_in (subtopology euclidean t) u)) 10127 ==> ((!k. closed_in (subtopology euclidean s) k 10128 ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=> 10129 (!k. closed_in (subtopology euclidean s) k 10130 ==> closed_in (subtopology euclidean s) 10131 {x | x IN s /\ f x IN IMAGE f k}))``, 10132 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 10133 ASM_SIMP_TAC std_ss [QUOTIENT_MAP_OPEN_CLOSED] THEN 10134 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN 10135 X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN 10136 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 10137 UNDISCH_TAC ``!u. u SUBSET t ==> 10138 (closed_in (subtopology euclidean s) 10139 {x | x IN s /\ f x IN u} <=> 10140 closed_in (subtopology euclidean t) u)`` THEN 10141 DISCH_TAC THEN 10142 FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (f:real->real) k``) THEN 10143 ASM_SIMP_TAC std_ss [IMAGE_SUBSET] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_SET_TAC[]); 10144 10145val CLOSED_MAP_IMP_OPEN_MAP = store_thm ("CLOSED_MAP_IMP_OPEN_MAP", 10146 ``!f:real->real s t. 10147 (IMAGE f s = t) /\ 10148 (!u. closed_in (subtopology euclidean s) u 10149 ==> closed_in (subtopology euclidean t) (IMAGE f u)) /\ 10150 (!u. open_in (subtopology euclidean s) u 10151 ==> open_in (subtopology euclidean s) 10152 {x | x IN s /\ f x IN IMAGE f u}) 10153 ==> (!u. open_in (subtopology euclidean s) u 10154 ==> open_in (subtopology euclidean t) (IMAGE f u))``, 10155 REPEAT STRIP_TAC THEN 10156 SUBGOAL_THEN 10157 ``IMAGE (f:real->real) u = 10158 t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})`` 10159 SUBST1_TAC THENL 10160 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM_SET_TAC[], 10161 MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN 10162 FIRST_X_ASSUM MATCH_MP_TAC THEN 10163 MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN 10164 ASM_SIMP_TAC std_ss [CLOSED_IN_REFL]]); 10165 10166val OPEN_MAP_IMP_CLOSED_MAP = store_thm ("OPEN_MAP_IMP_CLOSED_MAP", 10167 ``!f:real->real s t. 10168 (IMAGE f s = t) /\ 10169 (!u. open_in (subtopology euclidean s) u 10170 ==> open_in (subtopology euclidean t) (IMAGE f u)) /\ 10171 (!u. closed_in (subtopology euclidean s) u 10172 ==> closed_in (subtopology euclidean s) 10173 {x | x IN s /\ f x IN IMAGE f u}) 10174 ==> (!u. closed_in (subtopology euclidean s) u 10175 ==> closed_in (subtopology euclidean t) (IMAGE f u))``, 10176 REPEAT STRIP_TAC THEN 10177 SUBGOAL_THEN 10178 ``IMAGE (f:real->real) u = 10179 t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})`` 10180 SUBST1_TAC THENL 10181 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM_SET_TAC[], 10182 MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN 10183 FIRST_X_ASSUM MATCH_MP_TAC THEN 10184 MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN 10185 ASM_SIMP_TAC std_ss [OPEN_IN_REFL]]); 10186 10187val OPEN_MAP_FROM_COMPOSITION_SURJECTIVE = store_thm ("OPEN_MAP_FROM_COMPOSITION_SURJECTIVE", 10188 ``!f:real->real g:real->real s t u. 10189 f continuous_on s /\ (IMAGE f s = t) /\ IMAGE g t SUBSET u /\ 10190 (!k. open_in (subtopology euclidean s) k 10191 ==> open_in (subtopology euclidean u) (IMAGE (g o f) k)) 10192 ==> (!k. open_in (subtopology euclidean t) k 10193 ==> open_in (subtopology euclidean u) (IMAGE g k))``, 10194 REPEAT STRIP_TAC THEN SUBGOAL_THEN 10195 ``IMAGE g k = IMAGE ((g:real->real) o (f:real->real)) 10196 {x | x IN s /\ f(x) IN k}`` SUBST1_TAC THENL 10197 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 10198 REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[], 10199 FIRST_X_ASSUM MATCH_MP_TAC THEN 10200 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN 10201 EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[SUBSET_REFL]]); 10202 10203val CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE = store_thm ("CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE", 10204 ``!f:real->real g:real->real s t u. 10205 f continuous_on s /\ (IMAGE f s = t) /\ IMAGE g t SUBSET u /\ 10206 (!k. closed_in (subtopology euclidean s) k 10207 ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k)) 10208 ==> (!k. closed_in (subtopology euclidean t) k 10209 ==> closed_in (subtopology euclidean u) (IMAGE g k))``, 10210 REPEAT STRIP_TAC THEN SUBGOAL_THEN 10211 ``IMAGE g k = IMAGE ((g:real->real) o (f:real->real)) 10212 {x | x IN s /\ f(x) IN k}`` SUBST1_TAC THENL 10213 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 10214 REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[], 10215 FIRST_X_ASSUM MATCH_MP_TAC THEN 10216 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN 10217 EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[SUBSET_REFL]]); 10218 10219val OPEN_MAP_FROM_COMPOSITION_INJECTIVE = store_thm ("OPEN_MAP_FROM_COMPOSITION_INJECTIVE", 10220 ``!f:real->real g:real->real s t u. 10221 IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\ 10222 g continuous_on t /\ (!x y. x IN t /\ y IN t /\ (g x = g y) ==> (x = y)) /\ 10223 (!k. open_in (subtopology euclidean s) k 10224 ==> open_in (subtopology euclidean u) (IMAGE (g o f) k)) 10225 ==> (!k. open_in (subtopology euclidean s) k 10226 ==> open_in (subtopology euclidean t) (IMAGE f k))``, 10227 REPEAT STRIP_TAC THEN SUBGOAL_THEN 10228 ``IMAGE f k = {x | x IN t /\ 10229 g(x) IN IMAGE ((g:real->real) o (f:real->real)) k}`` 10230 SUBST1_TAC THENL 10231 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 10232 REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[], 10233 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN 10234 EXISTS_TAC ``u:real->bool`` THEN ASM_SIMP_TAC std_ss []]); 10235 10236val CLOSED_MAP_FROM_COMPOSITION_INJECTIVE = store_thm ("CLOSED_MAP_FROM_COMPOSITION_INJECTIVE", 10237 ``!f:real->real g:real->real s t u. 10238 IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\ 10239 g continuous_on t /\ (!x y. x IN t /\ y IN t /\ (g x = g y) ==> (x = y)) /\ 10240 (!k. closed_in (subtopology euclidean s) k 10241 ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k)) 10242 ==> (!k. closed_in (subtopology euclidean s) k 10243 ==> closed_in (subtopology euclidean t) (IMAGE f k))``, 10244 REPEAT STRIP_TAC THEN SUBGOAL_THEN 10245 ``IMAGE f k = {x | x IN t /\ 10246 g(x) IN IMAGE ((g:real->real) o (f:real->real)) k}`` 10247 SUBST1_TAC THENL 10248 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 10249 REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[], 10250 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN 10251 EXISTS_TAC ``u:real->bool`` THEN ASM_SIMP_TAC std_ss []]); 10252 10253val OPEN_MAP_CLOSED_SUPERSET_PREIMAGE = store_thm ("OPEN_MAP_CLOSED_SUPERSET_PREIMAGE", 10254 ``!f:real->real s t u w. 10255 (!k. open_in (subtopology euclidean s) k 10256 ==> open_in (subtopology euclidean t) (IMAGE f k)) /\ 10257 closed_in (subtopology euclidean s) u /\ 10258 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u 10259 ==> ?v. closed_in (subtopology euclidean t) v /\ 10260 w SUBSET v /\ 10261 {x | x IN s /\ f(x) IN v} SUBSET u``, 10262 REPEAT STRIP_TAC THEN 10263 EXISTS_TAC ``t DIFF IMAGE (f:real->real) (s DIFF u)`` THEN 10264 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 10265 MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN 10266 FIRST_X_ASSUM MATCH_MP_TAC THEN 10267 ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL]); 10268 10269val OPEN_MAP_CLOSED_SUPERSET_PREIMAGE_EQ = store_thm ("OPEN_MAP_CLOSED_SUPERSET_PREIMAGE_EQ", 10270 ``!f:real->real s t. 10271 IMAGE f s SUBSET t 10272 ==> ((!k. open_in (subtopology euclidean s) k 10273 ==> open_in (subtopology euclidean t) (IMAGE f k)) <=> 10274 (!u w. closed_in (subtopology euclidean s) u /\ 10275 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u 10276 ==> ?v. closed_in (subtopology euclidean t) v /\ 10277 w SUBSET v /\ {x | x IN s /\ f(x) IN v} SUBSET u))``, 10278 REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN 10279 ASM_SIMP_TAC std_ss [OPEN_MAP_CLOSED_SUPERSET_PREIMAGE] THEN 10280 FIRST_X_ASSUM(MP_TAC o SPECL 10281 [``s DIFF k:real->bool``, ``t DIFF IMAGE (f:real->real) k``]) THEN 10282 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 10283 ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL] THEN 10284 KNOW_TAC ``t DIFF IMAGE (f:real->real) k SUBSET t /\ 10285 {x | x IN s /\ f x IN t DIFF IMAGE (f:real->real) k} SUBSET s DIFF k`` THENL 10286 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 10287 DISCH_THEN(X_CHOOSE_THEN ``v:real->bool`` STRIP_ASSUME_TAC) THEN 10288 SUBGOAL_THEN ``IMAGE (f:real->real) k = t DIFF v`` SUBST1_TAC THENL 10289 [ASM_SET_TAC[], ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL]]); 10290 10291val CLOSED_MAP_OPEN_SUPERSET_PREIMAGE = store_thm ("CLOSED_MAP_OPEN_SUPERSET_PREIMAGE", 10292 ``!f:real->real s t u w. 10293 (!k. closed_in (subtopology euclidean s) k 10294 ==> closed_in (subtopology euclidean t) (IMAGE f k)) /\ 10295 open_in (subtopology euclidean s) u /\ 10296 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u 10297 ==> ?v. open_in (subtopology euclidean t) v /\ 10298 w SUBSET v /\ 10299 {x | x IN s /\ f(x) IN v} SUBSET u``, 10300 REPEAT STRIP_TAC THEN 10301 EXISTS_TAC ``t DIFF IMAGE (f:real->real) (s DIFF u)`` THEN 10302 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 10303 MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN 10304 FIRST_X_ASSUM MATCH_MP_TAC THEN 10305 ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL]); 10306 10307val CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_EQ = store_thm ("CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_EQ", 10308 ``!f:real->real s t. 10309 IMAGE f s SUBSET t 10310 ==> ((!k. closed_in (subtopology euclidean s) k 10311 ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=> 10312 (!u w. open_in (subtopology euclidean s) u /\ 10313 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u 10314 ==> ?v. open_in (subtopology euclidean t) v /\ 10315 w SUBSET v /\ {x | x IN s /\ f(x) IN v} SUBSET u))``, 10316 REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN 10317 ASM_SIMP_TAC std_ss [CLOSED_MAP_OPEN_SUPERSET_PREIMAGE] THEN 10318 FIRST_X_ASSUM(MP_TAC o SPECL 10319 [``s DIFF k:real->bool``, ``t DIFF IMAGE (f:real->real) k``]) THEN 10320 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 10321 ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL] THEN 10322 KNOW_TAC ``t DIFF IMAGE (f:real->real) k SUBSET t /\ 10323 {x | x IN s /\ f x IN t DIFF IMAGE (f:real->real) k} SUBSET s DIFF k`` THENL 10324 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 10325 DISCH_THEN(X_CHOOSE_THEN ``v:real->bool`` STRIP_ASSUME_TAC) THEN 10326 SUBGOAL_THEN ``IMAGE (f:real->real) k = t DIFF v`` SUBST1_TAC THENL 10327 [ASM_SET_TAC[], ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL]]); 10328 10329val BIGUNION_GSPEC = store_thm ("BIGUNION_GSPEC", 10330 ``(!P f. BIGUNION {f x | P x} = {a | ?x. P x /\ a IN (f x)}) /\ 10331 (!P f. BIGUNION {f x y | P x y} = {a | ?x y. P x y /\ a IN (f x y)}) /\ 10332 (!P f. BIGUNION {f x y z | P x y z} = 10333 {a | ?x y z. P x y z /\ a IN (f x y z)})``, 10334 REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 10335 SIMP_TAC std_ss [IN_BIGUNION, GSPECIFICATION, EXISTS_PROD] THEN MESON_TAC[]); 10336 10337val CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_POINT = store_thm ("CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_POINT", 10338 ``!f:real->real s t. 10339 IMAGE f s SUBSET t 10340 ==> ((!k. closed_in (subtopology euclidean s) k 10341 ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=> 10342 (!u y. open_in (subtopology euclidean s) u /\ 10343 y IN t /\ {x | x IN s /\ (f(x) = y)} SUBSET u 10344 ==> ?v. open_in (subtopology euclidean t) v /\ 10345 y IN v /\ {x | x IN s /\ f(x) IN v} SUBSET u))``, 10346 REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_EQ] THEN 10347 EQ_TAC THEN DISCH_TAC THENL 10348 [MAP_EVERY X_GEN_TAC [``u:real->bool``, ``y:real``] THEN 10349 STRIP_TAC THEN 10350 FIRST_X_ASSUM(MP_TAC o SPECL [``u:real->bool``, ``{y:real}``]) THEN 10351 ASM_REWRITE_TAC[SING_SUBSET, IN_SING], 10352 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``w:real->bool``] THEN 10353 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN 10354 KNOW_TAC ``(!y. ?v. open_in (subtopology euclidean s) u /\ 10355 y IN t /\ {x | x IN s /\ (f x = y)} SUBSET u 10356 ==> open_in (subtopology euclidean t) v /\ 10357 y IN v /\ {x | x IN s /\ f x IN v} SUBSET u) 10358 ==> (?v. open_in (subtopology euclidean t) v /\ 10359 w SUBSET v /\ {x | x IN s /\ f x IN v} SUBSET u)`` THENL 10360 [ALL_TAC, METIS_TAC [GSYM RIGHT_EXISTS_IMP_THM]] THEN 10361 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 10362 X_GEN_TAC ``vv:real->real->bool`` THEN DISCH_TAC THEN 10363 EXISTS_TAC ``BIGUNION {(vv:real->real->bool) y | y IN w}`` THEN 10364 CONJ_TAC THENL 10365 [MATCH_MP_TAC OPEN_IN_BIGUNION THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN 10366 ASM_SET_TAC[], 10367 SIMP_TAC std_ss [BIGUNION_GSPEC] THEN 10368 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 10369 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, GSYM RIGHT_EXISTS_AND_THM, 10370 LEFT_IMP_EXISTS_THM] THEN 10371 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 10372 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN ASM_SET_TAC[]]]); 10373 10374val CONNECTED_OPEN_MONOTONE_PREIMAGE = store_thm ("CONNECTED_OPEN_MONOTONE_PREIMAGE", 10375 ``!f:real->real s t. 10376 f continuous_on s /\ (IMAGE f s = t) /\ 10377 (!c. open_in (subtopology euclidean s) c 10378 ==> open_in (subtopology euclidean t) (IMAGE f c)) /\ 10379 (!y. y IN t ==> connected {x | x IN s /\ (f x = y)}) 10380 ==> !c. connected c /\ c SUBSET t 10381 ==> connected {x | x IN s /\ f x IN c}``, 10382 REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``c:real->bool`` o MATCH_MP 10383 (ONCE_REWRITE_RULE[CONJ_EQ_IMP] OPEN_MAP_RESTRICT)) THEN 10384 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC(ISPECL 10385 [``f:real->real``, ``{x | x IN s /\ (f:real->real) x IN c}``] 10386 OPEN_MAP_IMP_QUOTIENT_MAP) THEN 10387 SUBGOAL_THEN ``IMAGE f {x | x IN s /\ (f:real->real) x IN c} = c`` 10388 ASSUME_TAC THENL [ASM_SET_TAC[], ASM_REWRITE_TAC[]] THEN 10389 KNOW_TAC ``(f:real->real) continuous_on {x | x IN s /\ f x IN c}`` THENL 10390 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 10391 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[], 10392 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN 10393 MATCH_MP_TAC CONNECTED_MONOTONE_QUOTIENT_PREIMAGE THEN 10394 MAP_EVERY EXISTS_TAC [``f:real->real``, ``c:real->bool``] THEN 10395 ASM_REWRITE_TAC[] THEN 10396 SIMP_TAC std_ss [SET_RULE 10397 ``y IN c ==> ({x | x IN {x | x IN s /\ f x IN c} /\ (f x = y)} = 10398 {x | x IN s /\ (f x = y)})``] THEN 10399 ASM_SET_TAC[]); 10400 10401val CONNECTED_CLOSED_MONOTONE_PREIMAGE = store_thm ("CONNECTED_CLOSED_MONOTONE_PREIMAGE", 10402 ``!f:real->real s t. 10403 f continuous_on s /\ (IMAGE f s = t) /\ 10404 (!c. closed_in (subtopology euclidean s) c 10405 ==> closed_in (subtopology euclidean t) (IMAGE f c)) /\ 10406 (!y. y IN t ==> connected {x | x IN s /\ (f x = y)}) 10407 ==> !c. connected c /\ c SUBSET t 10408 ==> connected {x | x IN s /\ f x IN c}``, 10409 REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``c:real->bool`` o MATCH_MP 10410 (ONCE_REWRITE_RULE[CONJ_EQ_IMP] CLOSED_MAP_RESTRICT)) THEN 10411 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC(ISPECL 10412 [``f:real->real``, ``{x | x IN s /\ (f:real->real) x IN c}``] 10413 CLOSED_MAP_IMP_QUOTIENT_MAP) THEN 10414 SUBGOAL_THEN ``IMAGE f {x | x IN s /\ (f:real->real) x IN c} = c`` 10415 ASSUME_TAC THENL [ASM_SET_TAC[], ASM_REWRITE_TAC[]] THEN 10416 KNOW_TAC ``(f:real->real) continuous_on {x | x IN s /\ f x IN c}`` THENL 10417 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 10418 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[], 10419 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN 10420 MATCH_MP_TAC CONNECTED_MONOTONE_QUOTIENT_PREIMAGE THEN 10421 MAP_EVERY EXISTS_TAC [``f:real->real``, ``c:real->bool``] THEN 10422 ASM_REWRITE_TAC[] THEN 10423 SIMP_TAC std_ss [SET_RULE 10424 ``y IN c ==> ({x | x IN {x | x IN s /\ f x IN c} /\ (f x = y)} = 10425 {x | x IN s /\ (f x = y)})``] THEN 10426 ASM_SET_TAC[]); 10427 10428(* ------------------------------------------------------------------------- *) 10429(* Proper maps, including projections out of compact sets. *) 10430(* ------------------------------------------------------------------------- *) 10431 10432val PROPER_MAP = store_thm ("PROPER_MAP", 10433 ``!f:real->real s t. 10434 IMAGE f s SUBSET t 10435 ==> ((!k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}) <=> 10436 (!k. closed_in (subtopology euclidean s) k 10437 ==> closed_in (subtopology euclidean t) (IMAGE f k)) /\ 10438 (!a. a IN t ==> compact {x | x IN s /\ (f x = a)}))``, 10439 REPEAT STRIP_TAC THEN EQ_TAC THENL 10440 [REPEAT STRIP_TAC THENL 10441 [ALL_TAC, 10442 ONCE_REWRITE_TAC[SET_RULE ``(x = a) <=> x IN {a}``] THEN 10443 FIRST_X_ASSUM MATCH_MP_TAC THEN 10444 ASM_REWRITE_TAC[SING_SUBSET, COMPACT_SING]] THEN 10445 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 10446 REWRITE_TAC[CLOSED_IN_LIMPT] THEN 10447 CONJ_TAC THENL [ASM_SET_TAC[], X_GEN_TAC ``y:real``] THEN 10448 REWRITE_TAC[LIMPT_SEQUENTIAL_INJ, IN_DELETE] THEN 10449 SIMP_TAC std_ss [IN_IMAGE, GSYM LEFT_EXISTS_AND_THM, SKOLEM_THM] THEN 10450 KNOW_TAC ``(?(x :num -> real) (f' :num -> real). 10451 ((!(n :num). 10452 ((f' n = (f :real -> real) (x n)) /\ 10453 x n IN (k :real -> bool)) /\ f' n <> (y :real)) /\ 10454 (!(m :num) (n :num). (f' m = f' n) <=> (m = n)) /\ 10455 ((f' --> y) sequentially :bool)) /\ y IN (t :real -> bool)) ==> 10456 ?(x :real). (y = f x) /\ x IN k`` THENL 10457 [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN 10458 SIMP_TAC std_ss [GSYM CONJ_ASSOC, FORALL_AND_THM] THEN 10459 SIMP_TAC std_ss [GSYM FUN_EQ_THM] THEN 10460 SIMP_TAC std_ss [UNWIND_THM2, FUN_EQ_THM] THEN 10461 DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN 10462 SUBGOAL_THEN 10463 ``~(BIGINTER {{a | a IN k /\ (f:real->real) a IN 10464 (y INSERT IMAGE (\i. f(x(n + i))) univ(:num))} | n IN univ(:num)} = {})`` 10465 MP_TAC THENL 10466 [MATCH_MP_TAC COMPACT_FIP THEN CONJ_TAC THENL 10467 [SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV] THEN X_GEN_TAC ``n:num`` THEN 10468 UNDISCH_TAC ``closed_in (subtopology euclidean s) k`` THEN DISCH_TAC THEN 10469 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [CLOSED_IN_CLOSED]) THEN 10470 DISCH_THEN(X_CHOOSE_THEN ``c:real->bool`` STRIP_ASSUME_TAC) THEN 10471 ONCE_REWRITE_TAC [METIS [] ``f a IN s <=> (\a. f a IN s) a``] THEN 10472 ASM_REWRITE_TAC[SET_RULE 10473 ``{x | x IN s INTER k /\ P x} = k INTER {x | x IN s /\ P x}``] THEN 10474 MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN 10475 BETA_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 10476 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 10477 MATCH_MP_TAC COMPACT_SEQUENCE_WITH_LIMIT THEN 10478 UNDISCH_TAC ``((\n. f ((x:num->real) n)) --> y) sequentially`` THEN DISCH_TAC THEN 10479 FIRST_ASSUM(MP_TAC o SPEC ``n:num`` o MATCH_MP SEQ_OFFSET) THEN 10480 BETA_TAC THEN GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [ADD_SYM] THEN 10481 SIMP_TAC std_ss [], 10482 SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_FINITE_SUBSET_IMAGE] THEN 10483 X_GEN_TAC ``i:num->bool`` THEN STRIP_TAC THEN 10484 UNDISCH_TAC ``FINITE (i:num->bool)`` THEN DISCH_TAC THEN 10485 FIRST_ASSUM(MP_TAC o ISPEC ``\n:num. n`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN 10486 SIMP_TAC std_ss [] THEN DISCH_THEN(X_CHOOSE_TAC ``m:num``) THEN 10487 SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, BIGINTER_IMAGE, GSPECIFICATION] THEN 10488 EXISTS_TAC ``(x:num->real) m`` THEN 10489 X_GEN_TAC ``p:num`` THEN DISCH_TAC THEN 10490 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 10491 REWRITE_TAC[IN_INSERT, IN_IMAGE, IN_UNIV] THEN DISJ2_TAC THEN 10492 EXISTS_TAC ``m - p:num`` THEN BETA_TAC THEN 10493 UNDISCH_TAC ``!x:num. x IN i ==> x <= m`` THEN DISCH_THEN (MP_TAC o SPEC ``p:num``) THEN 10494 ASM_REWRITE_TAC [] THEN ARITH_TAC], 10495 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN 10496 DISCH_THEN (X_CHOOSE_TAC ``x:real``) THEN EXISTS_TAC ``x:real`` THEN 10497 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [BIGINTER_GSPEC, GSPECIFICATION, IN_UNIV] THEN 10498 DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``0:num``) THEN 10499 SIMP_TAC std_ss [ADD_CLAUSES, IN_INSERT, IN_IMAGE, IN_UNIV] THEN 10500 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (DISJ_CASES_THEN MP_TAC)) THEN 10501 ASM_SIMP_TAC std_ss [] THEN DISCH_THEN(X_CHOOSE_TAC ``i:num``) THEN 10502 FIRST_X_ASSUM (MP_TAC o SPEC ``i + 1:num``) THEN 10503 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 10504 ASM_SIMP_TAC std_ss [IN_INSERT, IN_IMAGE, IN_UNIV] THEN ARITH_TAC], 10505 STRIP_TAC THEN X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN 10506 REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN 10507 X_GEN_TAC ``c:(real->bool)->bool`` THEN STRIP_TAC THEN 10508 SUBGOAL_THEN 10509 ``!a. a IN k 10510 ==> ?g. g SUBSET c /\ FINITE g /\ 10511 {x | x IN s /\ ((f:real->real) x = a)} SUBSET BIGUNION g`` 10512 MP_TAC THENL 10513 [X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN UNDISCH_THEN 10514 ``!a. a IN t ==> compact {x | x IN s /\ ((f:real->real) x = a)}`` 10515 (MP_TAC o SPEC ``a:real``) THEN 10516 KNOW_TAC ``(a :real) IN (t :real -> bool)`` THENL 10517 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 10518 POP_ASSUM K_TAC THEN REWRITE_TAC[COMPACT_EQ_HEINE_BOREL]] THEN 10519 DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_SET_TAC[], 10520 DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 10521 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 10522 X_GEN_TAC ``uu:real->(real->bool)->bool`` THEN DISCH_TAC] THEN 10523 SUBGOAL_THEN 10524 ``!a. a IN k ==> ?v. open v /\ a IN v /\ 10525 {x | x IN s /\ (f:real->real) x IN v} SUBSET BIGUNION(uu a)`` 10526 MP_TAC THENL 10527 [REPEAT STRIP_TAC THEN 10528 UNDISCH_THEN 10529 ``!k. closed_in (subtopology euclidean s) k 10530 ==> closed_in (subtopology euclidean t) (IMAGE (f:real->real) k)`` 10531 (MP_TAC o SPEC ``(s:real->bool) DIFF BIGUNION(uu(a:real))``) THEN 10532 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 10533 KNOW_TAC ``(s :real -> bool) DIFF 10534 BIGUNION ((uu :real -> (real -> bool) -> bool) (a :real)) SUBSET s /\ 10535 open_in (subtopology euclidean s) (s DIFF (s DIFF BIGUNION (uu a)))`` THENL 10536 [CONJ_TAC THENL [SET_TAC[], ALL_TAC] THEN 10537 REWRITE_TAC[SET_RULE ``s DIFF (s DIFF t) = s INTER t``] THEN 10538 MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN 10539 MATCH_MP_TAC OPEN_BIGUNION THEN ASM_SET_TAC[], 10540 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 10541 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 10542 REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN (X_CHOOSE_TAC ``v:real->bool``) THEN 10543 EXISTS_TAC ``v:real->bool`` THEN POP_ASSUM MP_TAC THEN 10544 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 10545 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC ``a:real``)) THEN 10546 ASM_REWRITE_TAC[] THEN 10547 KNOW_TAC ``a IN t:real->bool`` THENL [ASM_SET_TAC[], 10548 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN DISCH_TAC] THEN 10549 STRIP_TAC THEN ASM_SET_TAC[]], 10550 DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 10551 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 10552 X_GEN_TAC ``vv:real->(real->bool)`` THEN DISCH_TAC] THEN 10553 UNDISCH_TAC ``compact k`` THEN DISCH_TAC THEN 10554 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [COMPACT_EQ_HEINE_BOREL]) THEN 10555 DISCH_THEN(MP_TAC o SPEC ``IMAGE (vv:real->(real->bool)) k``) THEN 10556 KNOW_TAC ``(!(t :real -> bool). 10557 t IN IMAGE (vv :real -> real -> bool) (k :real -> bool) ==> 10558 (open t :bool)) /\ k SUBSET BIGUNION (IMAGE vv k)`` THENL 10559 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 10560 POP_ASSUM K_TAC THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM]] THEN 10561 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r ==> s <=> q /\ p ==> r ==> s`] THEN 10562 SIMP_TAC real_ss [FORALL_FINITE_SUBSET_IMAGE] THEN 10563 X_GEN_TAC ``j:real->bool`` THEN REPEAT STRIP_TAC THEN 10564 EXISTS_TAC ``BIGUNION (IMAGE (uu:real->(real->bool)->bool) j)`` THEN 10565 REPEAT CONJ_TAC THENL 10566 [ASM_SET_TAC[], 10567 ASM_SIMP_TAC std_ss [FINITE_BIGUNION_EQ, FORALL_IN_IMAGE, IMAGE_FINITE] THEN 10568 ASM_SET_TAC[], 10569 SIMP_TAC std_ss [BIGUNION_IMAGE, SUBSET_DEF, IN_BIGUNION, GSPECIFICATION] THEN 10570 ASM_SET_TAC[]]]); 10571 10572val COMPACT_CONTINUOUS_IMAGE_EQ = store_thm ("COMPACT_CONTINUOUS_IMAGE_EQ", 10573 ``!f:real->real s. 10574 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 10575 ==> (f continuous_on s <=> 10576 !t. compact t /\ t SUBSET s ==> compact(IMAGE f t))``, 10577 REPEAT STRIP_TAC THEN EQ_TAC THENL 10578 [MESON_TAC[COMPACT_CONTINUOUS_IMAGE, CONTINUOUS_ON_SUBSET], DISCH_TAC] THEN 10579 FIRST_X_ASSUM(X_CHOOSE_TAC ``g:real->real`` o 10580 SIMP_RULE std_ss [INJECTIVE_ON_LEFT_INVERSE]) THEN 10581 REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN 10582 X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 10583 MP_TAC(ISPECL [``g:real->real``, ``IMAGE (f:real->real) s``, 10584 ``s:real->bool``] PROPER_MAP) THEN 10585 KNOW_TAC ``IMAGE (g :real -> real) 10586 (IMAGE (f :real -> real) (s :real -> bool)) SUBSET s`` THENL 10587 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 10588 POP_ASSUM K_TAC] THEN 10589 MATCH_MP_TAC(TAUT `(q ==> s) /\ p ==> (p <=> q /\ r) ==> s`) THEN 10590 REPEAT STRIP_TAC THENL 10591 [SUBGOAL_THEN 10592 ``{x | x IN s /\ (f:real->real) x IN u} = IMAGE g u`` 10593 (fn th => ASM_MESON_TAC[th]), 10594 SUBGOAL_THEN 10595 ``{x | x IN IMAGE f s /\ (g:real->real) x IN k} = IMAGE f k`` 10596 (fn th => ASM_SIMP_TAC std_ss [th])] THEN 10597 UNDISCH_TAC `` closed_in 10598 (subtopology euclidean 10599 (IMAGE (f :real -> real) (s :real -> bool))) 10600 (u :real -> bool)`` THEN DISCH_TAC THEN 10601 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM_SET_TAC[]); 10602 10603val PROPER_MAP_FROM_COMPACT = store_thm ("PROPER_MAP_FROM_COMPACT", 10604 ``!f:real->real s k. 10605 f continuous_on s /\ IMAGE f s SUBSET t /\ compact s /\ 10606 closed_in (subtopology euclidean t) k 10607 ==> compact {x | x IN s /\ f x IN k}``, 10608 REPEAT STRIP_TAC THEN 10609 MATCH_MP_TAC CLOSED_IN_COMPACT THEN EXISTS_TAC ``s:real->bool`` THEN 10610 METIS_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_GEN]); 10611 10612val PROPER_MAP_COMPOSE = store_thm ("PROPER_MAP_COMPOSE", 10613 ``!f:real->real g:real->real s t u. 10614 IMAGE f s SUBSET t /\ 10615 (!k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}) /\ 10616 (!k. k SUBSET u /\ compact k ==> compact {x | x IN t /\ g x IN k}) 10617 ==> !k. k SUBSET u /\ compact k 10618 ==> compact {x | x IN s /\ (g o f) x IN k}``, 10619 REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN 10620 FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN 10621 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 10622 FIRST_X_ASSUM(MP_TAC o SPEC ``{x | x IN t /\ (g:real->real) x IN k}``) THEN 10623 KNOW_TAC ``{x | x IN (t :real -> bool) /\ 10624 (g :real -> real) x IN (k :real -> bool)} SUBSET t /\ 10625 compact {x | x IN t /\ g x IN k}`` THENL 10626 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 10627 POP_ASSUM K_TAC THEN MATCH_MP_TAC EQ_IMPLIES] THEN 10628 AP_TERM_TAC THEN ASM_SET_TAC[]); 10629 10630val PROPER_MAP_FROM_COMPOSITION_LEFT = store_thm ("PROPER_MAP_FROM_COMPOSITION_LEFT", 10631 ``!f:real->real g:real->real s t u. 10632 f continuous_on s /\ (IMAGE f s = t) /\ 10633 g continuous_on t /\ IMAGE g t SUBSET u /\ 10634 (!k. k SUBSET u /\ compact k 10635 ==> compact {x | x IN s /\ (g o f) x IN k}) 10636 ==> !k. k SUBSET u /\ compact k ==> compact {x | x IN t /\ g x IN k}``, 10637 REWRITE_TAC[o_THM] THEN REPEAT STRIP_TAC THEN 10638 FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN ASM_REWRITE_TAC[] THEN 10639 DISCH_THEN(MP_TAC o ISPEC ``f:real->real`` o MATCH_MP 10640 (REWRITE_RULE[IMP_CONJ_ALT] COMPACT_CONTINUOUS_IMAGE)) THEN 10641 KNOW_TAC ``(f :real -> real) continuous_on 10642 {x | x IN (s :real -> bool) /\ 10643 (g :real -> real) (f x) IN (k :real -> bool)} `` THENL 10644 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 10645 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[], 10646 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 10647 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]]); 10648 10649val lemma = prove ( 10650 ``!s t. closed_in (subtopology euclidean s) t ==> compact s ==> compact t``, 10651 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_SUBSET, CLOSED_IN_CLOSED_EQ]); 10652 10653val PROPER_MAP_FROM_COMPOSITION_RIGHT = store_thm ("PROPER_MAP_FROM_COMPOSITION_RIGHT", 10654 ``!f:real->real g:real->real s t u. 10655 f continuous_on s /\ IMAGE f s SUBSET t /\ 10656 g continuous_on t /\ IMAGE g t SUBSET u /\ 10657 (!k. k SUBSET u /\ compact k 10658 ==> compact {x | x IN s /\ (g o f) x IN k}) 10659 ==> !k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}``, 10660 REWRITE_TAC[o_THM] THEN REPEAT STRIP_TAC THEN 10661 FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (g:real->real) k``) THEN 10662 KNOW_TAC ``IMAGE (g :real -> real) (k :real -> bool) SUBSET (u :real -> bool) /\ 10663 compact (IMAGE g k)`` THENL 10664 [CONJ_TAC THENL [ASM_SET_TAC[], MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE] THEN 10665 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET], 10666 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 10667 MATCH_MP_TAC lemma THEN 10668 MATCH_MP_TAC CLOSED_IN_SUBSET_TRANS THEN 10669 EXISTS_TAC ``s:real->bool`` THEN 10670 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 10671 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN 10672 EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[] THEN 10673 MATCH_MP_TAC CLOSED_SUBSET THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED]]); 10674 10675(* ------------------------------------------------------------------------- *) 10676(* Pasting functions together on open sets. *) 10677(* ------------------------------------------------------------------------- *) 10678 10679val PASTING_LEMMA = store_thm ("PASTING_LEMMA", 10680 ``!f:'a->real->real g t s k. 10681 (!i. i IN k 10682 ==> open_in (subtopology euclidean s) (t i) /\ 10683 (f i) continuous_on (t i)) /\ 10684 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j 10685 ==> (f i x = f j x)) /\ 10686 (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ (g x = f j x)) 10687 ==> g continuous_on s``, 10688 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN 10689 STRIP_TAC THEN X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 10690 SUBGOAL_THEN 10691 ``{x | x IN s /\ g x IN u} = 10692 BIGUNION {{x | x IN (t i) /\ ((f:'a->real->real) i x) IN u} | 10693 i IN k}`` 10694 SUBST1_TAC THENL 10695 [SUBGOAL_THEN ``!i. i IN k ==> ((t:'a->real->bool) i) SUBSET s`` 10696 ASSUME_TAC THENL 10697 [ASM_MESON_TAC[OPEN_IN_SUBSET, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY], 10698 SIMP_TAC std_ss [BIGUNION_GSPEC] THEN ASM_SET_TAC[]], 10699 MATCH_MP_TAC OPEN_IN_BIGUNION THEN SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 10700 METIS_TAC[OPEN_IN_TRANS]]); 10701 10702val PASTING_LEMMA_EXISTS = store_thm ("PASTING_LEMMA_EXISTS", 10703 ``!f:'a->real->real t s k. 10704 s SUBSET BIGUNION {t i | i IN k} /\ 10705 (!i. i IN k 10706 ==> open_in (subtopology euclidean s) (t i) /\ 10707 (f i) continuous_on (t i)) /\ 10708 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j 10709 ==> (f i x = f j x)) 10710 ==> ?g. g continuous_on s /\ 10711 (!x i. i IN k /\ x IN s INTER t i ==> (g x = f i x))``, 10712 REPEAT STRIP_TAC THEN 10713 EXISTS_TAC ``\x. (f:'a->real->real)(@i. i IN k /\ x IN t i) x`` THEN 10714 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN MATCH_MP_TAC PASTING_LEMMA THEN 10715 MAP_EVERY EXISTS_TAC 10716 [``f:'a->real->real``, ``t:'a->real->bool``, ``k:'a->bool``] THEN 10717 ASM_SET_TAC[]); 10718 10719val CONTINUOUS_ON_UNION_LOCAL_OPEN = store_thm ("CONTINUOUS_ON_UNION_LOCAL_OPEN", 10720 ``!f:real->real s. 10721 open_in (subtopology euclidean (s UNION t)) s /\ 10722 open_in (subtopology euclidean (s UNION t)) t /\ 10723 f continuous_on s /\ f continuous_on t 10724 ==> f continuous_on (s UNION t)``, 10725 REPEAT STRIP_TAC THEN MP_TAC(ISPECL 10726 [``(\i:(real->bool). (f:real->real))``, ``f:real->real``, 10727 ``(\i:(real->bool). i)``, ``s UNION (t:real->bool)``, ``{s:real->bool;t}``] 10728 PASTING_LEMMA) THEN DISCH_THEN MATCH_MP_TAC THEN 10729 ASM_SIMP_TAC std_ss [FORALL_IN_INSERT, EXISTS_IN_INSERT, NOT_IN_EMPTY] THEN 10730 REWRITE_TAC[IN_UNION]); 10731 10732val CONTINUOUS_ON_UNION_OPEN = store_thm ("CONTINUOUS_ON_UNION_OPEN", 10733 ``!f s t. open s /\ open t /\ f continuous_on s /\ f continuous_on t 10734 ==> f continuous_on (s UNION t)``, 10735 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN 10736 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN 10737 ASM_SIMP_TAC std_ss [OPEN_UNION] THEN SET_TAC[]); 10738 10739val CONTINUOUS_ON_CASES_LOCAL_OPEN = store_thm ("CONTINUOUS_ON_CASES_LOCAL_OPEN", 10740 ``!P f g:real->real s t. 10741 open_in (subtopology euclidean (s UNION t)) s /\ 10742 open_in (subtopology euclidean (s UNION t)) t /\ 10743 f continuous_on s /\ g continuous_on t /\ 10744 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x)) 10745 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)``, 10746 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN 10747 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL 10748 [EXISTS_TAC ``f:real->real``, EXISTS_TAC ``g:real->real``] THEN 10749 ASM_SIMP_TAC std_ss [] THEN METIS_TAC[]); 10750 10751val CONTINUOUS_ON_CASES_OPEN = store_thm ("CONTINUOUS_ON_CASES_OPEN", 10752 ``!P f g s t. 10753 open s /\ 10754 open t /\ 10755 f continuous_on s /\ 10756 g continuous_on t /\ 10757 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x)) 10758 ==> (\x. if P x then f x else g x) continuous_on s UNION t``, 10759 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL_OPEN THEN 10760 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN 10761 ASM_SIMP_TAC std_ss [OPEN_UNION] THEN SET_TAC[]); 10762 10763(* ------------------------------------------------------------------------- *) 10764(* Likewise on closed sets, with a finiteness assumption. *) 10765(* ------------------------------------------------------------------------- *) 10766 10767val PASTING_LEMMA_CLOSED = store_thm ("PASTING_LEMMA_CLOSED", 10768 ``!f:'a->real->real g t s k. 10769 FINITE k /\ 10770 (!i. i IN k 10771 ==> closed_in (subtopology euclidean s) (t i) /\ 10772 (f i) continuous_on (t i)) /\ 10773 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j 10774 ==> (f i x = f j x)) /\ 10775 (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ (g x = f j x)) 10776 ==> g continuous_on s``, 10777 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN 10778 STRIP_TAC THEN X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 10779 SUBGOAL_THEN 10780 ``{x | x IN s /\ g x IN u} = 10781 BIGUNION {{x | x IN (t i) /\ ((f:'a->real->real) i x) IN u} | 10782 i IN k}`` 10783 SUBST1_TAC THENL 10784 [SUBGOAL_THEN ``!i. i IN k ==> ((t:'a->real->bool) i) SUBSET s`` 10785 ASSUME_TAC THENL 10786 [ASM_MESON_TAC[CLOSED_IN_SUBSET, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY], 10787 SIMP_TAC std_ss [BIGUNION_GSPEC] THEN ASM_SET_TAC[]], 10788 MATCH_MP_TAC CLOSED_IN_BIGUNION THEN 10789 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, IMAGE_FINITE, FORALL_IN_IMAGE] THEN 10790 METIS_TAC[CLOSED_IN_TRANS]]); 10791 10792val PASTING_LEMMA_EXISTS_CLOSED = store_thm ("PASTING_LEMMA_EXISTS_CLOSED", 10793 ``!f:'a->real->real t s k. 10794 FINITE k /\ 10795 s SUBSET BIGUNION {t i | i IN k} /\ 10796 (!i. i IN k 10797 ==> closed_in (subtopology euclidean s) (t i) /\ 10798 (f i) continuous_on (t i)) /\ 10799 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j 10800 ==> (f i x = f j x)) 10801 ==> ?g. g continuous_on s /\ 10802 (!x i. i IN k /\ x IN s INTER t i ==> (g x = f i x))``, 10803 REPEAT STRIP_TAC THEN 10804 EXISTS_TAC ``\x. (f:'a->real->real)(@i. i IN k /\ x IN t i) x`` THEN 10805 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 10806 MATCH_MP_TAC PASTING_LEMMA_CLOSED THEN 10807 MAP_EVERY EXISTS_TAC 10808 [``f:'a->real->real``, ``t:'a->real->bool``, ``k:'a->bool``] THEN 10809 ASM_SET_TAC[]); 10810 10811(* ------------------------------------------------------------------------- *) 10812(* Closure of halflines, halfspaces and hyperplanes. *) 10813(* ------------------------------------------------------------------------- *) 10814 10815val LIM_LIFT_DOT = store_thm ("LIM_LIFT_DOT", 10816 ``!f:real->real a. 10817 (f --> l) net ==> ((\y. a * f(y)) --> (a * l)) net``, 10818 METIS_TAC [LIM_CMUL]); 10819 10820val CONTINUOUS_AT_LIFT_DOT = store_thm ("CONTINUOUS_AT_LIFT_DOT", 10821 ``!a:real x. (\y. a * y) continuous at x``, 10822 REPEAT GEN_TAC THEN SIMP_TAC std_ss [CONTINUOUS_AT, o_THM] THEN 10823 KNOW_TAC ``((\y. a * (\y. y) y:real) --> (a * x)) (at x)`` THENL 10824 [ALL_TAC, SIMP_TAC std_ss []] THEN 10825 MATCH_MP_TAC LIM_LIFT_DOT THEN REWRITE_TAC[LIM_AT] THEN METIS_TAC[]); 10826 10827val CONTINUOUS_ON_LIFT_DOT = store_thm ("CONTINUOUS_ON_LIFT_DOT", 10828 ``!s. (\y. a * y) continuous_on s``, 10829 SIMP_TAC std_ss [CONTINUOUS_AT_IMP_CONTINUOUS_ON, CONTINUOUS_AT_LIFT_DOT]); 10830 10831val CLOSED_INTERVAL_LEFT = store_thm ("CLOSED_INTERVAL_LEFT", 10832 ``!b:real. 10833 closed {x:real | x <= b}``, 10834 SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_APPROACHABLE, GSPECIFICATION] THEN 10835 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN 10836 FIRST_X_ASSUM(MP_TAC o SPEC ``(x:real) - (b:real)``) THEN 10837 ASM_REWRITE_TAC[REAL_SUB_LT] THEN 10838 DISCH_THEN(X_CHOOSE_THEN ``z:real`` MP_TAC) THEN 10839 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 10840 REWRITE_TAC[dist] THEN ASM_REAL_ARITH_TAC); 10841 10842val CLOSED_INTERVAL_RIGHT = store_thm ("CLOSED_INTERVAL_RIGHT", 10843 ``!a:real. 10844 closed {x:real | a <= x}``, 10845 SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_APPROACHABLE, GSPECIFICATION] THEN 10846 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN 10847 FIRST_X_ASSUM(MP_TAC o SPEC ``(a:real) - (x:real)``) THEN 10848 ASM_REWRITE_TAC[REAL_SUB_LT] THEN 10849 DISCH_THEN(X_CHOOSE_THEN ``z:real`` MP_TAC) THEN 10850 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 10851 REWRITE_TAC[dist] THEN ASM_REAL_ARITH_TAC); 10852 10853val CLOSED_HALFSPACE_LE = store_thm ("CLOSED_HALFSPACE_LE", 10854 ``!a:real b. closed {x | a * x <= b}``, 10855 REPEAT GEN_TAC THEN 10856 MP_TAC(ISPEC ``univ(:real)`` CONTINUOUS_ON_LIFT_DOT) THEN 10857 SIMP_TAC std_ss [CONTINUOUS_ON_CLOSED, GSYM CLOSED_IN, SUBTOPOLOGY_UNIV] THEN 10858 DISCH_THEN(MP_TAC o SPEC 10859 ``IMAGE (\x. x) {r | ?x:real. (a * x = r) /\ r <= b}``) THEN 10860 KNOW_TAC ``closed_in (subtopology euclidean (IMAGE (\y. a * y) univ(:real))) 10861 (IMAGE (\x. x) {r | ?x. (a * x = r) /\ r <= b})`` THENL 10862 [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 10863 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 10864 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE, IN_UNIV] THEN 10865 METIS_TAC []] THEN 10866 REWRITE_TAC[CLOSED_IN_CLOSED] THEN 10867 EXISTS_TAC ``{x | (x:real) <= (b)}`` THEN 10868 SIMP_TAC std_ss [CLOSED_INTERVAL_LEFT] THEN 10869 SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_UNIV, GSPECIFICATION, IN_INTER] THEN 10870 METIS_TAC []); 10871 10872val CLOSED_HALFSPACE_GE = store_thm ("CLOSED_HALFSPACE_GE", 10873 ``!a:real b. closed {x | a * x >= b}``, 10874 REWRITE_TAC[REAL_ARITH ``a >= b <=> -a <= -b:real``] THEN 10875 REWRITE_TAC[GSYM REAL_MUL_LNEG, CLOSED_HALFSPACE_LE]); 10876 10877val CLOSED_HYPERPLANE = store_thm ("CLOSED_HYPERPLANE", 10878 ``!a b. closed {x | a * x = b}``, 10879 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN 10880 REWRITE_TAC[REAL_ARITH ``b <= a * x <=> a * x >= b:real``] THEN 10881 REWRITE_TAC[SET_RULE `` {x | a * x <= b /\ a * x >= b} = 10882 {x | a * x <= b} INTER {x | a * x >= b}``] THEN 10883 SIMP_TAC std_ss [CLOSED_INTER, CLOSED_HALFSPACE_LE, CLOSED_HALFSPACE_GE]); 10884 10885val CLOSURE_HYPERPLANE = store_thm ("CLOSURE_HYPERPLANE", 10886 ``!a b. closure {x | a * x = b} = {x | a * x = b}``, 10887 SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_HYPERPLANE]); 10888 10889val CLOSED_STANDARD_HYPERPLANE = store_thm ("CLOSED_STANDARD_HYPERPLANE", 10890 ``!a. closed {x:real | x = a}``, 10891 REPEAT GEN_TAC THEN 10892 MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSED_HYPERPLANE) THEN 10893 REAL_ARITH_TAC); 10894 10895val CLOSED_HALFSPACE_COMPONENT_LE = store_thm ("CLOSED_HALFSPACE_COMPONENT_LE", 10896 ``!a. closed {x:real | x <= a}``, 10897 REPEAT GEN_TAC THEN 10898 MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSED_HALFSPACE_LE) THEN 10899 REAL_ARITH_TAC); 10900 10901val CLOSED_HALFSPACE_COMPONENT_GE = store_thm ("CLOSED_HALFSPACE_COMPONENT_GE", 10902 ``!a. closed {x:real | x >= a}``, 10903 REPEAT GEN_TAC THEN 10904 MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSED_HALFSPACE_GE) THEN 10905 REAL_ARITH_TAC); 10906 10907(* ------------------------------------------------------------------------- *) 10908(* Openness of halfspaces. *) 10909(* ------------------------------------------------------------------------- *) 10910 10911val OPEN_HALFSPACE_LT = store_thm ("OPEN_HALFSPACE_LT", 10912 ``!a b. open {x | a * x < b}``, 10913 REWRITE_TAC[GSYM REAL_NOT_LE] THEN 10914 SIMP_TAC std_ss [SET_RULE ``{x | ~p x} = UNIV DIFF {x | p x}``] THEN 10915 REWRITE_TAC[GSYM closed_def, GSYM real_ge, CLOSED_HALFSPACE_GE]); 10916 10917val OPEN_HALFSPACE_COMPONENT_LT = store_thm ("OPEN_HALFSPACE_COMPONENT_LT", 10918 ``!a. open {x:real | x < a}``, 10919 REPEAT GEN_TAC THEN 10920 MP_TAC(ISPECL [``1:real``, ``a:real``] OPEN_HALFSPACE_LT) THEN 10921 ASM_SIMP_TAC std_ss [REAL_MUL_LID]); 10922 10923val OPEN_HALFSPACE_GT = store_thm ("OPEN_HALFSPACE_GT", 10924 ``!a b. open {x | a * x > b}``, 10925 REWRITE_TAC[REAL_ARITH ``x > y <=> ~(x <= y:real)``] THEN 10926 SIMP_TAC std_ss [SET_RULE ``{x | ~p x} = UNIV DIFF {x | p x}``] THEN 10927 REWRITE_TAC[GSYM closed_def, CLOSED_HALFSPACE_LE]); 10928 10929val OPEN_HALFSPACE_COMPONENT_GT = store_thm ("OPEN_HALFSPACE_COMPONENT_GT", 10930 ``!a. open {x:real | x > a}``, 10931 REPEAT GEN_TAC THEN 10932 MP_TAC(ISPECL [``1:real``, ``a:real``] OPEN_HALFSPACE_GT) THEN 10933 ASM_SIMP_TAC std_ss [REAL_MUL_LID]); 10934 10935val OPEN_POSITIVE_MULTIPLES = store_thm ("OPEN_POSITIVE_MULTIPLES", 10936 ``!s:real->bool. open s ==> open {c * x | &0 < c /\ x IN s}``, 10937 SIMP_TAC std_ss [open_def, FORALL_IN_GSPEC] THEN GEN_TAC THEN DISCH_TAC THEN 10938 MAP_EVERY X_GEN_TAC [``c:real``, ``x:real``] THEN STRIP_TAC THEN 10939 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_SIMP_TAC std_ss [] THEN 10940 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 10941 EXISTS_TAC ``c * e:real`` THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL] THEN 10942 X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 10943 FIRST_X_ASSUM(MP_TAC o SPEC ``inv(c) * y:real``) THEN 10944 KNOW_TAC ``(dist (inv (c :real) * (y :real),(x :real)) :real) < (e :real)`` THENL 10945 [SUBGOAL_THEN ``x:real = inv c * c * x`` SUBST1_TAC THENL 10946 [ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID, 10947 REAL_LT_IMP_NE], 10948 ONCE_REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN 10949 ASM_SIMP_TAC std_ss [DIST_MUL, abs, REAL_LT_INV_EQ, REAL_LT_IMP_LE] THEN 10950 ONCE_REWRITE_TAC[METIS [REAL_MUL_SYM, GSYM real_div] ``inv c * x:real = x / c:real``] THEN 10951 METIS_TAC[REAL_LT_LDIV_EQ, REAL_MUL_SYM]], 10952 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 10953 DISCH_TAC THEN SRW_TAC [][] THEN 10954 EXISTS_TAC ``c:real`` THEN EXISTS_TAC ``inv(c) * y:real`` THEN 10955 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_LT_IMP_NE] THEN 10956 REAL_ARITH_TAC]); 10957 10958val OPEN_INTERVAL_LEFT = store_thm ("OPEN_INTERVAL_LEFT", 10959 ``!b:real. open {x:real | x < b}``, 10960 REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT]); 10961 10962val OPEN_INTERVAL_RIGHT = store_thm ("OPEN_INTERVAL_RIGHT", 10963 ``!a:real. open {x:real | a < x}``, 10964 REWRITE_TAC[GSYM real_gt, OPEN_HALFSPACE_COMPONENT_GT]); 10965 10966val OPEN_POSITIVE_ORTHANT = store_thm ("OPEN_POSITIVE_ORTHANT", 10967 ``open {x:real | &0 < x}``, 10968 MP_TAC(ISPEC ``0:real`` OPEN_INTERVAL_RIGHT) THEN 10969 REWRITE_TAC[]); 10970 10971(* ------------------------------------------------------------------------- *) 10972(* Closures and interiors of halfspaces. *) 10973(* ------------------------------------------------------------------------- *) 10974 10975val INTERIOR_HALFSPACE_LE = store_thm ("INTERIOR_HALFSPACE_LE", 10976 ``!a:real b. 10977 ~(a = 0) ==> (interior {x | a * x <= b} = {x | a * x < b})``, 10978 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN 10979 SIMP_TAC std_ss [OPEN_HALFSPACE_LT, SUBSET_DEF, GSPECIFICATION, REAL_LT_IMP_LE] THEN 10980 X_GEN_TAC ``s:real->bool`` THEN STRIP_TAC THEN 10981 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN ASM_SIMP_TAC std_ss [REAL_LT_LE] THEN 10982 DISCH_TAC THEN UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN 10983 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN 10984 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 10985 DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 10986 REWRITE_TAC[SUBSET_DEF, IN_CBALL] THEN 10987 DISCH_THEN(MP_TAC o SPEC ``x + e / abs(a) * a:real``) THEN 10988 REWRITE_TAC[METIS [dist, REAL_ADD_SUB2, ABS_NEG] ``dist(x:real,x + y) = abs y``] THEN 10989 ASM_SIMP_TAC std_ss [ABS_MUL, ABS_DIV, ABS_ABS, REAL_DIV_RMUL, 10990 ABS_ZERO, REAL_ARITH ``&0 < x ==> abs x <= x:real``] THEN 10991 DISCH_TAC THEN 10992 FIRST_X_ASSUM(MP_TAC o SPEC ``x + e / abs(a) * a:real``) THEN 10993 ASM_REWRITE_TAC [REAL_LDISTRIB] THEN 10994 REWRITE_TAC [REAL_ARITH ``a * (b * a) = b * (a * a:real)``] THEN 10995 MATCH_MP_TAC(REAL_ARITH ``&0 < e ==> ~(b + e <= b:real)``) THEN 10996 ASM_SIMP_TAC std_ss [REAL_LT_MUL, REAL_LT_DIV, GSYM ABS_NZ, REAL_POSSQ]); 10997 10998val INTERIOR_HALFSPACE_GE = store_thm ("INTERIOR_HALFSPACE_GE", 10999 ``!a:real b. 11000 ~(a = 0) ==> (interior {x | a * x >= b} = {x | a * x > b})``, 11001 REPEAT STRIP_TAC THEN 11002 ONCE_REWRITE_TAC[REAL_ARITH ``a >= b <=> -a <= -b:real``, 11003 REAL_ARITH ``a > b <=> -a < -b:real``] THEN 11004 ASM_SIMP_TAC std_ss [REAL_NEG_LMUL, INTERIOR_HALFSPACE_LE, REAL_NEG_EQ0]); 11005 11006val INTERIOR_HALFSPACE_COMPONENT_LE = store_thm ("INTERIOR_HALFSPACE_COMPONENT_LE", 11007 ``!a. interior {x:real | x <= a} = {x | x < a}``, 11008 REPEAT GEN_TAC THEN 11009 MP_TAC(ISPECL [``1:real``, ``a:real``] INTERIOR_HALFSPACE_LE) THEN 11010 ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]); 11011 11012val INTERIOR_HALFSPACE_COMPONENT_GE = store_thm ("INTERIOR_HALFSPACE_COMPONENT_GE", 11013 ``!a. interior {x:real | x >= a} = {x | x > a}``, 11014 REPEAT GEN_TAC THEN 11015 MP_TAC(ISPECL [``1:real``, ``a:real``] INTERIOR_HALFSPACE_GE) THEN 11016 ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]); 11017 11018val CLOSURE_HALFSPACE_LT = store_thm ("CLOSURE_HALFSPACE_LT", 11019 ``!a:real b. 11020 ~(a = 0) ==> (closure {x | a * x < b} = {x | a * x <= b})``, 11021 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN 11022 SIMP_TAC std_ss [SET_RULE ``UNIV DIFF {x | P x} = {x | ~P x}``] THEN 11023 ASM_SIMP_TAC std_ss [REAL_ARITH ``~(x < b) <=> x >= b:real``, INTERIOR_HALFSPACE_GE] THEN 11024 SIMP_TAC std_ss [EXTENSION, IN_DIFF, IN_UNIV, GSPECIFICATION] THEN REAL_ARITH_TAC); 11025 11026val CLOSURE_HALFSPACE_GT = store_thm ("CLOSURE_HALFSPACE_GT", 11027 ``!a:real b. 11028 ~(a = 0) ==> (closure {x | a * x > b} = {x | a * x >= b})``, 11029 REPEAT STRIP_TAC THEN 11030 ONCE_REWRITE_TAC[REAL_ARITH ``a >= b <=> -a <= -b:real``, 11031 REAL_ARITH ``a > b <=> -a < -b:real``] THEN 11032 ASM_SIMP_TAC std_ss [REAL_NEG_LMUL, CLOSURE_HALFSPACE_LT, REAL_NEG_EQ0]); 11033 11034val CLOSURE_HALFSPACE_COMPONENT_LT = store_thm ("CLOSURE_HALFSPACE_COMPONENT_LT", 11035 ``!a. closure {x:real | x < a} = {x | x <= a}``, 11036 REPEAT GEN_TAC THEN 11037 MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSURE_HALFSPACE_LT) THEN 11038 ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]); 11039 11040val CLOSURE_HALFSPACE_COMPONENT_GT = store_thm ("CLOSURE_HALFSPACE_COMPONENT_GT", 11041 ``!a. closure {x:real | x > a} = {x | x >= a}``, 11042 REPEAT GEN_TAC THEN 11043 MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSURE_HALFSPACE_GT) THEN 11044 ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]); 11045 11046val INTERIOR_HYPERPLANE = store_thm ("INTERIOR_HYPERPLANE", 11047 ``!a b. ~(a = 0) ==> (interior {x | a * x = b} = {})``, 11048 REWRITE_TAC[REAL_ARITH ``(x = y) <=> x <= y /\ x >= y:real``] THEN 11049 SIMP_TAC std_ss [SET_RULE ``{x | p x /\ q x} = {x | p x} INTER {x | q x}``] THEN 11050 REWRITE_TAC[INTERIOR_INTER] THEN 11051 REWRITE_TAC [GSYM DE_MORGAN_THM, REAL_ARITH ``x <= y /\ x >= y:real <=> (x = y)``] THEN 11052 ASM_SIMP_TAC std_ss [INTERIOR_HALFSPACE_LE, INTERIOR_HALFSPACE_GE] THEN 11053 SIMP_TAC std_ss [EXTENSION, IN_INTER, GSPECIFICATION, NOT_IN_EMPTY] THEN 11054 REAL_ARITH_TAC); 11055 11056val FRONTIER_HALFSPACE_LE = store_thm ("FRONTIER_HALFSPACE_LE", 11057 ``!a:real b. ~((a = 0) /\ (b = &0)) 11058 ==> (frontier {x | a * x <= b} = {x | a * x = b})``, 11059 REPEAT GEN_TAC THEN ASM_CASES_TAC ``a:real = 0`` THEN 11060 ASM_SIMP_TAC std_ss [REAL_MUL_LZERO] THENL 11061 [ASM_CASES_TAC ``&0 <= b:real`` THEN 11062 ASM_SIMP_TAC std_ss [GSPEC_T, FRONTIER_UNIV, GSPEC_F, FRONTIER_EMPTY], 11063 ASM_SIMP_TAC std_ss [frontier, INTERIOR_HALFSPACE_LE, CLOSURE_CLOSED, 11064 CLOSED_HALFSPACE_LE] THEN 11065 SIMP_TAC std_ss [EXTENSION, IN_DIFF, GSPECIFICATION] THEN REAL_ARITH_TAC]); 11066 11067val FRONTIER_HALFSPACE_GE = store_thm ("FRONTIER_HALFSPACE_GE", 11068 ``!a:real b. ~((a = 0) /\ (b = &0)) 11069 ==> (frontier {x | a * x >= b} = {x | a * x = b})``, 11070 REPEAT STRIP_TAC THEN 11071 MP_TAC(ISPECL [``-a:real``, ``-b:real``] FRONTIER_HALFSPACE_LE) THEN 11072 ASM_REWRITE_TAC [REAL_NEG_EQ0, REAL_NEG_LMUL] THEN 11073 REWRITE_TAC [GSYM REAL_NEG_LMUL] THEN REWRITE_TAC [REAL_EQ_NEG] THEN 11074 SIMP_TAC std_ss [REAL_LE_NEG2, real_ge]); 11075 11076val FRONTIER_HALFSPACE_LT = store_thm ("FRONTIER_HALFSPACE_LT", 11077 ``!a:real b. ~((a = 0) /\ (b = &0)) 11078 ==> (frontier {x | a * x < b} = {x | a * x = b})``, 11079 REPEAT GEN_TAC THEN ASM_CASES_TAC ``a:real = 0`` THEN 11080 ASM_SIMP_TAC std_ss [REAL_NEG_LMUL] THENL 11081 [ASM_CASES_TAC ``&0 < b:real`` THEN REWRITE_TAC [REAL_MUL_LZERO] THEN 11082 ASM_SIMP_TAC std_ss [GSPEC_T, FRONTIER_UNIV, GSPEC_F, FRONTIER_EMPTY], 11083 ASM_SIMP_TAC std_ss [frontier, CLOSURE_HALFSPACE_LT, INTERIOR_OPEN, 11084 OPEN_HALFSPACE_LT] THEN 11085 SIMP_TAC std_ss [EXTENSION, IN_DIFF, GSPECIFICATION] THEN REAL_ARITH_TAC]); 11086 11087val FRONTIER_HALFSPACE_GT = store_thm ("FRONTIER_HALFSPACE_GT", 11088 ``!a:real b. ~((a = 0) /\ (b = &0)) 11089 ==> (frontier {x | a * x > b} = {x | a * x = b})``, 11090 REPEAT STRIP_TAC THEN 11091 MP_TAC(ISPECL [``-a:real``, ``-b:real``] FRONTIER_HALFSPACE_LT) THEN 11092 ASM_REWRITE_TAC[REAL_NEG_EQ0, REAL_MUL_LNEG] THEN 11093 SIMP_TAC std_ss [REAL_LT_NEG, REAL_EQ_NEG, real_gt]); 11094 11095val INTERIOR_STANDARD_HYPERPLANE = store_thm ("INTERIOR_STANDARD_HYPERPLANE", 11096 ``!a. interior {x:real | x = a} = {}``, 11097 REPEAT GEN_TAC THEN 11098 MP_TAC(ISPECL [``1:real``, ``a:real``] INTERIOR_HYPERPLANE) THEN 11099 ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]); 11100 11101(* ------------------------------------------------------------------------- *) 11102(* Unboundedness of halfspaces. *) 11103(* ------------------------------------------------------------------------- *) 11104 11105val UNBOUNDED_HALFSPACE_COMPONENT_LE = store_thm 11106 ("UNBOUNDED_HALFSPACE_COMPONENT_LE", 11107 ``!a. ~bounded {x:real | x <= a}``, 11108 REPEAT GEN_TAC 11109 >> ASM_SIMP_TAC std_ss [bounded_def, FORALL_IN_GSPEC] 11110 >> X_GEN_TAC ``B:real`` 11111 >> EXISTS_TAC ``-((&1:real) + max (abs B) (abs a))`` 11112 >> REWRITE_TAC [ABS_NEG, REAL_NOT_LE, REAL_NEG_ADD] 11113 >> RW_TAC bool_ss [abs, max_def] 11114 >> FULL_SIMP_TAC real_ss [REAL_NOT_LE] 11115 >| (* 12 goals *) 11116 [ ASM_REAL_ARITH_TAC, (* 1 *) 11117 ASM_REAL_ARITH_TAC, (* 2 *) 11118 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 3 *) 11119 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 4 *) 11120 Cases_on `0 <= B` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 5 *) 11121 Cases_on `0 <= B` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 6 *) 11122 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 7 *) 11123 ASM_REAL_ARITH_TAC, (* 8 *) 11124 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 9 *) 11125 Cases_on `0 <= B` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 10 *) 11126 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 11 *) 11127 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC ]); 11128 11129val UNBOUNDED_HALFSPACE_COMPONENT_GE = store_thm 11130 ("UNBOUNDED_HALFSPACE_COMPONENT_GE", 11131 ``!a. ~bounded {x:real | x >= a}``, 11132 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_NEGATIONS) THEN 11133 MP_TAC(SPECL [``-a:real``] UNBOUNDED_HALFSPACE_COMPONENT_LE) THEN 11134 REWRITE_TAC[GSYM MONO_NOT_EQ] THEN MATCH_MP_TAC EQ_IMPLIES THEN 11135 AP_TERM_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN CONJ_TAC THENL 11136 [MESON_TAC[REAL_NEG_NEG], 11137 SIMP_TAC std_ss [GSPECIFICATION] THEN REAL_ARITH_TAC]); 11138 11139val UNBOUNDED_HALFSPACE_COMPONENT_LT = store_thm ("UNBOUNDED_HALFSPACE_COMPONENT_LT", 11140 ``!a. ~bounded {x:real | x < a}``, 11141 ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN 11142 REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_LT, 11143 UNBOUNDED_HALFSPACE_COMPONENT_LE]); 11144 11145val UNBOUNDED_HALFSPACE_COMPONENT_GT = store_thm ("UNBOUNDED_HALFSPACE_COMPONENT_GT", 11146 ``!a. ~bounded {x:real | x > a}``, 11147 ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN 11148 REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_GT, 11149 UNBOUNDED_HALFSPACE_COMPONENT_GE]); 11150 11151(* ------------------------------------------------------------------------- *) 11152(* Equality of continuous functions on closure and related results. *) 11153(* ------------------------------------------------------------------------- *) 11154 11155val FORALL_IN_CLOSURE = store_thm ("FORALL_IN_CLOSURE", 11156 ``!f:real->real s t. 11157 closed t /\ f continuous_on (closure s) /\ 11158 (!x. x IN s ==> f x IN t) 11159 ==> (!x. x IN closure s ==> f x IN t)``, 11160 REWRITE_TAC[SET_RULE ``(!x. x IN s ==> f x IN t) <=> 11161 s SUBSET {x | x IN s /\ f x IN t}``] THEN 11162 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN 11163 ASM_REWRITE_TAC[CLOSED_CLOSURE] THEN CONJ_TAC THENL 11164 [MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[], 11165 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN 11166 ASM_REWRITE_TAC[CLOSED_CLOSURE]]); 11167 11168val FORALL_IN_CLOSURE_EQ = store_thm ("FORALL_IN_CLOSURE_EQ", 11169 ``!f s t. 11170 closed t /\ f continuous_on closure s 11171 ==> ((!x. x IN closure s ==> f x IN t) <=> 11172 (!x. x IN s ==> f x IN t))``, 11173 METIS_TAC[FORALL_IN_CLOSURE, CLOSURE_SUBSET, SUBSET_DEF]); 11174 11175val CONTINUOUS_LE_ON_CLOSURE = store_thm ("CONTINUOUS_LE_ON_CLOSURE", 11176 ``!f:real->real s a. 11177 f continuous_on closure(s) /\ (!x. x IN s ==> f(x) <= a) 11178 ==> !x. x IN closure(s) ==> f(x) <= a``, 11179 REPEAT GEN_TAC THEN STRIP_TAC THEN 11180 KNOW_TAC `` !(x :real). x IN closure (s :real -> bool) 11181 ==> (f :real -> real) x IN {y | y <= (a :real)}`` THENL 11182 [ALL_TAC, SET_TAC []] THEN 11183 MATCH_MP_TAC FORALL_IN_CLOSURE THEN 11184 ASM_SIMP_TAC std_ss [ETA_AX, CLOSED_HALFSPACE_COMPONENT_LE] THEN ASM_SET_TAC []); 11185 11186val CONTINUOUS_GE_ON_CLOSURE = store_thm ("CONTINUOUS_GE_ON_CLOSURE", 11187 ``!f:real->real s a. 11188 f continuous_on closure(s) /\ (!x. x IN s ==> a <= f(x)) 11189 ==> !x. x IN closure(s) ==> a <= f(x)``, 11190 REPEAT GEN_TAC THEN STRIP_TAC THEN 11191 KNOW_TAC `` !(x :real). x IN closure (s :real -> bool) 11192 ==> (f :real -> real) x IN {y | y >= (a :real)}`` THENL 11193 [ALL_TAC, SET_TAC [real_ge]] THEN 11194 MATCH_MP_TAC FORALL_IN_CLOSURE THEN 11195 ASM_SIMP_TAC std_ss [ETA_AX, CLOSED_HALFSPACE_COMPONENT_GE] THEN ASM_SET_TAC [real_ge]); 11196 11197val CONTINUOUS_CONSTANT_ON_CLOSURE = store_thm ("CONTINUOUS_CONSTANT_ON_CLOSURE", 11198 ``!f:real->real s a. 11199 f continuous_on closure(s) /\ (!x. x IN s ==> (f(x) = a)) 11200 ==> !x. x IN closure(s) ==> (f(x) = a)``, 11201 REWRITE_TAC[SET_RULE 11202 ``x IN s ==> (f x = a) <=> x IN s ==> f x IN {a}``] THEN 11203 REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC FORALL_IN_CLOSURE THEN 11204 ASM_REWRITE_TAC[CLOSED_SING]); 11205 11206val CONTINUOUS_AGREE_ON_CLOSURE = store_thm ("CONTINUOUS_AGREE_ON_CLOSURE", 11207 ``!g h:real->real. 11208 g continuous_on closure s /\ h continuous_on closure s /\ 11209 (!x. x IN s ==> (g x = h x)) 11210 ==> !x. x IN closure s ==> (g x = h x)``, 11211 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN STRIP_TAC THEN 11212 ONCE_REWRITE_TAC [METIS [] ``(g x - h x = 0) = ((\x. g x - h x) x = 0:real)``] THEN 11213 MATCH_MP_TAC CONTINUOUS_CONSTANT_ON_CLOSURE THEN 11214 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_SUB]); 11215 11216val CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT", 11217 ``!f:real->real s a. 11218 f continuous_on s 11219 ==> closed_in (subtopology euclidean s) {x | x IN s /\ (f x = a)}``, 11220 REPEAT STRIP_TAC THEN 11221 ONCE_REWRITE_TAC[SET_RULE 11222 ``{x | x IN s /\ (f(x) = a)} = {x | x IN s /\ f(x) IN {a}}``] THEN 11223 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN 11224 ASM_REWRITE_TAC[CLOSED_SING]); 11225 11226val CONTINUOUS_CLOSED_PREIMAGE_CONSTANT = store_thm ("CONTINUOUS_CLOSED_PREIMAGE_CONSTANT", 11227 ``!f:real->real s. 11228 f continuous_on s /\ closed s ==> closed {x | x IN s /\ (f(x) = a)}``, 11229 REPEAT STRIP_TAC THEN 11230 ASM_CASES_TAC ``{x | x IN s /\ ((f:real->real)(x) = a)} = {}`` THEN 11231 ASM_REWRITE_TAC[CLOSED_EMPTY] THEN ONCE_REWRITE_TAC[SET_RULE 11232 ``{x | x IN s /\ (f(x) = a)} = {x | x IN s /\ f(x) IN {a}}``] THEN 11233 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN 11234 ASM_REWRITE_TAC[CLOSED_SING] THEN ASM_SET_TAC[]); 11235 11236(* ------------------------------------------------------------------------- *) 11237(* Theorems relating continuity and uniform continuity to closures. *) 11238(* ------------------------------------------------------------------------- *) 11239 11240val CONTINUOUS_ON_CLOSURE = store_thm ("CONTINUOUS_ON_CLOSURE", 11241 ``!f:real->real s. 11242 f continuous_on closure s <=> 11243 !x e. x IN closure s /\ &0 < e 11244 ==> ?d. &0 < d /\ 11245 !y. y IN s /\ dist(y,x) < d ==> dist(f y,f x) < e``, 11246 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on] THEN 11247 EQ_TAC THENL [METIS_TAC[REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET], ALL_TAC] THEN 11248 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 11249 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 11250 FIRST_ASSUM(MP_TAC o SPECL [``x:real``, ``e / &2:real``]) THEN 11251 KNOW_TAC ``x IN closure s:real->bool /\ 0 < e / 2:real`` THENL 11252 [ASM_REWRITE_TAC[REAL_HALF], DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [])] THEN 11253 DISCH_TAC THEN FIRST_ASSUM (fn th => REWRITE_TAC [th]) THEN 11254 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 11255 EXISTS_TAC ``d / &2:real`` THEN ASM_REWRITE_TAC[REAL_HALF] THEN 11256 X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 11257 FIRST_X_ASSUM(MP_TAC o SPECL [``y:real``, ``e / &2:real``]) THEN 11258 ASM_REWRITE_TAC[REAL_HALF] THEN 11259 DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN 11260 MP_TAC(ISPECL [``y:real``, ``s:real->bool``] CLOSURE_APPROACHABLE) THEN 11261 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min k (d / &2:real)``) THEN 11262 ASM_REWRITE_TAC[REAL_HALF, REAL_LT_MIN] THEN 11263 KNOW_TAC ``!a b c e. abs(a - b) < e / &2 /\ abs(b - c) < e / &2:real ==> 11264 abs(a - c) < e / 2 + e / 2:real`` THENL 11265 [REAL_ARITH_TAC, DISCH_TAC] THEN STRIP_TAC THEN 11266 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN REWRITE_TAC [dist] THEN 11267 FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC ``(f:real->real) y'`` THEN CONJ_TAC THENL 11268 [REWRITE_TAC [GSYM dist] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN 11269 FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [], 11270 REWRITE_TAC [GSYM dist] THEN FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [] THEN 11271 MATCH_MP_TAC DIST_TRIANGLE_LT THEN EXISTS_TAC ``y:real`` THEN 11272 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN MATCH_MP_TAC REAL_LT_ADD2 THEN 11273 METIS_TAC [DIST_SYM]]); 11274 11275val CONTINUOUS_ON_CLOSURE_SEQUENTIALLY = store_thm ("CONTINUOUS_ON_CLOSURE_SEQUENTIALLY", 11276 ``!f:real->real s. 11277 f continuous_on closure s <=> 11278 !x a. a IN closure s /\ (!n. x n IN s) /\ (x --> a) sequentially 11279 ==> ((f o x) --> f a) sequentially``, 11280 REWRITE_TAC[CONTINUOUS_ON_CLOSURE] THEN 11281 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 11282 REWRITE_TAC[AND_IMP_INTRO, GSYM continuous_within] THEN 11283 REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]); 11284 11285val UNIFORMLY_CONTINUOUS_ON_CLOSURE = store_thm ("UNIFORMLY_CONTINUOUS_ON_CLOSURE", 11286 ``!f:real->real s. 11287 f uniformly_continuous_on s /\ f continuous_on closure s 11288 ==> f uniformly_continuous_on closure s``, 11289 REPEAT GEN_TAC THEN 11290 REWRITE_TAC[uniformly_continuous_on] THEN STRIP_TAC THEN 11291 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 11292 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &3:real``) THEN 11293 KNOW_TAC ``0 < e / 3:real`` THENL 11294 [FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 11295 ASM_REAL_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 11296 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 11297 EXISTS_TAC ``d / &3:real`` THEN CONJ_TAC THENL 11298 [FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 11299 REWRITE_TAC [REAL_MUL_LZERO] THEN ASM_REWRITE_TAC [], ALL_TAC] THEN 11300 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 11301 UNDISCH_TAC ``f continuous_on closure s`` THEN DISCH_TAC THEN 11302 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [continuous_on]) THEN 11303 DISCH_THEN(fn th => 11304 MP_TAC(SPEC ``y:real`` th) THEN MP_TAC(SPEC ``x:real`` th)) THEN 11305 ASM_REWRITE_TAC[] THEN 11306 DISCH_THEN(MP_TAC o SPEC ``e / &3:real``) THEN ASM_REWRITE_TAC [] THEN 11307 DISCH_THEN(X_CHOOSE_THEN ``d1:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 11308 MP_TAC(ISPECL [``x:real``, ``s:real->bool``] CLOSURE_APPROACHABLE) THEN 11309 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min d1 (d / &3:real)``) THEN 11310 KNOW_TAC ``0 < min d1 (d / 3:real)`` THENL 11311 [REWRITE_TAC [min_def] THEN COND_CASES_TAC THEN 11312 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 11313 REWRITE_TAC [REAL_MUL_LZERO] THEN ASM_REWRITE_TAC [], 11314 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 11315 REWRITE_TAC[REAL_LT_MIN] THEN 11316 DISCH_THEN(X_CHOOSE_THEN ``x':real`` STRIP_ASSUME_TAC) THEN 11317 DISCH_THEN(MP_TAC o SPEC ``x':real``) THEN 11318 ASM_SIMP_TAC std_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET] THEN DISCH_TAC THEN 11319 DISCH_THEN(MP_TAC o SPEC ``e / &3:real``) THEN ASM_REWRITE_TAC [] THEN 11320 DISCH_THEN(X_CHOOSE_THEN ``d2:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 11321 MP_TAC(ISPECL [``y:real``, ``s:real->bool``] CLOSURE_APPROACHABLE) THEN 11322 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min d2 (d / &3:real)``) THEN 11323 KNOW_TAC ``0 < min d2 (d / 3:real)`` THENL 11324 [REWRITE_TAC [min_def] THEN COND_CASES_TAC THEN 11325 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 11326 REWRITE_TAC [REAL_MUL_LZERO] THEN ASM_REWRITE_TAC [], 11327 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 11328 REWRITE_TAC[REAL_LT_MIN] THEN 11329 DISCH_THEN(X_CHOOSE_THEN ``y':real`` STRIP_ASSUME_TAC) THEN 11330 DISCH_THEN(MP_TAC o SPEC ``y':real``) THEN 11331 ASM_SIMP_TAC std_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET] THEN DISCH_TAC THEN 11332 FIRST_X_ASSUM(MP_TAC o SPECL [``x':real``, ``y':real``]) THEN 11333 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 11334 METIS_TAC[dist, ABS_SUB, REAL_ARITH 11335 ``abs(y - x) * 3 < d /\ abs(x' - x) * 3 < d /\ abs(y' - y) * 3 < d 11336 ==> abs(y' - x') < d:real``]); 11337 11338(* ------------------------------------------------------------------------- *) 11339(* Cauchy continuity, and the extension of functions to closures. *) 11340(* ------------------------------------------------------------------------- *) 11341 11342val UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS = store_thm 11343 ("UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS", 11344 ``!f:real->real s. 11345 f uniformly_continuous_on s 11346 ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))``, 11347 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on, cauchy, o_DEF] THEN 11348 MESON_TAC[]); 11349 11350val CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS = store_thm 11351 ("CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS", 11352 ``!f:real->real s. 11353 f continuous_on s /\ closed s 11354 ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))``, 11355 REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED, CONTINUOUS_ON_SEQUENTIALLY] THEN 11356 REWRITE_TAC[complete] THEN MESON_TAC[CONVERGENT_IMP_CAUCHY]); 11357 11358val CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA = store_thm 11359 ("CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA", 11360 ``!f:real->real s. 11361 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x)) 11362 ==> !a x. (!n. (x n) IN s) /\ (x --> a) sequentially 11363 ==> ?l. ((f o x) --> l) sequentially /\ 11364 !y. (!n. (y n) IN s) /\ (y --> a) sequentially 11365 ==> ((f o y) --> l) sequentially``, 11366 REPEAT STRIP_TAC THEN 11367 FIRST_ASSUM(MP_TAC o SPEC ``x:num->real``) THEN 11368 KNOW_TAC ``cauchy x /\ (!n. x n IN s)`` THENL 11369 [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY], 11370 DISCH_THEN (fn th => REWRITE_TAC [th])] THEN 11371 REWRITE_TAC [GSYM CONVERGENT_EQ_CAUCHY] THEN 11372 DISCH_THEN (X_CHOOSE_TAC ``l:real``) THEN EXISTS_TAC ``l:real`` THEN 11373 ASM_REWRITE_TAC [] THEN 11374 X_GEN_TAC ``y:num->real`` THEN STRIP_TAC THEN 11375 FIRST_ASSUM(MP_TAC o SPEC ``y:num->real``) THEN 11376 KNOW_TAC ``cauchy y /\ (!n. y n IN s)`` THENL 11377 [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY], 11378 DISCH_THEN (fn th => REWRITE_TAC [th])] THEN 11379 REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN 11380 DISCH_THEN(X_CHOOSE_THEN ``l':real`` STRIP_ASSUME_TAC) THEN 11381 SUBGOAL_THEN ``l:real = l'`` (fn th => ASM_REWRITE_TAC[th]) THEN 11382 ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN 11383 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN 11384 EXISTS_TAC ``\n:num. (f:real->real)(x n) - f(y n)`` THEN 11385 RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN 11386 ASM_SIMP_TAC std_ss [LIM_SUB, TRIVIAL_LIMIT_SEQUENTIALLY] THEN 11387 FIRST_X_ASSUM(MP_TAC o SPEC 11388 ``\n. if EVEN n then x(n DIV 2):real else y(n DIV 2)``) THEN 11389 REWRITE_TAC[cauchy, o_THM, LIM_SEQUENTIALLY] THEN 11390 KNOW_TAC ``(!(e :real). 11391 (0 :real) < e ==> 11392 ?(N :num). 11393 !(m :num) (n :num). 11394 m >= N /\ n >= N ==> 11395 (dist 11396 ((\(n :num). 11397 if EVEN n then (x :num -> real) (n DIV (2 :num)) 11398 else (y :num -> real) (n DIV (2 :num))) m, 11399 (\(n :num). 11400 if EVEN n then x (n DIV (2 :num)) 11401 else y (n DIV (2 :num))) n) :real) < e) /\ 11402 (!(n :num). (\(n :num). 11403 if EVEN n then x (n DIV (2 :num)) else y (n DIV (2 :num))) n IN 11404 (s :real -> bool))`` THENL 11405 [ (* goal 1 (of 2) *) 11406 CONJ_TAC THENL [ALL_TAC, METIS_TAC[]] THEN 11407 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN MAP_EVERY UNDISCH_TAC 11408 [``((y:num->real) --> a) sequentially``, 11409 ``((x:num->real) --> a) sequentially``] THEN 11410 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 11411 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_HALF] THEN 11412 DISCH_THEN(X_CHOOSE_TAC ``N1:num``) THEN 11413 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_HALF] THEN 11414 DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN 11415 EXISTS_TAC ``2 * (N1 + N2:num)`` THEN 11416 MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``] THEN STRIP_TAC THEN 11417 UNDISCH_TAC ``!n. (y:num->real) n IN s`` THEN DISCH_TAC THEN 11418 UNDISCH_TAC ``!n. (x:num->real) n IN s`` THEN DISCH_TAC THEN 11419 POP_ASSUM K_TAC THEN POP_ASSUM K_TAC THEN 11420 REPEAT(FIRST_X_ASSUM(fn th => 11421 MP_TAC(SPEC ``m DIV 2`` th) THEN MP_TAC(SPEC ``n DIV 2`` th))) THEN 11422 KNOW_TAC ``N1 <= n DIV 2`` THENL 11423 [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN 11424 ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11425 POP_ASSUM K_TAC THEN DISCH_TAC] THEN 11426 KNOW_TAC ``N1 <= m DIV 2`` THENL 11427 [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN 11428 ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11429 POP_ASSUM K_TAC THEN DISCH_TAC] THEN 11430 KNOW_TAC ``N2 <= n DIV 2`` THENL 11431 [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN 11432 ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11433 POP_ASSUM K_TAC THEN DISCH_TAC] THEN 11434 KNOW_TAC ``N2 <= m DIV 2`` THENL 11435 [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN 11436 ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11437 POP_ASSUM K_TAC THEN DISCH_TAC] THEN 11438 REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN 11439 FULL_SIMP_TAC std_ss [dist, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 11440 Cases_on `EVEN m` >> Cases_on `EVEN n` >> fs [] >| (* 4 subgoals *) 11441 [ MP_TAC (Q.SPECL [`x (m DIV 2) - a`, `x (n DIV 2) - a`] ABS_TRIANGLE_NEG), 11442 MP_TAC (Q.SPECL [`x (m DIV 2) - a`, `y (n DIV 2) - a`] ABS_TRIANGLE_NEG), 11443 MP_TAC (Q.SPECL [`y (m DIV 2) - a`, `x (n DIV 2) - a`] ABS_TRIANGLE_NEG), 11444 MP_TAC (Q.SPECL [`y (m DIV 2) - a`, `y (n DIV 2) - a`] ABS_TRIANGLE_NEG) ] 11445 >> ASM_REAL_ARITH_TAC, 11446 (* goal 2 (of 2) *) 11447 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 11448 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN 11449 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN 11450 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 11451 X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 11452 FIRST_X_ASSUM(MP_TAC o SPECL [``2 * n:num``, ``2 * n + 1:num``]) THEN 11453 KNOW_TAC ``2 * n >= N /\ 2 * n + 1 >= N:num`` THENL 11454 [ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 11455 SIMP_TAC arith_ss [EVEN_ADD, EVEN_MULT] THEN 11456 KNOW_TAC ``((2 * n) DIV 2 = n) /\ ((2 * n + 1) DIV 2 = n)`` THENL 11457 [SIMP_TAC arith_ss [DIV_EQ_X, ARITH_PROVE ``0 < 2:num``], ALL_TAC] THEN 11458 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11459 REWRITE_TAC[dist, REAL_SUB_RZERO] ]); 11460 11461val CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE = store_thm ("CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE", 11462 ``!f:real->real s. 11463 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x)) 11464 ==> ?g. g continuous_on closure s /\ (!x. x IN s ==> (g x = f x))``, 11465 REPEAT STRIP_TAC THEN 11466 SUBGOAL_THEN 11467 ``!a:real. ?x. 11468 a IN closure s ==> (!n. x n IN s) /\ (x --> a) sequentially`` 11469 MP_TAC THENL [MESON_TAC[CLOSURE_SEQUENTIAL], ALL_TAC] THEN 11470 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 11471 X_GEN_TAC ``X:real->num->real`` THEN DISCH_TAC THEN 11472 FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA) THEN 11473 DISCH_THEN(MP_TAC o GEN ``a:real`` o 11474 SPECL [``a:real``, ``(X:real->num->real) a``]) THEN 11475 KNOW_TAC ``(!(a :real). a IN closure (s :real -> bool) ==> 11476 ?(l :real). 11477 (((f :real -> real) o X a --> l) sequentially :bool) /\ 11478 !(y :num -> real). 11479 (!(n :num). y n IN s) /\ ((y --> a) sequentially :bool) ==> 11480 ((f o y --> l) sequentially :bool)) ==> 11481 ?(g :real -> real). 11482 g continuous_on closure s /\ !(x :real). x IN s ==> (g x = f x)`` THENL 11483 [ALL_TAC, METIS_TAC []] THEN DISCH_TAC THEN 11484 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 11485 SIMP_TAC std_ss [SKOLEM_THM] THEN 11486 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN 11487 POP_ASSUM MP_TAC THEN STRIP_TAC THEN 11488 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL 11489 [X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN 11490 FIRST_X_ASSUM(MP_TAC o SPEC ``a:real``) THEN 11491 ASM_SIMP_TAC std_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET] THEN 11492 DISCH_THEN(MP_TAC o SPEC ``(\n. a):num->real`` o CONJUNCT2) THEN 11493 ASM_SIMP_TAC std_ss [LIM_CONST_EQ, o_DEF, TRIVIAL_LIMIT_SEQUENTIALLY], 11494 STRIP_TAC] THEN 11495 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CLOSURE_SEQUENTIALLY] THEN 11496 MAP_EVERY X_GEN_TAC [``x:num->real``, ``a:real``] THEN STRIP_TAC THEN 11497 MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN 11498 EXISTS_TAC ``(f:real->real) o (x:num->real)`` THEN ASM_SIMP_TAC std_ss [] THEN 11499 MATCH_MP_TAC ALWAYS_EVENTUALLY THEN ASM_SIMP_TAC std_ss [o_THM]); 11500 11501val UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE = store_thm ("UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE", 11502 ``!f:real->real s. 11503 f uniformly_continuous_on s 11504 ==> ?g. g uniformly_continuous_on closure s /\ (!x. x IN s ==> (g x = f x)) /\ 11505 !h. h continuous_on closure s /\ (!x. x IN s ==> (h x = f x)) 11506 ==> !x. x IN closure s ==> (h x = g x)``, 11507 REPEAT STRIP_TAC THEN 11508 FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE o 11509 MATCH_MP UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS) THEN 11510 STRIP_TAC THEN EXISTS_TAC ``g:real->real`` THEN 11511 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THENL 11512 [METIS_TAC[UNIFORMLY_CONTINUOUS_ON_CLOSURE, UNIFORMLY_CONTINUOUS_ON_EQ], 11513 METIS_TAC[CONTINUOUS_AGREE_ON_CLOSURE]]); 11514 11515val CAUCHY_CONTINUOUS_IMP_CONTINUOUS = store_thm ("CAUCHY_CONTINUOUS_IMP_CONTINUOUS", 11516 ``!f:real->real s. 11517 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x)) 11518 ==> f continuous_on s``, 11519 REPEAT STRIP_TAC THEN 11520 FIRST_ASSUM(CHOOSE_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN 11521 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, CLOSURE_SUBSET, CONTINUOUS_ON_EQ]); 11522 11523val BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE = store_thm ("BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE", 11524 ``!f:real->real s. 11525 f uniformly_continuous_on s /\ bounded s ==> bounded(IMAGE f s)``, 11526 REPEAT STRIP_TAC THEN FIRST_ASSUM 11527 (MP_TAC o MATCH_MP UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN 11528 DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN 11529 MATCH_MP_TAC BOUNDED_SUBSET THEN 11530 EXISTS_TAC ``IMAGE (g:real->real) (closure s)`` THEN CONJ_TAC THENL 11531 [ASM_MESON_TAC[COMPACT_CLOSURE, UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS, 11532 COMPACT_IMP_BOUNDED, COMPACT_CONTINUOUS_IMAGE], 11533 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[]]); 11534 11535(* ------------------------------------------------------------------------- *) 11536(* Occasionally useful invariance properties. *) 11537(* ------------------------------------------------------------------------- *) 11538 11539val CONTINUOUS_AT_COMPOSE_EQ = store_thm ("CONTINUOUS_AT_COMPOSE_EQ", 11540 ``!f:real->real g:real->real h:real->real. 11541 g continuous at x /\ h continuous at (g x) /\ 11542 (!y. g(h y) = y) /\ (h(g x) = x) 11543 ==> ((f continuous at (g x) <=> (\x. f(g x)) continuous at x))``, 11544 REPEAT STRIP_TAC THEN EQ_TAC THEN 11545 ASM_SIMP_TAC std_ss [REWRITE_RULE[o_DEF] CONTINUOUS_AT_COMPOSE] THEN 11546 DISCH_TAC THEN 11547 SUBGOAL_THEN 11548 ``((f:real->real) o (g:real->real) o (h:real->real)) 11549 continuous at (g(x:real))`` 11550 MP_TAC THENL 11551 [REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN 11552 ASM_REWRITE_TAC[o_DEF], 11553 ASM_SIMP_TAC std_ss [o_DEF, ETA_AX]]); 11554 11555val CONTINUOUS_AT_TRANSLATION = store_thm ("CONTINUOUS_AT_TRANSLATION", 11556 ``!a z f:real->real. 11557 f continuous at (a + z) <=> (\x. f(a + x)) continuous at z``, 11558 REPEAT GEN_TAC THEN 11559 ONCE_REWRITE_TAC [METIS [] ``a + z = (\z. a + z) z:real``] THEN 11560 MATCH_MP_TAC CONTINUOUS_AT_COMPOSE_EQ THEN 11561 EXISTS_TAC ``\x:real. x - a`` THEN 11562 SIMP_TAC std_ss [CONTINUOUS_ADD, CONTINUOUS_SUB, 11563 CONTINUOUS_AT_ID, CONTINUOUS_CONST] THEN 11564 REAL_ARITH_TAC); 11565 11566(* ------------------------------------------------------------------------- *) 11567(* Interior of an injective image. *) 11568(* ------------------------------------------------------------------------- *) 11569 11570val INTERIOR_IMAGE_SUBSET = store_thm ("INTERIOR_IMAGE_SUBSET", 11571 ``!f:real->real s. 11572 (!x. f continuous at x) /\ (!x y. (f x = f y) ==> (x = y)) 11573 ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)``, 11574 REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET_DEF] THEN 11575 SIMP_TAC std_ss [interior, GSPECIFICATION] THEN 11576 X_GEN_TAC ``y:real`` THEN 11577 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 11578 SIMP_TAC std_ss [IN_IMAGE, GSPECIFICATION] THEN 11579 SUBGOAL_THEN ``y IN IMAGE (f:real->real) s`` MP_TAC THENL 11580 [ASM_SET_TAC[], ALL_TAC] THEN 11581 REWRITE_TAC[IN_IMAGE] THEN 11582 STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN 11583 ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN 11584 EXISTS_TAC ``{x | (f:real->real)(x) IN t}`` THEN 11585 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN CONJ_TAC THENL 11586 [MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN ASM_MESON_TAC[], 11587 ASM_SET_TAC[]]); 11588 11589(* ------------------------------------------------------------------------- *) 11590(* Making a continuous function avoid some value in a neighbourhood. *) 11591(* ------------------------------------------------------------------------- *) 11592 11593val CONTINUOUS_WITHIN_AVOID = store_thm ("CONTINUOUS_WITHIN_AVOID", 11594 ``!f:real->real x s a. 11595 f continuous (at x within s) /\ x IN s /\ ~(f x = a) 11596 ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)``, 11597 REPEAT STRIP_TAC THEN 11598 UNDISCH_TAC ``f continuous (at x within s)`` THEN DISCH_TAC THEN 11599 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [continuous_within]) THEN 11600 DISCH_THEN(MP_TAC o SPEC ``abs((f:real->real) x - a)``) THEN 11601 ASM_REWRITE_TAC[GSYM ABS_NZ, REAL_SUB_0] THEN 11602 DISCH_THEN (X_CHOOSE_TAC ``d:real``) THEN EXISTS_TAC ``d:real`` THEN 11603 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN 11604 REWRITE_TAC[] THEN DISCH_TAC THEN X_GEN_TAC ``y:real`` THEN 11605 POP_ASSUM (MP_TAC o SPEC ``y:real``) THEN 11606 MATCH_MP_TAC MONO_IMP THEN SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 11607 11608val CONTINUOUS_AT_AVOID = store_thm ("CONTINUOUS_AT_AVOID", 11609 ``!f:real->real x a. 11610 f continuous (at x) /\ ~(f x = a) 11611 ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)``, 11612 MP_TAC CONTINUOUS_WITHIN_AVOID THEN 11613 DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN 11614 POP_ASSUM (MP_TAC o SPECL [``f:real->real``,``x:real``]) THEN 11615 DISCH_THEN(MP_TAC o SPEC ``univ(:real)``) THEN 11616 DISCH_TAC THEN X_GEN_TAC ``a:real`` THEN POP_ASSUM (MP_TAC o SPEC ``a:real``) THEN 11617 REWRITE_TAC[WITHIN_UNIV, IN_UNIV]); 11618 11619val CONTINUOUS_ON_AVOID = store_thm ("CONTINUOUS_ON_AVOID", 11620 ``!f:real->real x s a. 11621 f continuous_on s /\ x IN s /\ ~(f x = a) 11622 ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)``, 11623 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 11624 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_WITHIN_AVOID THEN 11625 ASM_SIMP_TAC std_ss []); 11626 11627val CONTINUOUS_ON_OPEN_AVOID = store_thm ("CONTINUOUS_ON_OPEN_AVOID", 11628 ``!f:real->real x s a. 11629 f continuous_on s /\ open s /\ x IN s /\ ~(f x = a) 11630 ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)``, 11631 REPEAT GEN_TAC THEN ASM_CASES_TAC ``open(s:real->bool)`` THEN 11632 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_AT] THEN 11633 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_AVOID THEN 11634 ASM_SIMP_TAC std_ss []); 11635 11636(* ------------------------------------------------------------------------- *) 11637(* Proving a function is constant by proving open-ness of level set. *) 11638(* ------------------------------------------------------------------------- *) 11639 11640val CONTINUOUS_LEVELSET_OPEN_IN_CASES = store_thm ("CONTINUOUS_LEVELSET_OPEN_IN_CASES", 11641 ``!f:real->real s a. 11642 connected s /\ 11643 f continuous_on s /\ 11644 open_in (subtopology euclidean s) {x | x IN s /\ (f x = a)} 11645 ==> (!x. x IN s ==> ~(f x = a)) \/ (!x. x IN s ==> (f x = a))``, 11646 REWRITE_TAC[SET_RULE ``(!x. x IN s ==> ~(f x = a)) <=> 11647 ({x | x IN s /\ (f x = a)} = {})``, 11648 SET_RULE ``(!x. x IN s ==> (f x = a)) <=> 11649 ({x | x IN s /\ (f x = a)} = s)``] THEN 11650 REWRITE_TAC[CONNECTED_CLOPEN] THEN REPEAT STRIP_TAC THEN 11651 FIRST_X_ASSUM MATCH_MP_TAC THEN 11652 ASM_SIMP_TAC std_ss [CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT]); 11653 11654val CONTINUOUS_LEVELSET_OPEN_IN = store_thm ("CONTINUOUS_LEVELSET_OPEN_IN", 11655 ``!f:real->real s a. 11656 connected s /\ 11657 f continuous_on s /\ 11658 open_in (subtopology euclidean s) {x | x IN s /\ (f x = a)} /\ 11659 (?x. x IN s /\ (f x = a)) 11660 ==> (!x. x IN s ==> (f x = a))``, 11661 METIS_TAC[CONTINUOUS_LEVELSET_OPEN_IN_CASES]); 11662 11663val CONTINUOUS_LEVELSET_OPEN = store_thm ("CONTINUOUS_LEVELSET_OPEN", 11664 ``!f:real->real s a. 11665 connected s /\ 11666 f continuous_on s /\ 11667 open {x | x IN s /\ (f x = a)} /\ 11668 (?x. x IN s /\ (f x = a)) 11669 ==> (!x. x IN s ==> (f x = a))``, 11670 REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 11671 MATCH_MP_TAC CONTINUOUS_LEVELSET_OPEN_IN THEN 11672 ASM_REWRITE_TAC[OPEN_IN_OPEN] THEN 11673 EXISTS_TAC ``{x | x IN s /\ ((f:real->real) x = a)}`` THEN 11674 ASM_REWRITE_TAC[] THEN SET_TAC[]); 11675 11676(* ------------------------------------------------------------------------- *) 11677(* Some arithmetical combinations (more to prove). *) 11678(* ------------------------------------------------------------------------- *) 11679 11680val OPEN_SCALING = store_thm ("OPEN_SCALING", 11681 ``!s:real->bool c. ~(c = &0) /\ open s ==> open(IMAGE (\x. c * x) s)``, 11682 REPEAT GEN_TAC THEN SIMP_TAC std_ss [open_def, FORALL_IN_IMAGE] THEN 11683 STRIP_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 11684 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 11685 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 11686 EXISTS_TAC ``e * abs(c:real)`` THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL, GSYM ABS_NZ] THEN 11687 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN 11688 EXISTS_TAC ``inv(c) * y:real`` THEN 11689 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_MUL_LID] THEN 11690 FIRST_X_ASSUM MATCH_MP_TAC THEN 11691 SUBGOAL_THEN ``x = inv(c) * c * x:real`` SUBST1_TAC THENL 11692 [ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID], 11693 REWRITE_TAC[dist, GSYM REAL_MUL_ASSOC, GSYM REAL_SUB_LDISTRIB, ABS_MUL] THEN 11694 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC std_ss [ABS_INV] THEN 11695 ASM_SIMP_TAC std_ss [GSYM real_div, REAL_LT_LDIV_EQ, GSYM ABS_NZ] THEN 11696 ASM_REWRITE_TAC[GSYM dist]]); 11697 11698val OPEN_NEGATIONS = store_thm ("OPEN_NEGATIONS", 11699 ``!s:real->bool. open s ==> open (IMAGE (\x. -x) s)``, 11700 SUBGOAL_THEN ``(\x. -x) = \x:real. -(&1) * x`` 11701 (fn th => SIMP_TAC std_ss [th, OPEN_SCALING, REAL_ARITH ``~(-(&1) = &0:real)``]) THEN 11702 REWRITE_TAC[FUN_EQ_THM] THEN REAL_ARITH_TAC); 11703 11704val OPEN_TRANSLATION = store_thm ("OPEN_TRANSLATION", 11705 ``!s a:real. open s ==> open(IMAGE (\x. a + x) s)``, 11706 REPEAT STRIP_TAC THEN 11707 MP_TAC(ISPECL [``\x:real. x - a``, ``s:real->bool``] 11708 CONTINUOUS_OPEN_PREIMAGE_UNIV) THEN 11709 ASM_SIMP_TAC std_ss [CONTINUOUS_SUB, CONTINUOUS_AT_ID, CONTINUOUS_CONST] THEN 11710 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 11711 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE, IN_UNIV] THEN 11712 ASM_MESON_TAC[REAL_ARITH ``(a + x) - a = x:real``, 11713 REAL_ARITH ``a + (x - a) = x:real``]); 11714 11715val OPEN_TRANSLATION_EQ = store_thm ("OPEN_TRANSLATION_EQ", 11716 ``!a s. open (IMAGE (\x:real. a + x) s) <=> open s``, 11717 REPEAT GEN_TAC THEN EQ_TAC THENL 11718 [ALL_TAC, REWRITE_TAC [OPEN_TRANSLATION]] THEN 11719 REWRITE_TAC [open_def] THEN DISCH_TAC THEN GEN_TAC THEN 11720 DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN 11721 KNOW_TAC ``a + x IN IMAGE (\x:real. a + x) s`` THENL 11722 [SIMP_TAC std_ss [IN_IMAGE, REAL_EQ_LADD] THEN METIS_TAC [], 11723 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 11724 STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC [] THEN 11725 GEN_TAC THEN DISCH_TAC THEN FULL_SIMP_TAC std_ss [dist, IN_IMAGE] THEN 11726 FIRST_X_ASSUM (MP_TAC o SPEC ``a + x':real``) THEN 11727 ASM_SIMP_TAC real_ss [REAL_ARITH ``a + b - (a + c) = b - c:real``] THEN 11728 REWRITE_TAC [REAL_EQ_LADD] THEN METIS_TAC []); 11729 11730val OPEN_AFFINITY = store_thm ("OPEN_AFFINITY", 11731 ``!s a:real c. 11732 open s /\ ~(c = &0) ==> open (IMAGE (\x. a + c * x) s)``, 11733 REPEAT STRIP_TAC THEN 11734 SUBGOAL_THEN ``(\x:real. a + c * x) = (\x. a + x) o (\x. c * x)`` 11735 SUBST1_TAC THENL [REWRITE_TAC[o_DEF], ALL_TAC] THEN 11736 ASM_SIMP_TAC std_ss [IMAGE_COMPOSE, OPEN_TRANSLATION, OPEN_SCALING]); 11737 11738val INTERIOR_TRANSLATION = store_thm ("INTERIOR_TRANSLATION", 11739 ``!a:real s. 11740 interior (IMAGE (\x. a + x) s) = IMAGE (\x. a + x) (interior s)``, 11741 REPEAT STRIP_TAC THEN 11742 KNOW_TAC ``(!t. ?s. IMAGE ((\x. a + x):real->real) s = t)`` THENL 11743 [REWRITE_TAC [SURJECTIVE_IMAGE] THEN GEN_TAC THEN EXISTS_TAC ``-a + y:real`` THEN 11744 SIMP_TAC std_ss [] THEN REAL_ARITH_TAC, DISCH_TAC] THEN 11745 REWRITE_TAC [interior] THEN 11746 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN 11747 GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 11748 [FIRST_ASSUM (MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 11749 DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC [IN_IMAGE] THEN 11750 SIMP_TAC std_ss [] THEN STRIP_TAC THEN EXISTS_TAC ``x':real`` THEN 11751 ASM_REWRITE_TAC [] THEN 11752 FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN STRIP_TAC THEN 11753 EXISTS_TAC ``s':real->bool`` THEN REPEAT CONJ_TAC THENL 11754 [METIS_TAC [OPEN_TRANSLATION_EQ], 11755 UNDISCH_TAC ``IMAGE ((\x. a + x):real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN 11756 DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_SIMP_TAC std_ss [IN_IMAGE] THEN 11757 REWRITE_TAC [REAL_EQ_LADD] THEN METIS_TAC [], 11758 REWRITE_TAC [SUBSET_DEF] THEN X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 11759 UNDISCH_TAC ``IMAGE ((\x. a + x):real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN 11760 DISCH_THEN (MP_TAC o SPEC ``a + y:real``) THEN SIMP_TAC std_ss [IN_IMAGE] THEN 11761 KNOW_TAC ``(?x:real. (a + y = a + x) /\ x IN s')`` THENL 11762 [METIS_TAC [], ALL_TAC] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11763 DISCH_TAC THEN UNDISCH_TAC ``t SUBSET IMAGE ((\x. a + x):real->real) s`` THEN 11764 REWRITE_TAC [SUBSET_DEF] THEN DISCH_THEN (MP_TAC o SPEC ``a + y:real``) THEN 11765 ASM_REWRITE_TAC [] THEN SIMP_TAC std_ss [IN_IMAGE, REAL_EQ_LADD]], ALL_TAC] THEN 11766 FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN 11767 STRIP_TAC THEN EXISTS_TAC ``IMAGE (\x:real. a + x) t`` THEN 11768 REPEAT CONJ_TAC THENL 11769 [METIS_TAC [OPEN_TRANSLATION_EQ], 11770 SIMP_TAC std_ss [IN_IMAGE] THEN EXISTS_TAC ``x':real`` THEN 11771 ASM_REWRITE_TAC [], 11772 MATCH_MP_TAC IMAGE_SUBSET THEN ASM_REWRITE_TAC []]); 11773 11774val OPEN_SUMS = store_thm ("OPEN_SUMS", 11775 ``!s t:real->bool. 11776 open s \/ open t ==> open {x + y | x IN s /\ y IN t}``, 11777 REPEAT GEN_TAC THEN REWRITE_TAC[open_def] THEN STRIP_TAC THEN 11778 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 11779 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THENL 11780 [FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``), 11781 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``)] THEN 11782 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN 11783 EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN 11784 X_GEN_TAC ``z:real`` THEN DISCH_TAC THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN 11785 METIS_TAC[REAL_ADD_SYM, REAL_ARITH ``(z - y) + y:real = z``, dist, 11786 REAL_ARITH ``abs(z:real - (x + y)) < e ==> abs(z - y - x) < e``]); 11787 11788(* ------------------------------------------------------------------------- *) 11789(* Upper and lower hemicontinuous functions, relation in the case of *) 11790(* preimage map to open and closed maps, and fact that upper and lower *) 11791(* hemicontinuity together imply continuity in the sense of the Hausdorff *) 11792(* metric (at points where the function gives a bounded and nonempty set). *) 11793(* ------------------------------------------------------------------------- *) 11794 11795val UPPER_HEMICONTINUOUS = store_thm ("UPPER_HEMICONTINUOUS", 11796 ``!f:real->real->bool t s. 11797 (!x. x IN s ==> f(x) SUBSET t) 11798 ==> ((!u. open_in (subtopology euclidean t) u 11799 ==> open_in (subtopology euclidean s) 11800 {x | x IN s /\ f(x) SUBSET u}) <=> 11801 (!u. closed_in (subtopology euclidean t) u 11802 ==> closed_in (subtopology euclidean s) 11803 {x | x IN s /\ ~(f(x) INTER u = {})}))``, 11804 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 11805 FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN 11806 MATCH_MP_TAC MONO_IMP THEN 11807 SIMP_TAC std_ss [OPEN_IN_DIFF, CLOSED_IN_DIFF, OPEN_IN_REFL, CLOSED_IN_REFL] THENL 11808 [REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ], REWRITE_TAC[closed_in]] THEN 11809 SIMP_TAC std_ss [TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, SUBSET_RESTRICT] THEN 11810 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]); 11811 11812val LOWER_HEMICONTINUOUS = store_thm ("LOWER_HEMICONTINUOUS", 11813 ``!f:real->real->bool t s. 11814 (!x. x IN s ==> f(x) SUBSET t) 11815 ==> ((!u. closed_in (subtopology euclidean t) u 11816 ==> closed_in (subtopology euclidean s) 11817 {x | x IN s /\ f(x) SUBSET u}) <=> 11818 (!u. open_in (subtopology euclidean t) u 11819 ==> open_in (subtopology euclidean s) 11820 {x | x IN s /\ ~(f(x) INTER u = {})}))``, 11821 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 11822 FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN 11823 MATCH_MP_TAC MONO_IMP THEN 11824 SIMP_TAC std_ss [OPEN_IN_DIFF, CLOSED_IN_DIFF, OPEN_IN_REFL, CLOSED_IN_REFL] THENL 11825 [REWRITE_TAC[closed_in], REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ]] THEN 11826 SIMP_TAC std_ss [TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, SUBSET_RESTRICT] THEN 11827 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]); 11828 11829val OPEN_MAP_IFF_LOWER_HEMICONTINUOUS_PREIMAGE = store_thm ("OPEN_MAP_IFF_LOWER_HEMICONTINUOUS_PREIMAGE", 11830 ``!f:real->real s t. 11831 IMAGE f s SUBSET t 11832 ==> ((!u. open_in (subtopology euclidean s) u 11833 ==> open_in (subtopology euclidean t) (IMAGE f u)) <=> 11834 (!u. closed_in (subtopology euclidean s) u 11835 ==> closed_in (subtopology euclidean t) 11836 {y | y IN t /\ 11837 {x | x IN s /\ (f x = y)} SUBSET u}))``, 11838 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 11839 [X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN 11840 FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN 11841 ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL] THEN 11842 SIMP_TAC std_ss [OPEN_IN_CLOSED_IN_EQ, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 11843 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 11844 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 11845 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[], 11846 X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN 11847 FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN 11848 ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL] THEN 11849 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 11850 REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 11851 DISCH_THEN(fn th => CONJ_TAC THENL [ASM_SET_TAC[], MP_TAC th]) THEN 11852 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]]); 11853 11854val CLOSED_MAP_IFF_UPPER_HEMICONTINUOUS_PREIMAGE = store_thm ("CLOSED_MAP_IFF_UPPER_HEMICONTINUOUS_PREIMAGE", 11855 ``!f:real->real s t. 11856 IMAGE f s SUBSET t 11857 ==> ((!u. closed_in (subtopology euclidean s) u 11858 ==> closed_in (subtopology euclidean t) (IMAGE f u)) <=> 11859 (!u. open_in (subtopology euclidean s) u 11860 ==> open_in (subtopology euclidean t) 11861 {y | y IN t /\ 11862 {x | x IN s /\ (f x = y)} SUBSET u}))``, 11863 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 11864 [X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN 11865 FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN 11866 ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL] THEN 11867 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 11868 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 11869 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 11870 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[], 11871 X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN 11872 FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN 11873 ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL] THEN 11874 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 11875 REWRITE_TAC[closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 11876 DISCH_THEN(fn th => CONJ_TAC THENL [ASM_SET_TAC[], MP_TAC th]) THEN 11877 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]]); 11878 11879val UPPER_LOWER_HEMICONTINUOUS_EXPLICIT = store_thm ("UPPER_LOWER_HEMICONTINUOUS_EXPLICIT", 11880 ``!f:real->real->bool t s. 11881 (!x. x IN s ==> f(x) SUBSET t) /\ 11882 (!u. open_in (subtopology euclidean t) u 11883 ==> open_in (subtopology euclidean s) 11884 {x | x IN s /\ f(x) SUBSET u}) /\ 11885 (!u. closed_in (subtopology euclidean t) u 11886 ==> closed_in (subtopology euclidean s) 11887 {x | x IN s /\ f(x) SUBSET u}) 11888 ==> !x e. x IN s /\ &0 < e /\ bounded(f x) /\ ~(f x = {}) 11889 ==> ?d. &0 < d /\ 11890 !x'. x' IN s /\ dist(x,x') < d 11891 ==> (!y. y IN f x 11892 ==> ?y'. y' IN f x' /\ dist(y,y') < e) /\ 11893 (!y'. y' IN f x' 11894 ==> ?y. y IN f x /\ dist(y',y) < e)``, 11895 REPEAT STRIP_TAC THEN 11896 UNDISCH_TAC 11897 ``!u. open_in (subtopology euclidean t) u 11898 ==> open_in (subtopology euclidean s) 11899 {x | x IN s /\ (f:real->real->bool)(x) SUBSET u}`` THEN 11900 DISCH_THEN(MP_TAC o SPEC 11901 ``t INTER 11902 {a + b | a IN (f:real->real->bool) x /\ b IN ball(0,e)}``) THEN 11903 SIMP_TAC std_ss [OPEN_SUMS, OPEN_BALL, OPEN_IN_OPEN_INTER] THEN 11904 SIMP_TAC std_ss [open_in, SUBSET_RESTRICT] THEN 11905 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 11906 ASM_SIMP_TAC std_ss [GSPECIFICATION, SUBSET_INTER] THEN 11907 KNOW_TAC ``(f :real -> real -> bool) (x :real) SUBSET 11908 {a + b | a IN f x /\ b IN ball ((0 :real),(e :real))}`` THENL 11909 [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN 11910 METIS_TAC[CENTRE_IN_BALL, REAL_ADD_RID], 11911 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 11912 DISCH_THEN(X_CHOOSE_THEN ``d1:real`` 11913 (CONJUNCTS_THEN2 ASSUME_TAC ASSUME_TAC))] THEN 11914 UNDISCH_TAC 11915 ``!u. closed_in (subtopology euclidean t) u 11916 ==> closed_in (subtopology euclidean s) 11917 {x | x IN s /\ (f:real->real->bool)(x) SUBSET u}`` THEN 11918 ASM_SIMP_TAC std_ss [LOWER_HEMICONTINUOUS] THEN DISCH_THEN(MP_TAC o 11919 GEN ``a:real`` o SPEC ``t INTER ball(a:real,e / &2)``) THEN 11920 SIMP_TAC std_ss [OPEN_BALL, OPEN_IN_OPEN_INTER] THEN 11921 MP_TAC(SPEC ``closure((f:real->real->bool) x)`` 11922 COMPACT_EQ_HEINE_BOREL) THEN 11923 ASM_REWRITE_TAC[COMPACT_CLOSURE] THEN DISCH_THEN(MP_TAC o SPEC 11924 ``{ball(a:real,e / &2) | a IN (f:real->real->bool) x}``) THEN 11925 SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, OPEN_BALL] THEN 11926 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN 11927 SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE] THEN 11928 KNOW_TAC ``closure ((f :real -> real -> bool) (x :real)) SUBSET 11929 BIGUNION (IMAGE (\(a :real). ball (a,(e :real) / (2 :real))) (f x))`` THENL 11930 [SIMP_TAC std_ss [CLOSURE_APPROACHABLE, SUBSET_DEF, BIGUNION_IMAGE, GSPECIFICATION] THEN 11931 REWRITE_TAC[IN_BALL] THEN ASM_SIMP_TAC std_ss [REAL_HALF], 11932 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 11933 DISCH_THEN(X_CHOOSE_THEN ``c:real->bool`` STRIP_ASSUME_TAC) THEN 11934 DISCH_TAC THEN FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP 11935 (METIS[CLOSURE_SUBSET, SUBSET_TRANS] 11936 ``closure s SUBSET t ==> s SUBSET t``)) THEN 11937 SUBGOAL_THEN 11938 ``open_in (subtopology euclidean s) 11939 (BIGINTER {{x | x IN s /\ 11940 ~((f:real->real->bool) x INTER t INTER ball(a,e / &2) = {})} | 11941 a IN c})`` 11942 MP_TAC THENL 11943 [MATCH_MP_TAC OPEN_IN_BIGINTER THEN 11944 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, IMAGE_FINITE, 11945 GSYM INTER_ASSOC] THEN ASM_SIMP_TAC std_ss [IMAGE_EQ_EMPTY] THEN 11946 ASM_SET_TAC[], ALL_TAC] THEN 11947 REWRITE_TAC[open_in] THEN 11948 DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN 11949 KNOW_TAC ``(x :real) IN 11950 BIGINTER {{x | 11951 x IN (s :real -> bool) /\ 11952 (f :real -> real -> bool) x INTER (t :real -> bool) INTER 11953 ball (a,(e :real) / (2 :real)) <> ({} :real -> bool)} | 11954 a IN (c :real -> bool)}`` THENL 11955 [SIMP_TAC std_ss [BIGINTER_GSPEC, GSPECIFICATION] THEN 11956 X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN 11957 ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN 11958 EXISTS_TAC ``a:real`` THEN 11959 ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, REAL_HALF] THEN 11960 ASM_SET_TAC[], 11961 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 11962 DISCH_THEN(X_CHOOSE_THEN ``d2:real`` 11963 (CONJUNCTS_THEN2 ASSUME_TAC ASSUME_TAC))] THEN 11964 EXISTS_TAC ``min d1 d2:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 11965 X_GEN_TAC ``x':real`` THEN STRIP_TAC THEN CONJ_TAC THENL 11966 [ALL_TAC, 11967 UNDISCH_TAC ``!x'':real. 11968 x'' IN s /\ dist (x'',x) < d1 ==> 11969 f x'' SUBSET {a + b | a IN f x /\ b IN ball (0,e)}`` THEN 11970 DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC ``x':real``) THEN 11971 ASM_REWRITE_TAC[] THEN 11972 KNOW_TAC ``dist (x',x) < d1:real`` THENL 11973 [ASM_MESON_TAC[DIST_SYM], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 11974 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD, IN_BALL] THEN 11975 SIMP_TAC std_ss [REAL_ARITH ``(x:real = a + b) <=> (x - a = b)``, 11976 DIST_0, ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN 11977 REWRITE_TAC[dist]] THEN 11978 UNDISCH_TAC ``!x':real. 11979 x' IN s /\ dist (x',x) < d2 ==> 11980 x' IN 11981 BIGINTER 11982 {{x | x IN s /\ f x INTER t INTER ball (a,e / 2) <> {}} | 11983 a IN c}`` THEN DISCH_TAC THEN 11984 FIRST_X_ASSUM (MP_TAC o SPEC ``x':real``) THEN 11985 ASM_SIMP_TAC std_ss [BIGINTER_GSPEC, GSPECIFICATION] THEN 11986 KNOW_TAC ``dist (x',x) < d2:real`` THENL 11987 [ASM_MESON_TAC[DIST_SYM], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 11988 DISCH_TAC THEN 11989 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 11990 UNDISCH_TAC ``(f:real->real->bool) x SUBSET 11991 BIGUNION (IMAGE (\a. ball (a,e / &2)) c)`` THEN 11992 REWRITE_TAC[SUBSET_DEF] THEN DISCH_THEN(MP_TAC o SPEC ``y:real``) THEN 11993 ASM_SIMP_TAC std_ss [BIGUNION_IMAGE, GSPECIFICATION, IN_BALL] THEN 11994 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 11995 UNDISCH_TAC ``!(a' :real). 11996 a' IN (c :real -> bool) ==> 11997 (f :real -> real -> bool) (x' :real) INTER 11998 (t :real -> bool) INTER ball (a',(e :real) / (2 :real)) <> 11999 ({} :real -> bool)`` THEN DISCH_TAC THEN 12000 FIRST_X_ASSUM (MP_TAC o SPEC ``a:real``) THEN 12001 ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER, IN_BALL] THEN 12002 DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN 12003 POP_ASSUM MP_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 12004 METIS_TAC[DIST_TRIANGLE_HALF_L, DIST_SYM]); 12005 12006(* ------------------------------------------------------------------------- *) 12007(* Connected components, considered as a "connectedness" relation or a set. *) 12008(* ------------------------------------------------------------------------- *) 12009 12010val connected_component = new_definition ("connected_component", 12011 ``connected_component s x y <=> 12012 ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t``); 12013 12014val CONNECTED_COMPONENT_IN = store_thm ("CONNECTED_COMPONENT_IN", 12015 ``!s x y. connected_component s x y ==> x IN s /\ y IN s``, 12016 REWRITE_TAC[connected_component] THEN SET_TAC[]); 12017 12018val CONNECTED_COMPONENT_REFL = store_thm ("CONNECTED_COMPONENT_REFL", 12019 ``!s x:real. x IN s ==> connected_component s x x``, 12020 REWRITE_TAC[connected_component] THEN REPEAT STRIP_TAC THEN 12021 EXISTS_TAC ``{x:real}`` THEN REWRITE_TAC[CONNECTED_SING] THEN 12022 ASM_SET_TAC[]); 12023 12024val CONNECTED_COMPONENT_REFL_EQ = store_thm ("CONNECTED_COMPONENT_REFL_EQ", 12025 ``!s x:real. connected_component s x x <=> x IN s``, 12026 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_REFL] THEN 12027 REWRITE_TAC[connected_component] THEN SET_TAC[]); 12028 12029val CONNECTED_COMPONENT_SYM = store_thm ("CONNECTED_COMPONENT_SYM", 12030 ``!s x y:real. connected_component s x y ==> connected_component s y x``, 12031 REWRITE_TAC[connected_component] THEN MESON_TAC[]); 12032 12033val CONNECTED_COMPONENT_TRANS = store_thm ("CONNECTED_COMPONENT_TRANS", 12034 ``!s x y:real. 12035 connected_component s x y /\ connected_component s y z 12036 ==> connected_component s x z``, 12037 REPEAT GEN_TAC THEN REWRITE_TAC[connected_component] THEN 12038 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC ``t:real->bool``) 12039 (X_CHOOSE_TAC ``u:real->bool``)) THEN 12040 EXISTS_TAC ``t UNION u:real->bool`` THEN 12041 ASM_REWRITE_TAC[IN_UNION, UNION_SUBSET] THEN 12042 MATCH_MP_TAC CONNECTED_UNION THEN ASM_SET_TAC[]); 12043 12044val CONNECTED_COMPONENT_OF_SUBSET = store_thm ("CONNECTED_COMPONENT_OF_SUBSET", 12045 ``!s t x. s SUBSET t /\ connected_component s x y 12046 ==> connected_component t x y``, 12047 REWRITE_TAC[connected_component] THEN SET_TAC[]); 12048 12049val CONNECTED_COMPONENT_SET = store_thm ("CONNECTED_COMPONENT_SET", 12050 ``!s x. connected_component s x = 12051 { y | ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t}``, 12052 SIMP_TAC std_ss [GSPECIFICATION, EXTENSION] THEN 12053 SIMP_TAC std_ss [IN_DEF, connected_component]); 12054 12055val CONNECTED_COMPONENT_BIGUNION = store_thm ("CONNECTED_COMPONENT_BIGUNION", 12056 ``!s x. connected_component s x = 12057 BIGUNION {t | connected t /\ x IN t /\ t SUBSET s}``, 12058 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]); 12059 12060val CONNECTED_COMPONENT_SUBSET = store_thm ("CONNECTED_COMPONENT_SUBSET", 12061 ``!s x. (connected_component s x) SUBSET s``, 12062 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]); 12063 12064val CONNECTED_CONNECTED_COMPONENT_SET = store_thm ("CONNECTED_CONNECTED_COMPONENT_SET", 12065 ``!s. connected s <=> !x:real. x IN s ==> (connected_component s x = s)``, 12066 GEN_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_BIGUNION] THEN EQ_TAC THENL 12067 [SET_TAC[], ALL_TAC] THEN 12068 ASM_CASES_TAC ``s:real->bool = {}`` THEN 12069 ASM_REWRITE_TAC[CONNECTED_EMPTY] THEN 12070 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 12071 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 12072 DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN ASM_REWRITE_TAC[] THEN 12073 DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC CONNECTED_BIGUNION THEN 12074 ASM_SET_TAC[]); 12075 12076val CONNECTED_COMPONENT_UNIV = store_thm ("CONNECTED_COMPONENT_UNIV", 12077 ``!x. connected_component univ(:real) x = univ(:real)``, 12078 MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET, CONNECTED_UNIV, IN_UNIV]); 12079 12080val CONNECTED_COMPONENT_EQ_UNIV = store_thm ("CONNECTED_COMPONENT_EQ_UNIV", 12081 ``!s x. (connected_component s x = univ(:real)) <=> (s = univ(:real))``, 12082 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CONNECTED_COMPONENT_UNIV] THEN 12083 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (s = UNIV) ==> (t = UNIV)``) THEN 12084 REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]); 12085 12086val CONNECTED_COMPONENT_EQ_SELF = store_thm ("CONNECTED_COMPONENT_EQ_SELF", 12087 ``!s x. connected s /\ x IN s ==> (connected_component s x = s)``, 12088 MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET]); 12089 12090val CONNECTED_IFF_CONNECTED_COMPONENT = store_thm ("CONNECTED_IFF_CONNECTED_COMPONENT", 12091 ``!s. connected s <=> 12092 !x y. x IN s /\ y IN s ==> connected_component s x y``, 12093 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT_SET] THEN 12094 REWRITE_TAC[EXTENSION] THEN MESON_TAC[IN_DEF, CONNECTED_COMPONENT_IN]); 12095 12096val CONNECTED_COMPONENT_MAXIMAL = store_thm ("CONNECTED_COMPONENT_MAXIMAL", 12097 ``!s t x:real. 12098 x IN t /\ connected t /\ t SUBSET s 12099 ==> t SUBSET (connected_component s x)``, 12100 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]); 12101 12102val CONNECTED_COMPONENT_MONO = store_thm ("CONNECTED_COMPONENT_MONO", 12103 ``!s t x. s SUBSET t 12104 ==> (connected_component s x) SUBSET (connected_component t x)``, 12105 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]); 12106 12107val CONNECTED_CONNECTED_COMPONENT = store_thm ("CONNECTED_CONNECTED_COMPONENT", 12108 ``!s x. connected(connected_component s x)``, 12109 REWRITE_TAC[CONNECTED_COMPONENT_BIGUNION] THEN 12110 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_BIGUNION THEN SET_TAC[]); 12111 12112val CONNECTED_COMPONENT_EQ_EMPTY = store_thm ("CONNECTED_COMPONENT_EQ_EMPTY", 12113 ``!s x:real. (connected_component s x = {}) <=> ~(x IN s)``, 12114 REPEAT GEN_TAC THEN EQ_TAC THENL 12115 [REWRITE_TAC[EXTENSION, NOT_IN_EMPTY] THEN 12116 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 12117 SIMP_TAC std_ss [IN_DEF, CONNECTED_COMPONENT_REFL_EQ], 12118 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]]); 12119 12120val CONNECTED_COMPONENT_EMPTY = store_thm ("CONNECTED_COMPONENT_EMPTY", 12121 ``!x. connected_component {} x = {}``, 12122 REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY, NOT_IN_EMPTY]); 12123 12124val CONNECTED_COMPONENT_EQ = store_thm ("CONNECTED_COMPONENT_EQ", 12125 ``!s x y. y IN connected_component s x 12126 ==> ((connected_component s y = connected_component s x))``, 12127 REWRITE_TAC[EXTENSION, IN_DEF] THEN 12128 MESON_TAC[CONNECTED_COMPONENT_SYM, CONNECTED_COMPONENT_TRANS]); 12129 12130val CLOSED_CONNECTED_COMPONENT = store_thm ("CLOSED_CONNECTED_COMPONENT", 12131 ``!s x:real. closed s ==> closed(connected_component s x)``, 12132 REPEAT STRIP_TAC THEN 12133 ASM_CASES_TAC ``(x:real) IN s`` THENL 12134 [ALL_TAC, ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY, CLOSED_EMPTY]] THEN 12135 REWRITE_TAC[GSYM CLOSURE_EQ] THEN 12136 MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[CLOSURE_SUBSET] THEN 12137 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN 12138 SIMP_TAC std_ss [CONNECTED_CLOSURE, CONNECTED_CONNECTED_COMPONENT] THEN 12139 CONJ_TAC THENL 12140 [MATCH_MP_TAC(REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET) THEN 12141 ASM_SIMP_TAC std_ss [IN_DEF, CONNECTED_COMPONENT_REFL_EQ], 12142 MATCH_MP_TAC CLOSURE_MINIMAL THEN 12143 ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_SUBSET]]); 12144 12145val CONNECTED_COMPONENT_DISJOINT = store_thm ("CONNECTED_COMPONENT_DISJOINT", 12146 ``!s a b. DISJOINT (connected_component s a) (connected_component s b) <=> 12147 ~(a IN connected_component s b)``, 12148 REWRITE_TAC[DISJOINT_DEF, EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN 12149 REWRITE_TAC[IN_DEF] THEN 12150 MESON_TAC[CONNECTED_COMPONENT_SYM, CONNECTED_COMPONENT_TRANS]); 12151 12152val CONNECTED_COMPONENT_NONOVERLAP = store_thm ("CONNECTED_COMPONENT_NONOVERLAP", 12153 ``!s a b:real. 12154 ((connected_component s a) INTER (connected_component s b) = {}) <=> 12155 ~(a IN s) \/ ~(b IN s) \/ 12156 ~(connected_component s a = connected_component s b)``, 12157 REPEAT GEN_TAC THEN 12158 ASM_CASES_TAC ``(a:real) IN s`` THEN ASM_REWRITE_TAC[] THEN 12159 RULE_ASSUM_TAC(SIMP_RULE std_ss [GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN 12160 ASM_SIMP_TAC std_ss [INTER_EMPTY] THEN 12161 ASM_CASES_TAC ``(b:real) IN s`` THEN ASM_REWRITE_TAC[] THEN 12162 RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN 12163 ASM_REWRITE_TAC[INTER_EMPTY] THEN ASM_CASES_TAC 12164 ``connected_component s (a:real) = connected_component s b`` THEN 12165 ASM_REWRITE_TAC[INTER_IDEMPOT, CONNECTED_COMPONENT_EQ_EMPTY] THEN 12166 POP_ASSUM MP_TAC THEN 12167 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 12168 REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN 12169 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM DISJOINT_DEF]) THEN 12170 REWRITE_TAC[CONNECTED_COMPONENT_DISJOINT]); 12171 12172val CONNECTED_COMPONENT_OVERLAP = store_thm ("CONNECTED_COMPONENT_OVERLAP", 12173 ``!s a b:real. 12174 ~((connected_component s a) INTER (connected_component s b) = {}) <=> 12175 a IN s /\ b IN s /\ 12176 (connected_component s a = connected_component s b)``, 12177 REWRITE_TAC[CONNECTED_COMPONENT_NONOVERLAP, DE_MORGAN_THM]); 12178 12179val CONNECTED_COMPONENT_SYM_EQ = store_thm ("CONNECTED_COMPONENT_SYM_EQ", 12180 ``!s x y. connected_component s x y <=> connected_component s y x``, 12181 MESON_TAC[CONNECTED_COMPONENT_SYM]); 12182 12183val CONNECTED_COMPONENT_EQ_EQ = store_thm ("CONNECTED_COMPONENT_EQ_EQ", 12184 ``!s x y:real. 12185 (connected_component s x = connected_component s y) <=> 12186 ~(x IN s) /\ ~(y IN s) \/ 12187 x IN s /\ y IN s /\ connected_component s x y``, 12188 REPEAT GEN_TAC THEN ASM_CASES_TAC ``(y:real) IN s`` THENL 12189 [ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_REWRITE_TAC[] THENL 12190 [REWRITE_TAC[FUN_EQ_THM] THEN 12191 ASM_MESON_TAC[CONNECTED_COMPONENT_TRANS, CONNECTED_COMPONENT_REFL, 12192 CONNECTED_COMPONENT_SYM], 12193 ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]], 12194 RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN 12195 ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY] THEN 12196 ONCE_REWRITE_TAC[CONNECTED_COMPONENT_SYM_EQ] THEN 12197 ASM_REWRITE_TAC[EMPTY_DEF] THEN ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]]); 12198 12199val CONNECTED_EQ_CONNECTED_COMPONENT_EQ = store_thm ("CONNECTED_EQ_CONNECTED_COMPONENT_EQ", 12200 ``!s. connected s <=> 12201 !x y. x IN s /\ y IN s 12202 ==> (connected_component s x = connected_component s y)``, 12203 SIMP_TAC std_ss [CONNECTED_COMPONENT_EQ_EQ] THEN 12204 REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT]); 12205 12206val CONNECTED_COMPONENT_IDEMP = store_thm ("CONNECTED_COMPONENT_IDEMP", 12207 ``!s x:real. connected_component (connected_component s x) x = 12208 connected_component s x``, 12209 REWRITE_TAC[FUN_EQ_THM, connected_component] THEN 12210 REPEAT GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN EQ_TAC THEN 12211 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 12212 ASM_MESON_TAC[CONNECTED_COMPONENT_MAXIMAL, SUBSET_TRANS, 12213 CONNECTED_COMPONENT_SUBSET]); 12214 12215val CONNECTED_COMPONENT_UNIQUE = store_thm ("CONNECTED_COMPONENT_UNIQUE", 12216 ``!s c x:real. 12217 x IN c /\ c SUBSET s /\ connected c /\ 12218 (!c'. x IN c' /\ c' SUBSET s /\ connected c' 12219 ==> c' SUBSET c) 12220 ==> (connected_component s x = c)``, 12221 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 12222 [FIRST_X_ASSUM MATCH_MP_TAC THEN 12223 REWRITE_TAC[CONNECTED_COMPONENT_SUBSET, CONNECTED_CONNECTED_COMPONENT] THEN 12224 REWRITE_TAC[IN_DEF] THEN ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_REFL_EQ] THEN 12225 ASM_SET_TAC[], 12226 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]]); 12227 12228val JOINABLE_CONNECTED_COMPONENT_EQ = store_thm ("JOINABLE_CONNECTED_COMPONENT_EQ", 12229 ``!s t x y:real. 12230 connected t /\ t SUBSET s /\ 12231 ~(connected_component s x INTER t = {}) /\ 12232 ~(connected_component s y INTER t = {}) 12233 ==> (connected_component s x = connected_component s y)``, 12234 REPEAT GEN_TAC THEN 12235 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 12236 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 12237 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER] THEN DISCH_THEN(CONJUNCTS_THEN2 12238 (X_CHOOSE_THEN ``w:real`` STRIP_ASSUME_TAC) 12239 (X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC)) THEN 12240 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN 12241 SIMP_TAC std_ss [IN_DEF] THEN 12242 MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN 12243 EXISTS_TAC ``z:real`` THEN CONJ_TAC THENL [ASM_MESON_TAC[IN_DEF], ALL_TAC] THEN 12244 MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN 12245 EXISTS_TAC ``w:real`` THEN CONJ_TAC THENL 12246 [REWRITE_TAC[connected_component] THEN 12247 EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[], 12248 ASM_MESON_TAC[IN_DEF, CONNECTED_COMPONENT_SYM]]); 12249 12250val BIGUNION_CONNECTED_COMPONENT = store_thm ("BIGUNION_CONNECTED_COMPONENT", 12251 ``!s:real->bool. BIGUNION {connected_component s x |x| x IN s} = s``, 12252 GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 12253 SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_GSPEC, CONNECTED_COMPONENT_SUBSET] THEN 12254 SIMP_TAC std_ss [SUBSET_DEF, BIGUNION_GSPEC, GSPECIFICATION] THEN 12255 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN EXISTS_TAC ``x:real`` THEN 12256 ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN_DEF] THEN 12257 ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_REFL_EQ]); 12258 12259val COMPLEMENT_CONNECTED_COMPONENT_BIGUNION = store_thm ("COMPLEMENT_CONNECTED_COMPONENT_BIGUNION", 12260 ``!s x:real. 12261 s DIFF connected_component s x = 12262 BIGUNION({connected_component s y | y | y IN s} DELETE 12263 (connected_component s x))``, 12264 REPEAT GEN_TAC THEN 12265 GEN_REWR_TAC (LAND_CONV o LAND_CONV) 12266 [GSYM BIGUNION_CONNECTED_COMPONENT] THEN 12267 MATCH_MP_TAC(SET_RULE 12268 ``(!x. x IN s DELETE a ==> DISJOINT a x) 12269 ==> (BIGUNION s DIFF a = BIGUNION (s DELETE a))``) THEN 12270 SIMP_TAC std_ss [CONJ_EQ_IMP, FORALL_IN_GSPEC, IN_DELETE] THEN 12271 SIMP_TAC std_ss [CONNECTED_COMPONENT_DISJOINT, CONNECTED_COMPONENT_EQ_EQ] THEN 12272 MESON_TAC[IN_DEF, SUBSET_DEF, CONNECTED_COMPONENT_SUBSET]); 12273 12274val CLOSED_IN_CONNECTED_COMPONENT = store_thm ("CLOSED_IN_CONNECTED_COMPONENT", 12275 ``!s x:real. closed_in (subtopology euclidean s) (connected_component s x)``, 12276 REPEAT GEN_TAC THEN 12277 ASM_CASES_TAC ``connected_component s (x:real) = {}`` THEN 12278 ASM_REWRITE_TAC[CLOSED_IN_EMPTY] THEN 12279 RULE_ASSUM_TAC(REWRITE_RULE[CONNECTED_COMPONENT_EQ_EMPTY]) THEN 12280 REWRITE_TAC[CLOSED_IN_CLOSED] THEN 12281 EXISTS_TAC ``closure(connected_component s x):real->bool`` THEN 12282 REWRITE_TAC[CLOSED_CLOSURE] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 12283 REWRITE_TAC[SUBSET_INTER, CONNECTED_COMPONENT_SUBSET, CLOSURE_SUBSET] THEN 12284 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN REWRITE_TAC[INTER_SUBSET] THEN 12285 CONJ_TAC THENL 12286 [ASM_REWRITE_TAC[IN_INTER] THEN 12287 MATCH_MP_TAC(REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET) THEN 12288 ASM_SIMP_TAC std_ss [IN_DEF, CONNECTED_COMPONENT_REFL_EQ], 12289 MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN 12290 EXISTS_TAC ``connected_component s (x:real)`` THEN 12291 SIMP_TAC std_ss [INTER_SUBSET, CONNECTED_CONNECTED_COMPONENT, 12292 SUBSET_INTER, CONNECTED_COMPONENT_SUBSET, CLOSURE_SUBSET]]); 12293 12294val BIGUNION_DIFF = store_thm ("BIGUNION_DIFF", 12295 ``!s t. BIGUNION s DIFF t = BIGUNION {x DIFF t | x IN s}``, 12296 SIMP_TAC std_ss [BIGUNION_GSPEC] THEN SET_TAC[]); 12297 12298val OPEN_IN_CONNECTED_COMPONENT = store_thm ("OPEN_IN_CONNECTED_COMPONENT", 12299 ``!s x:real. 12300 FINITE {connected_component s x |x| x IN s} 12301 ==> open_in (subtopology euclidean s) (connected_component s x)``, 12302 REPEAT STRIP_TAC THEN 12303 SUBGOAL_THEN 12304 ``connected_component s (x:real) = 12305 s DIFF (BIGUNION {connected_component s y |y| y IN s} DIFF 12306 connected_component s x)`` 12307 SUBST1_TAC THENL 12308 [REWRITE_TAC[BIGUNION_CONNECTED_COMPONENT] THEN 12309 MATCH_MP_TAC(SET_RULE ``t SUBSET s ==> (t = s DIFF (s DIFF t))``) THEN 12310 SIMP_TAC std_ss [CONNECTED_COMPONENT_SUBSET], 12311 MATCH_MP_TAC OPEN_IN_DIFF THEN 12312 SIMP_TAC std_ss [OPEN_IN_SUBTOPOLOGY_REFL, TOPSPACE_EUCLIDEAN, SUBSET_UNIV] THEN 12313 SIMP_TAC std_ss [BIGUNION_DIFF] THEN 12314 MATCH_MP_TAC CLOSED_IN_BIGUNION THEN SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 12315 CONJ_TAC THENL [METIS_TAC [GSYM IMAGE_DEF, IMAGE_FINITE], ALL_TAC] THEN 12316 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 12317 SUBGOAL_THEN 12318 ``(connected_component s y DIFF connected_component s x = 12319 connected_component s y) \/ 12320 (connected_component s (y:real) DIFF connected_component s x = {})`` 12321 (DISJ_CASES_THEN SUBST1_TAC) 12322 THENL 12323 [MATCH_MP_TAC(SET_RULE 12324 ``(~(s INTER t = {}) ==> (s = t)) ==> (s DIFF t = s) \/ (s DIFF t = {})``) THEN 12325 SIMP_TAC std_ss [CONNECTED_COMPONENT_OVERLAP], 12326 REWRITE_TAC[CLOSED_IN_CONNECTED_COMPONENT], 12327 REWRITE_TAC[CLOSED_IN_EMPTY]]]); 12328 12329val CONNECTED_COMPONENT_EQUIVALENCE_RELATION = store_thm ("CONNECTED_COMPONENT_EQUIVALENCE_RELATION", 12330 ``!R s:real->bool. 12331 (!x y. R x y ==> R y x) /\ 12332 (!x y z. R x y /\ R y z ==> R x z) /\ 12333 (!a. a IN s 12334 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ 12335 !x. x IN t ==> R a x) 12336 ==> !a b. connected_component s a b ==> R a b``, 12337 REPEAT STRIP_TAC THEN 12338 MP_TAC(ISPECL [``R:real->real->bool``, ``connected_component s (a:real)``] 12339 CONNECTED_EQUIVALENCE_RELATION) THEN 12340 ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN 12341 KNOW_TAC ``(!(a' :real). 12342 a' IN connected_component (s :real -> bool) (a :real) ==> 12343 ?(t :real -> bool). 12344 open_in (subtopology euclidean (connected_component s a)) t /\ 12345 a' IN t /\ 12346 !(x :real). x IN t ==> (R :real -> real -> bool) a' x)`` THENL 12347 [X_GEN_TAC ``c:real`` THEN DISCH_TAC THEN 12348 FIRST_X_ASSUM(MP_TAC o SPEC ``c:real``) THEN 12349 KNOW_TAC ``(c :real) IN (s :real -> bool)`` THENL 12350 [ASM_MESON_TAC[CONNECTED_COMPONENT_SUBSET, SUBSET_DEF], 12351 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 12352 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 12353 EXISTS_TAC ``t INTER connected_component s (a:real)`` THEN 12354 ASM_SIMP_TAC std_ss [IN_INTER, OPEN_IN_OPEN] THEN 12355 UNDISCH_TAC ``open_in (subtopology euclidean s) t`` THEN DISCH_TAC THEN 12356 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN]) THEN 12357 SIMP_TAC std_ss [] THEN 12358 MP_TAC(ISPECL [``s:real->bool``, ``a:real``] 12359 CONNECTED_COMPONENT_SUBSET) THEN 12360 SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 12361 DISCH_THEN MATCH_MP_TAC THEN ASM_SIMP_TAC std_ss [IN_DEF] THEN 12362 REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN 12363 ASM_MESON_TAC[CONNECTED_COMPONENT_IN]]); 12364 12365val CONNECTED_COMPONENT_INTERMEDIATE_SUBSET = store_thm ("CONNECTED_COMPONENT_INTERMEDIATE_SUBSET", 12366 ``!t u a:real. 12367 connected_component u a SUBSET t /\ t SUBSET u 12368 ==> (connected_component t a = connected_component u a)``, 12369 REPEAT GEN_TAC THEN ASM_CASES_TAC ``(a:real) IN u`` THENL 12370 [REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_UNIQUE THEN 12371 ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN 12372 CONJ_TAC THENL [ASM_MESON_TAC[CONNECTED_COMPONENT_REFL, IN_DEF], ALL_TAC] THEN 12373 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN 12374 ASM_SET_TAC[], 12375 ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY, SUBSET_DEF]]); 12376 12377(* ------------------------------------------------------------------------- *) 12378(* The set of connected components of a set. *) 12379(* ------------------------------------------------------------------------- *) 12380 12381val components = new_definition ("components", 12382 ``components s = {connected_component s x | x | x:real IN s}``); 12383 12384val IN_COMPONENTS = store_thm ("IN_COMPONENTS", 12385 ``!u:real->bool s. s IN components u 12386 <=> ?x. x IN u /\ (s = connected_component u x)``, 12387 REPEAT GEN_TAC THEN REWRITE_TAC[components] THEN EQ_TAC 12388 THENL [SET_TAC[], STRIP_TAC THEN ASM_SIMP_TAC std_ss [] THEN 12389 UNDISCH_TAC ``x:real IN u`` THEN SET_TAC[]]); 12390 12391val BIGUNION_COMPONENTS = store_thm 12392 ("BIGUNION_COMPONENTS", 12393 ``!u:real->bool. u = BIGUNION (components u)``, 12394 REWRITE_TAC [EXTENSION] 12395 >> REPEAT GEN_TAC >> EQ_TAC 12396 >| [ (* goal 1 (of 2) *) 12397 DISCH_TAC >> REWRITE_TAC [IN_BIGUNION] \\ 12398 EXISTS_TAC ``connected_component (u:real->bool) x`` \\ 12399 CONJ_TAC >| 12400 [ REWRITE_TAC [CONNECTED_COMPONENT_SET] \\ 12401 SUBGOAL_THEN ``?s:real->bool. connected s /\ s SUBSET u /\ x IN s`` MP_TAC >| 12402 [ EXISTS_TAC ``{x:real}`` \\ 12403 ASM_REWRITE_TAC [CONNECTED_SING] \\ 12404 POP_ASSUM MP_TAC >> SET_TAC [], 12405 SET_TAC [] ], 12406 REWRITE_TAC [components] >> ASM_SET_TAC [] ], 12407 (* goal 2 of 2 *) 12408 REWRITE_TAC [IN_BIGUNION] \\ 12409 STRIP_TAC \\ 12410 MATCH_MP_TAC (SET_RULE ``!x:real s u. x IN s /\ s SUBSET u ==> x IN u``) \\ 12411 EXISTS_TAC ``s :real -> bool`` >> ASM_REWRITE_TAC [] \\ 12412 `?(y :real). ((s :real -> bool) = connected_component u y)` 12413 by METIS_TAC [IN_COMPONENTS] \\ 12414 ASM_REWRITE_TAC [CONNECTED_COMPONENT_SUBSET] ]); 12415 12416val PAIRWISE_DISJOINT_COMPONENTS = store_thm ("PAIRWISE_DISJOINT_COMPONENTS", 12417 ``!u:real->bool. pairwise DISJOINT (components u)``, 12418 GEN_TAC THEN REWRITE_TAC[pairwise, DISJOINT_DEF] THEN 12419 MAP_EVERY X_GEN_TAC [``s:real->bool``, ``t:real->bool``] THEN STRIP_TAC THEN 12420 ASSERT_TAC ``(?a. s:real->bool = connected_component u a) /\ 12421 ?b. t:real->bool = connected_component u b`` 12422 THENL [ASM_MESON_TAC[IN_COMPONENTS], 12423 ASM_MESON_TAC[CONNECTED_COMPONENT_NONOVERLAP]]); 12424 12425val IN_COMPONENTS_NONEMPTY = store_thm ("IN_COMPONENTS_NONEMPTY", 12426 ``!s c. c IN components s ==> ~(c = {})``, 12427 REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN 12428 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY]); 12429 12430val IN_COMPONENTS_SUBSET = store_thm ("IN_COMPONENTS_SUBSET", 12431 ``!s c. c IN components s ==> c SUBSET s``, 12432 REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN 12433 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]); 12434 12435val IN_COMPONENTS_CONNECTED = store_thm ("IN_COMPONENTS_CONNECTED", 12436 ``!s c. c IN components s ==> connected c``, 12437 REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN 12438 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT]); 12439 12440val IN_COMPONENTS_MAXIMAL = store_thm ("IN_COMPONENTS_MAXIMAL", 12441 ``!s c:real->bool. 12442 c IN components s <=> 12443 ~(c = {}) /\ c SUBSET s /\ connected c /\ 12444 !c'. ~(c' = {}) /\ c SUBSET c' /\ c' SUBSET s /\ connected c' 12445 ==> (c' = c)``, 12446 REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN EQ_TAC THENL 12447 [DISCH_THEN(X_CHOOSE_THEN ``x:real`` STRIP_ASSUME_TAC) THEN 12448 ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY, CONNECTED_COMPONENT_SUBSET, 12449 CONNECTED_CONNECTED_COMPONENT] THEN 12450 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 12451 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN 12452 ASM_MESON_TAC[CONNECTED_COMPONENT_REFL, IN_DEF, SUBSET_DEF], 12453 STRIP_TAC THEN 12454 UNDISCH_TAC ``(c:real->bool) <> {}`` THEN DISCH_TAC THEN 12455 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 12456 STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN CONJ_TAC THENL 12457 [ALL_TAC, ASM_SET_TAC[]] THEN 12458 MATCH_MP_TAC(GSYM CONNECTED_COMPONENT_UNIQUE) THEN 12459 ASM_REWRITE_TAC[] THEN X_GEN_TAC ``c':real->bool`` THEN STRIP_TAC THEN 12460 REWRITE_TAC[SET_RULE ``c' SUBSET c <=> (c' UNION c = c)``] THEN 12461 FIRST_X_ASSUM MATCH_MP_TAC THEN 12462 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 12463 MATCH_MP_TAC CONNECTED_UNION THEN ASM_SET_TAC[]]); 12464 12465val JOINABLE_COMPONENTS_EQ = store_thm ("JOINABLE_COMPONENTS_EQ", 12466 ``!s t c1 c2. 12467 connected t /\ t SUBSET s /\ 12468 c1 IN components s /\ c2 IN components s /\ 12469 ~(c1 INTER t = {}) /\ ~(c2 INTER t = {}) 12470 ==> (c1 = c2)``, 12471 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, components, FORALL_IN_GSPEC] THEN 12472 MESON_TAC[JOINABLE_CONNECTED_COMPONENT_EQ]); 12473 12474val CLOSED_IN_COMPONENT = store_thm ("CLOSED_IN_COMPONENT", 12475 ``!s c:real->bool. 12476 c IN components s ==> closed_in (subtopology euclidean s) c``, 12477 SIMP_TAC std_ss [components, FORALL_IN_GSPEC, CLOSED_IN_CONNECTED_COMPONENT]); 12478 12479val CLOSED_COMPONENTS = store_thm ("CLOSED_COMPONENTS", 12480 ``!s c. closed s /\ c IN components s ==> closed c``, 12481 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, components, FORALL_IN_GSPEC] THEN 12482 SIMP_TAC std_ss [CLOSED_CONNECTED_COMPONENT]); 12483 12484val COMPACT_COMPONENTS = store_thm ("COMPACT_COMPONENTS", 12485 ``!s c:real->bool. compact s /\ c IN components s ==> compact c``, 12486 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN 12487 MESON_TAC[CLOSED_COMPONENTS, IN_COMPONENTS_SUBSET, BOUNDED_SUBSET]); 12488 12489val CONTINUOUS_ON_COMPONENTS_GEN = store_thm ("CONTINUOUS_ON_COMPONENTS_GEN", 12490 ``!f:real->real s. 12491 (!c. c IN components s 12492 ==> open_in (subtopology euclidean s) c /\ f continuous_on c) 12493 ==> f continuous_on s``, 12494 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN 12495 DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN 12496 SUBGOAL_THEN 12497 ``{x | x IN s /\ (f:real->real) x IN t} = 12498 BIGUNION {{x | x IN c /\ f x IN t} | c IN components s}`` 12499 SUBST1_TAC THENL 12500 [GEN_REWR_TAC LAND_CONV [METIS [BIGUNION_COMPONENTS] ``{x | x IN s /\ f x IN t} = 12501 {x | x IN BIGUNION (components s) /\ f x IN t}``] THEN 12502 SIMP_TAC std_ss [BIGUNION_GSPEC, IN_BIGUNION] THEN SET_TAC[], 12503 MATCH_MP_TAC OPEN_IN_BIGUNION THEN SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 12504 METIS_TAC[OPEN_IN_TRANS]]); 12505 12506val CONTINUOUS_ON_COMPONENTS_FINITE = store_thm ("CONTINUOUS_ON_COMPONENTS_FINITE", 12507 ``!f:real->real s. 12508 FINITE(components s) /\ 12509 (!c. c IN components s ==> f continuous_on c) 12510 ==> f continuous_on s``, 12511 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN 12512 DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN 12513 SUBGOAL_THEN 12514 ``{x | x IN s /\ (f:real->real) x IN t} = 12515 BIGUNION {{x | x IN c /\ f x IN t} | c IN components s}`` 12516 SUBST1_TAC THENL 12517 [GEN_REWR_TAC LAND_CONV [METIS [BIGUNION_COMPONENTS] ``{x | x IN s /\ f x IN t} = 12518 {x | x IN BIGUNION (components s) /\ f x IN t}``] THEN 12519 SIMP_TAC std_ss [BIGUNION_GSPEC, IN_BIGUNION] THEN SET_TAC[], 12520 MATCH_MP_TAC CLOSED_IN_BIGUNION THEN 12521 ASM_SIMP_TAC std_ss [GSYM IMAGE_DEF, IMAGE_FINITE, FORALL_IN_IMAGE] THEN 12522 METIS_TAC[CLOSED_IN_TRANS, CLOSED_IN_COMPONENT]]); 12523 12524val COMPONENTS_NONOVERLAP = store_thm ("COMPONENTS_NONOVERLAP", 12525 ``!s c c'. c IN components s /\ c' IN components s 12526 ==> ((c INTER c' = {}) <=> ~(c = c'))``, 12527 SIMP_TAC std_ss [components, GSPECIFICATION] THEN REPEAT STRIP_TAC THEN 12528 ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_NONOVERLAP]); 12529 12530val COMPONENTS_EQ = store_thm ("COMPONENTS_EQ", 12531 ``!s c c'. c IN components s /\ c' IN components s 12532 ==> ((c = c') <=> ~(c INTER c' = {}))``, 12533 MESON_TAC[COMPONENTS_NONOVERLAP]); 12534 12535val COMPONENTS_EQ_EMPTY = store_thm ("COMPONENTS_EQ_EMPTY", 12536 ``!s. (components s = {}) <=> (s = {})``, 12537 GEN_TAC THEN REWRITE_TAC[EXTENSION] THEN 12538 SIMP_TAC std_ss [components, connected_component, GSPECIFICATION] THEN 12539 SET_TAC[]); 12540 12541val COMPONENTS_EMPTY = store_thm ("COMPONENTS_EMPTY", 12542 ``components {} = {}``, 12543 REWRITE_TAC[COMPONENTS_EQ_EMPTY]); 12544 12545val CONNECTED_EQ_CONNECTED_COMPONENTS_EQ = store_thm ("CONNECTED_EQ_CONNECTED_COMPONENTS_EQ", 12546 ``!s. connected s <=> 12547 !c c'. c IN components s /\ c' IN components s ==> (c = c')``, 12548 SIMP_TAC std_ss [components, GSPECIFICATION] THEN 12549 MESON_TAC[CONNECTED_EQ_CONNECTED_COMPONENT_EQ]); 12550 12551val COMPONENTS_EQ_SING_N_EXISTS = store_thm ("COMPONENTS_EQ_SING_N_EXISTS", 12552 ``(!s:real->bool. (components s = {s}) <=> connected s /\ ~(s = {})) /\ 12553 (!s:real->bool. (?a. (components s = {a})) <=> connected s /\ ~(s = {}))``, 12554 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN X_GEN_TAC ``s:real->bool`` THEN 12555 MATCH_MP_TAC(TAUT `(p ==> q) /\ (q ==> r) /\ (r ==> p) 12556 ==> (p <=> r) /\ (q <=> r)`) THEN 12557 REPEAT CONJ_TAC THENL 12558 [MESON_TAC[], 12559 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENTS_EQ] THEN 12560 ASM_MESON_TAC[IN_SING, COMPONENTS_EQ_EMPTY, NOT_INSERT_EMPTY], 12561 STRIP_TAC THEN ONCE_REWRITE_TAC[EXTENSION] THEN 12562 REWRITE_TAC[IN_SING] THEN 12563 SIMP_TAC std_ss [components, GSPECIFICATION] THEN 12564 ASM_MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET, MEMBER_NOT_EMPTY]]); 12565 12566val COMPONENTS_EQ_SING = store_thm ("COMPONENTS_EQ_SING", 12567 ``(!s:real->bool. (components s = {s}) <=> connected s /\ ~(s = {}))``, 12568 REWRITE_TAC [COMPONENTS_EQ_SING_N_EXISTS]); 12569 12570val COMPONENTS_EQ_SING_EXISTS = store_thm ("COMPONENTS_EQ_SING_EXISTS", 12571 `` (!s:real->bool. (?a. (components s = {a})) <=> connected s /\ ~(s = {}))``, 12572 REWRITE_TAC [COMPONENTS_EQ_SING_N_EXISTS]); 12573 12574val COMPONENTS_UNIV = store_thm ("COMPONENTS_UNIV", 12575 ``components univ(:real) = {univ(:real)}``, 12576 REWRITE_TAC[COMPONENTS_EQ_SING, CONNECTED_UNIV, UNIV_NOT_EMPTY]); 12577 12578val CONNECTED_EQ_COMPONENTS_SUBSET_SING = store_thm ("CONNECTED_EQ_COMPONENTS_SUBSET_SING", 12579 ``!s:real->bool. connected s <=> components s SUBSET {s}``, 12580 GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 12581 ASM_REWRITE_TAC[COMPONENTS_EMPTY, CONNECTED_EMPTY, EMPTY_SUBSET] THEN 12582 REWRITE_TAC[SET_RULE ``s SUBSET {a} <=> (s = {}) \/ (s = {a})``] THEN 12583 ASM_REWRITE_TAC[COMPONENTS_EQ_EMPTY, COMPONENTS_EQ_SING]); 12584 12585val CONNECTED_EQ_COMPONENTS_SUBSET_SING_EXISTS = store_thm ("CONNECTED_EQ_COMPONENTS_SUBSET_SING_EXISTS", 12586 ``!s:real->bool. connected s <=> ?a. components s SUBSET {a}``, 12587 GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 12588 ASM_REWRITE_TAC[COMPONENTS_EMPTY, CONNECTED_EMPTY, EMPTY_SUBSET] THEN 12589 REWRITE_TAC[SET_RULE ``s SUBSET {a} <=> (s = {}) \/ (s = {a})``] THEN 12590 ASM_REWRITE_TAC[COMPONENTS_EQ_EMPTY, COMPONENTS_EQ_SING_EXISTS]); 12591 12592val IN_COMPONENTS_SELF = store_thm ("IN_COMPONENTS_SELF", 12593 ``!s:real->bool. s IN components s <=> connected s /\ ~(s = {})``, 12594 GEN_TAC THEN EQ_TAC THENL 12595 [MESON_TAC[IN_COMPONENTS_NONEMPTY, IN_COMPONENTS_CONNECTED], 12596 SIMP_TAC std_ss [GSYM COMPONENTS_EQ_SING, IN_SING]]); 12597 12598val COMPONENTS_MAXIMAL = store_thm ("COMPONENTS_MAXIMAL", 12599 ``!s t c:real->bool. 12600 c IN components s /\ connected t /\ t SUBSET s /\ ~(c INTER t = {}) 12601 ==> t SUBSET c``, 12602 SIMP_TAC std_ss [CONJ_EQ_IMP, components, FORALL_IN_GSPEC] THEN 12603 REPEAT STRIP_TAC THEN 12604 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 12605 SIMP_TAC std_ss [IN_INTER, LEFT_IMP_EXISTS_THM] THEN 12606 X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 12607 FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP CONNECTED_COMPONENT_EQ) THEN 12608 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]); 12609 12610val COMPONENTS_UNIQUE = store_thm ("COMPONENTS_UNIQUE", 12611 ``!s:real->bool k. 12612 (BIGUNION k = s) /\ 12613 (!c. c IN k 12614 ==> connected c /\ ~(c = {}) /\ 12615 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> (c' = c)) 12616 ==> (components s = k)``, 12617 REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 12618 X_GEN_TAC ``c:real->bool`` THEN REWRITE_TAC[IN_COMPONENTS] THEN 12619 EQ_TAC THENL 12620 [DISCH_THEN(X_CHOOSE_THEN ``x:real`` 12621 (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN 12622 UNDISCH_TAC `` !c. c IN k ==> 12623 connected c /\ c <> {} /\ 12624 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> (c' = c)`` THEN DISCH_TAC THEN 12625 FIRST_ASSUM(MP_TAC o SPEC ``x:real`` o REWRITE_RULE [EXTENSION]) THEN 12626 REWRITE_TAC[IN_BIGUNION] THEN ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 12627 X_GEN_TAC ``c:real->bool`` THEN STRIP_TAC THEN 12628 SUBGOAL_THEN ``connected_component s (x:real) = c`` 12629 (fn th => ASM_REWRITE_TAC[th]) THEN 12630 MATCH_MP_TAC CONNECTED_COMPONENT_UNIQUE THEN 12631 FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN 12632 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 12633 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 12634 X_GEN_TAC ``c':real->bool`` THEN STRIP_TAC THEN 12635 REWRITE_TAC[SET_RULE ``c' SUBSET c <=> (c' UNION c = c)``] THEN 12636 FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL 12637 [MATCH_MP_TAC CONNECTED_UNION, ASM_SET_TAC[]] THEN 12638 ASM_SET_TAC[], 12639 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN 12640 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN 12641 UNDISCH_TAC ``c <> {}:real->bool`` THEN DISCH_TAC THEN 12642 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 12643 STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN 12644 CONJ_TAC THENL [ASM_SET_TAC[], CONV_TAC SYM_CONV] THEN 12645 FIRST_X_ASSUM MATCH_MP_TAC THEN 12646 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT, CONNECTED_COMPONENT_SUBSET] THEN 12647 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN 12648 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]]); 12649 12650val COMPONENTS_UNIQUE_EQ = store_thm ("COMPONENTS_UNIQUE_EQ", 12651 ``!s:real->bool k. 12652 (components s = k) <=> 12653 (BIGUNION k = s) /\ 12654 (!c. c IN k 12655 ==> connected c /\ ~(c = {}) /\ 12656 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> (c' = c))``, 12657 REPEAT GEN_TAC THEN EQ_TAC THENL 12658 [DISCH_THEN(SUBST1_TAC o SYM), REWRITE_TAC[COMPONENTS_UNIQUE]] THEN 12659 REWRITE_TAC[GSYM BIGUNION_COMPONENTS] THEN 12660 X_GEN_TAC ``c:real->bool`` THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL 12661 [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED], 12662 ASM_MESON_TAC[IN_COMPONENTS_NONEMPTY], 12663 RULE_ASSUM_TAC(REWRITE_RULE[IN_COMPONENTS_MAXIMAL]) THEN 12664 ASM_MESON_TAC[SUBSET_EMPTY]]); 12665 12666val EXISTS_COMPONENT_SUPERSET = store_thm ("EXISTS_COMPONENT_SUPERSET", 12667 ``!s t:real->bool. 12668 t SUBSET s /\ ~(s = {}) /\ connected t 12669 ==> ?c. c IN components s /\ t SUBSET c``, 12670 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``t:real->bool = {}`` THENL 12671 [ASM_REWRITE_TAC[EMPTY_SUBSET] THEN 12672 ASM_MESON_TAC[COMPONENTS_EQ_EMPTY, MEMBER_NOT_EMPTY], 12673 FIRST_X_ASSUM(X_CHOOSE_TAC ``a:real`` o 12674 REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 12675 EXISTS_TAC ``connected_component s (a:real)`` THEN 12676 REWRITE_TAC[IN_COMPONENTS] THEN CONJ_TAC THENL 12677 [ASM_SET_TAC[], ASM_MESON_TAC[CONNECTED_COMPONENT_MAXIMAL]]]); 12678 12679val COMPONENTS_INTERMEDIATE_SUBSET = store_thm ("COMPONENTS_INTERMEDIATE_SUBSET", 12680 ``!s t u:real->bool. 12681 s IN components u /\ s SUBSET t /\ t SUBSET u 12682 ==> s IN components t``, 12683 REPEAT GEN_TAC THEN SIMP_TAC std_ss [IN_COMPONENTS, GSYM LEFT_EXISTS_AND_THM] THEN 12684 MESON_TAC[CONNECTED_COMPONENT_INTERMEDIATE_SUBSET, SUBSET_DEF, 12685 CONNECTED_COMPONENT_REFL, IN_DEF, CONNECTED_COMPONENT_SUBSET]); 12686 12687val IN_COMPONENTS_BIGUNION_COMPLEMENT = store_thm ("IN_COMPONENTS_BIGUNION_COMPLEMENT", 12688 ``!s c:real->bool. 12689 c IN components s 12690 ==> (s DIFF c = BIGUNION(components s DELETE c))``, 12691 SIMP_TAC std_ss [components, FORALL_IN_GSPEC, 12692 COMPLEMENT_CONNECTED_COMPONENT_BIGUNION]); 12693 12694val CONNECTED_SUBSET_CLOPEN = store_thm ("CONNECTED_SUBSET_CLOPEN", 12695 ``!u s c:real->bool. 12696 closed_in (subtopology euclidean u) s /\ 12697 open_in (subtopology euclidean u) s /\ 12698 connected c /\ c SUBSET u /\ ~(c INTER s = {}) 12699 ==> c SUBSET s``, 12700 REPEAT STRIP_TAC THEN 12701 UNDISCH_TAC ``connected c`` THEN DISCH_TAC THEN 12702 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [CONNECTED_CLOSED_IN]) THEN 12703 SIMP_TAC std_ss [NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o 12704 SPECL [``c INTER s:real->bool``, ``c DIFF s:real->bool``]) THEN 12705 KNOW_TAC ``~((((closed_in (subtopology euclidean (c :real -> bool)) 12706 (c INTER (s :real -> bool)) /\ 12707 closed_in (subtopology euclidean c) (c DIFF s)) /\ 12708 (c SUBSET c INTER s UNION (c DIFF s))) /\ 12709 (c INTER s INTER (c DIFF s) = ({} :real -> bool))) /\ 12710 ~(c SUBSET s)) ==> c SUBSET s`` THENL 12711 [ALL_TAC, METIS_TAC [CONJ_ASSOC, SET_RULE ``(c DIFF s = {}) <=> c SUBSET s``]] THEN 12712 MATCH_MP_TAC(TAUT `p ==> ~(p /\ ~q) ==> q`) THEN 12713 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 12714 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 12715 CONJ_TAC THENL 12716 [UNDISCH_TAC ``closed_in (subtopology euclidean u) s`` THEN DISCH_TAC THEN 12717 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [CLOSED_IN_CLOSED]), 12718 UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN DISCH_TAC THEN 12719 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN])] THEN 12720 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 12721 REWRITE_TAC[OPEN_IN_OPEN, CLOSED_IN_CLOSED] THENL 12722 [EXISTS_TAC ``t:real->bool``, EXISTS_TAC ``univ(:real) DIFF t``] THEN 12723 ASM_REWRITE_TAC[GSYM OPEN_CLOSED] THEN ASM_SET_TAC[]); 12724 12725val CLOPEN_BIGUNION_COMPONENTS = store_thm ("CLOPEN_BIGUNION_COMPONENTS", 12726 ``!u s:real->bool. 12727 closed_in (subtopology euclidean u) s /\ 12728 open_in (subtopology euclidean u) s 12729 ==> ?k. k SUBSET components u /\ (s = BIGUNION k)``, 12730 REPEAT STRIP_TAC THEN 12731 EXISTS_TAC ``{c:real->bool | c IN components u /\ ~(c INTER s = {})}`` THEN 12732 SIMP_TAC std_ss [SUBSET_RESTRICT] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 12733 CONJ_TAC THENL 12734 [MP_TAC(ISPEC ``u:real->bool`` BIGUNION_COMPONENTS) THEN 12735 FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN SET_TAC[], 12736 SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_GSPEC] THEN 12737 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_SUBSET_CLOPEN THEN 12738 EXISTS_TAC ``u:real->bool`` THEN 12739 ASM_MESON_TAC[IN_COMPONENTS_CONNECTED, IN_COMPONENTS_SUBSET]]); 12740 12741val CLOPEN_IN_COMPONENTS = store_thm ("CLOPEN_IN_COMPONENTS", 12742 ``!u s:real->bool. 12743 closed_in (subtopology euclidean u) s /\ 12744 open_in (subtopology euclidean u) s /\ 12745 connected s /\ ~(s = {}) 12746 ==> s IN components u``, 12747 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[CONJ_ASSOC] THEN 12748 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 12749 FIRST_ASSUM(MP_TAC o MATCH_MP CLOPEN_BIGUNION_COMPONENTS) THEN 12750 DISCH_THEN(X_CHOOSE_THEN ``k:(real->bool)->bool`` STRIP_ASSUME_TAC) THEN 12751 ASM_CASES_TAC ``k:(real->bool)->bool = {}`` THEN 12752 ASM_REWRITE_TAC[BIGUNION_EMPTY] THEN 12753 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 12754 DISCH_THEN(X_CHOOSE_TAC ``c:real->bool``) THEN 12755 ASM_CASES_TAC ``k = {c:real->bool}`` THENL 12756 [METIS_TAC[BIGUNION_SING, GSYM SING_SUBSET], ALL_TAC] THEN 12757 MATCH_MP_TAC(TAUT `~p ==> p /\ q ==> r`) THEN 12758 SUBGOAL_THEN ``?c':real->bool. c' IN k /\ ~(c = c')`` STRIP_ASSUME_TAC THENL 12759 [ASM_MESON_TAC[SET_RULE 12760 ``a IN s /\ ~(s = {a}) ==> ?b. b IN s /\ ~(b = a)``], 12761 REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENTS_EQ] THEN 12762 DISCH_THEN(MP_TAC o SPECL [``c:real->bool``, ``c':real->bool``]) THEN 12763 ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THEN 12764 MATCH_MP_TAC COMPONENTS_INTERMEDIATE_SUBSET THEN 12765 EXISTS_TAC ``u:real->bool`` THEN 12766 MP_TAC(ISPEC ``u:real->bool`` BIGUNION_COMPONENTS) THEN ASM_SET_TAC[]]); 12767 12768(* ------------------------------------------------------------------------- *) 12769(* Continuity implies uniform continuity on a compact domain. *) 12770(* ------------------------------------------------------------------------- *) 12771 12772val COMPACT_UNIFORMLY_EQUICONTINUOUS = store_thm ("COMPACT_UNIFORMLY_EQUICONTINUOUS", 12773 ``!(fs:(real->real)->bool) s. 12774 (!x e. x IN s /\ &0 < e 12775 ==> ?d. &0 < d /\ 12776 (!f x'. f IN fs /\ x' IN s /\ dist (x',x) < d 12777 ==> dist (f x',f x) < e)) /\ 12778 compact s 12779 ==> !e. &0 < e 12780 ==> ?d. &0 < d /\ 12781 !f x x'. f IN fs /\ x IN s /\ x' IN s /\ dist (x',x) < d 12782 ==> dist(f x',f x) < e``, 12783 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 12784 DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 12785 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 12786 X_GEN_TAC ``d:real->real->real`` THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN 12787 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN 12788 DISCH_THEN(MP_TAC o SPEC 12789 ``{ ball(x:real,d x (e / &2:real)) | x IN s}``) THEN 12790 SIMP_TAC std_ss [FORALL_IN_GSPEC, OPEN_BALL, BIGUNION_GSPEC, SUBSET_DEF, GSPECIFICATION] THEN 12791 KNOW_TAC ``(!(x :real). 12792 x IN (s :real -> bool) ==> 12793 ?(x' :real). 12794 x' IN s /\ 12795 x IN 12796 ball 12797 (x', 12798 (d :real -> real -> real) x' 12799 ((e :real) / (2 :real))))`` THENL 12800 [ASM_MESON_TAC[CENTRE_IN_BALL, REAL_HALF], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 12801 DISCH_THEN (X_CHOOSE_TAC ``k:real``) THEN EXISTS_TAC ``k:real`` THEN 12802 POP_ASSUM MP_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 12803 MAP_EVERY X_GEN_TAC [``f:real->real``, ``u:real``, ``v:real``] THEN 12804 STRIP_TAC THEN FIRST_X_ASSUM(fn th => MP_TAC(SPEC ``v:real`` th) THEN 12805 ASM_REWRITE_TAC[] THEN DISCH_THEN(CHOOSE_THEN MP_TAC)) THEN 12806 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 12807 DISCH_THEN(fn th => 12808 MP_TAC(SPEC ``u:real`` th) THEN MP_TAC(SPEC ``v:real`` th)) THEN 12809 ASM_SIMP_TAC std_ss [DIST_REFL] THEN POP_ASSUM MP_TAC THEN 12810 DISCH_THEN (X_CHOOSE_TAC ``w:real``) THEN ASM_REWRITE_TAC [] THEN 12811 ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN ASM_REWRITE_TAC[IN_BALL] THEN 12812 ONCE_REWRITE_TAC[DIST_SYM] THEN REPEAT STRIP_TAC THEN 12813 FIRST_X_ASSUM(MP_TAC o SPECL [``w:real``, ``e / &2:real``]) THEN 12814 ASM_REWRITE_TAC[REAL_HALF] THEN 12815 DISCH_THEN(MP_TAC o SPEC ``f:real->real`` o CONJUNCT2) THEN 12816 DISCH_THEN(fn th => MP_TAC(SPEC ``u:real`` th) THEN 12817 MP_TAC(SPEC ``v:real`` th)) THEN 12818 ASM_REWRITE_TAC[] THEN GEN_REWR_TAC (LAND_CONV o LAND_CONV) [DIST_SYM] THEN 12819 REWRITE_TAC [dist] THEN GEN_REWR_TAC (RAND_CONV o RAND_CONV o RAND_CONV) [GSYM REAL_HALF] THEN 12820 REAL_ARITH_TAC); 12821 12822val COMPACT_UNIFORMLY_CONTINUOUS = store_thm ("COMPACT_UNIFORMLY_CONTINUOUS", 12823 ``!f:real->real s. 12824 f continuous_on s /\ compact s ==> f uniformly_continuous_on s``, 12825 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on, uniformly_continuous_on] THEN 12826 STRIP_TAC THEN 12827 MP_TAC(ISPECL [``{f:real->real}``, ``s:real->bool``] 12828 COMPACT_UNIFORMLY_EQUICONTINUOUS) THEN 12829 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM, CONJ_EQ_IMP, IN_SING, UNWIND_FORALL_THM2] THEN 12830 ASM_MESON_TAC[]); 12831 12832(* ------------------------------------------------------------------------- *) 12833(* A uniformly convergent limit of continuous functions is continuous. *) 12834(* ------------------------------------------------------------------------- *) 12835 12836val ABS_TRIANGLE_LE = store_thm ("ABS_TRIANGLE_LE", 12837 ``!x y. abs(x) + abs(y) <= e ==> abs(x + y) <= e:real``, 12838 METIS_TAC[REAL_LE_TRANS, ABS_TRIANGLE]); 12839 12840val CONTINUOUS_UNIFORM_LIMIT = store_thm ("CONTINUOUS_UNIFORM_LIMIT", 12841 ``!net f:'a->real->real g s. 12842 ~(trivial_limit net) /\ 12843 eventually (\n. (f n) continuous_on s) net /\ 12844 (!e. &0 < e 12845 ==> eventually (\n. !x. x IN s ==> abs(f n x - g x) < e) net) 12846 ==> g continuous_on s``, 12847 REWRITE_TAC[continuous_on] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN 12848 X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN 12849 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 12850 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &3:real``) THEN 12851 ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT] THEN 12852 UNDISCH_TAC ``eventually 12853 (\n. !x. x IN s ==> 12854 !e. 0 < e ==> 12855 ?d. 0 < d /\ 12856 !x'. x' IN s /\ dist (x',x) < d ==> 12857 dist (f n x',f n x) < e) net`` THEN DISCH_TAC THEN 12858 FIRST_X_ASSUM(fn th => MP_TAC th THEN REWRITE_TAC[AND_IMP_INTRO] THEN 12859 GEN_REWR_TAC LAND_CONV [GSYM EVENTUALLY_AND]) THEN 12860 DISCH_THEN(MP_TAC o MATCH_MP EVENTUALLY_HAPPENS) THEN 12861 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC ``a:'a`` THEN 12862 DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC ``x:real``) ASSUME_TAC) THEN 12863 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``e / &3:real``) THEN 12864 ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT] THEN 12865 DISCH_THEN (X_CHOOSE_TAC ``d:real``) THEN EXISTS_TAC ``d:real`` THEN 12866 POP_ASSUM MP_TAC THEN 12867 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN 12868 DISCH_TAC THEN X_GEN_TAC ``y:real`` THEN POP_ASSUM (MP_TAC o Q.SPEC `y:real`) THEN 12869 DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN 12870 FIRST_X_ASSUM(fn th => 12871 MP_TAC(SPEC ``x:real`` th) THEN MP_TAC(SPEC ``y:real`` th)) THEN 12872 ASM_REWRITE_TAC[] THEN SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 12873 MATCH_MP_TAC(REAL_ARITH ``w <= x + y + z 12874 ==> x * &3 < e ==> y * &3 < e ==> z * &3 < e ==> w < e:real``) THEN 12875 REWRITE_TAC[dist] THEN 12876 SUBST1_TAC(REAL_ARITH 12877 ``(g:real->real) y - g x = 12878 -(f (a:'a) y - g y) + (f a x - g x) + (f a y - f a x)``) THEN 12879 MATCH_MP_TAC ABS_TRIANGLE_LE THEN SIMP_TAC std_ss [ABS_NEG, REAL_LE_LADD] THEN 12880 MATCH_MP_TAC REAL_LE_ADD2 THEN SIMP_TAC std_ss [REAL_LE_REFL] THEN 12881 MATCH_MP_TAC ABS_TRIANGLE_LE THEN REWRITE_TAC[ABS_NEG, REAL_LE_REFL]); 12882 12883(* ------------------------------------------------------------------------- *) 12884(* Topological stuff lifted from and dropped to R *) 12885(* ------------------------------------------------------------------------- *) 12886 12887val OPEN = store_thm ("OPEN", 12888 ``!s. open s <=> 12889 !x. x IN s ==> ?e. &0 < e /\ !x'. abs(x' - x) < e ==> x' IN s``, 12890 REWRITE_TAC[open_def, dist]); 12891 12892val CLOSED = store_thm ("CLOSED", 12893 ``!s. closed s <=> 12894 !x. (!e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ abs(x' - x) < e) 12895 ==> x IN s``, 12896 SIMP_TAC std_ss [open_def, closed_def, dist, IN_DIFF, IN_UNIV] THEN 12897 SET_TAC []); 12898 12899val CONTINUOUS_AT_RANGE = store_thm ("CONTINUOUS_AT_RANGE", 12900 ``!f x. f continuous (at x) <=> 12901 !e. &0 < e 12902 ==> ?d. &0 < d /\ 12903 (!x'. abs(x' - x) < d 12904 ==> abs(f x' - f x) < e)``, 12905 REWRITE_TAC[continuous_at, o_THM, dist] THEN REWRITE_TAC[dist]); 12906 12907val CONTINUOUS_ON_RANGE = store_thm ("CONTINUOUS_ON_RANGE", 12908 ``!f s. f continuous_on s <=> 12909 !x. x IN s 12910 ==> !e. &0 < e 12911 ==> ?d. &0 < d /\ 12912 (!x'. x' IN s /\ abs(x' - x) < d 12913 ==> abs(f x' - f x) < e)``, 12914 REWRITE_TAC[continuous_on, o_THM, dist] THEN REWRITE_TAC[dist]); 12915 12916val CONTINUOUS_ABS_COMPOSE = store_thm ("CONTINUOUS_ABS_COMPOSE", 12917 ``!net f:'a->real. 12918 f continuous net 12919 ==> (\x. abs(f x)) continuous net``, 12920 REPEAT GEN_TAC THEN REWRITE_TAC[continuous, tendsto] THEN 12921 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 12922 MATCH_MP_TAC MONO_IMP THEN 12923 REWRITE_TAC[] THEN 12924 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] EVENTUALLY_MONO) THEN 12925 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 12926 12927val CONTINUOUS_ON_ABS_COMPOSE = store_thm ("CONTINUOUS_ON_ABS_COMPOSE", 12928 ``!f:real->real s. 12929 f continuous_on s 12930 ==> (\x. abs(f x)) continuous_on s``, 12931 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_ABS_COMPOSE]); 12932 12933val CONTINUOUS_AT_ABS = store_thm ("CONTINUOUS_AT_ABS", 12934 ``!x. abs continuous (at x)``, 12935 REWRITE_TAC[CONTINUOUS_AT_RANGE] THEN 12936 METIS_TAC [ABS_SUB_ABS, REAL_LET_TRANS]); 12937 12938val CONTINUOUS_AT_DIST = store_thm ("CONTINUOUS_AT_DIST", 12939 ``!a:real x. (\x. dist(a,x)) continuous (at x)``, 12940 REWRITE_TAC[CONTINUOUS_AT_RANGE, dist] THEN 12941 METIS_TAC[REAL_ARITH ``abs(abs(a:real - x) - abs(a - y)) <= abs(x - y)``, 12942 REAL_LET_TRANS]); 12943 12944val CONTINUOUS_ON_DIST = store_thm ("CONTINUOUS_ON_DIST", 12945 ``!a s. (\x. dist(a,x)) continuous_on s``, 12946 REWRITE_TAC[CONTINUOUS_ON_RANGE, dist] THEN 12947 METIS_TAC [REAL_ARITH ``abs(abs(a:real - x) - abs(a - y)) <= abs(x - y)``, 12948 REAL_LET_TRANS]); 12949 12950(* ------------------------------------------------------------------------- *) 12951(* Hence some handy theorems on distance, diameter etc. of/from a set. *) 12952(* ------------------------------------------------------------------------- *) 12953 12954val COMPACT_ATTAINS_SUP = store_thm ("COMPACT_ATTAINS_SUP", 12955 ``!s. compact s /\ ~(s = {}) 12956 ==> ?x. x IN s /\ !y. y IN s ==> y <= x``, 12957 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN 12958 MP_TAC(SPEC ``s:real->bool`` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN 12959 STRIP_TAC THEN EXISTS_TAC ``sup (s:real->bool)`` THEN ASM_SIMP_TAC std_ss [] THEN 12960 METIS_TAC [CLOSED, REAL_ARITH ``s <= s - e <=> ~(&0 < e:real)``, 12961 REAL_ARITH ``x <= s /\ ~(x <= s - e) ==> abs(x - s) < e:real``]); 12962 12963val COMPACT_ATTAINS_INF = store_thm ("COMPACT_ATTAINS_INF", 12964 ``!s. compact s /\ ~(s = {}) 12965 ==> ?x. x IN s /\ !y. y IN s ==> x <= y``, 12966 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN 12967 MP_TAC(SPEC ``s:real->bool`` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN 12968 STRIP_TAC THEN EXISTS_TAC ``inf (s:real->bool)`` THEN ASM_REWRITE_TAC[] THEN 12969 METIS_TAC[ CLOSED, REAL_ARITH ``s + e <= s <=> ~(&0 < e:real)``, 12970 REAL_ARITH ``s <= x /\ ~(s + e <= x) ==> abs(x - s) < e:real``]); 12971 12972val CONTINUOUS_ATTAINS_SUP = store_thm ("CONTINUOUS_ATTAINS_SUP", 12973 ``!f:real->real s. 12974 compact s /\ ~(s = {}) /\ (f) continuous_on s 12975 ==> ?x. x IN s /\ !y. y IN s ==> f(y) <= f(x)``, 12976 REPEAT STRIP_TAC THEN 12977 MP_TAC(SPEC ``IMAGE (f:real->real) s`` COMPACT_ATTAINS_SUP) THEN 12978 ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, COMPACT_CONTINUOUS_IMAGE, IMAGE_EQ_EMPTY] THEN 12979 MESON_TAC[IN_IMAGE]); 12980 12981val CONTINUOUS_ATTAINS_INF = store_thm ("CONTINUOUS_ATTAINS_INF", 12982 ``!f:real->real s. 12983 compact s /\ ~(s = {}) /\ (f) continuous_on s 12984 ==> ?x. x IN s /\ !y. y IN s ==> f(x) <= f(y)``, 12985 REPEAT STRIP_TAC THEN 12986 MP_TAC(SPEC ``IMAGE (f:real->real) s`` COMPACT_ATTAINS_INF) THEN 12987 ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, COMPACT_CONTINUOUS_IMAGE, IMAGE_EQ_EMPTY] THEN 12988 MESON_TAC[IN_IMAGE]); 12989 12990val DISTANCE_ATTAINS_SUP = store_thm ("DISTANCE_ATTAINS_SUP", 12991 ``!s a. compact s /\ ~(s = {}) 12992 ==> ?x. x IN s /\ !y. y IN s ==> dist(a,y) <= dist(a,x)``, 12993 REPEAT STRIP_TAC THEN 12994 ONCE_REWRITE_TAC [METIS [] ``dist (a,x) = (\x. dist (a,x)) x:real``] THEN 12995 MATCH_MP_TAC CONTINUOUS_ATTAINS_SUP THEN 12996 ASM_REWRITE_TAC[CONTINUOUS_ON_RANGE] THEN REWRITE_TAC[dist] THEN 12997 ASM_MESON_TAC[REAL_LET_TRANS, ABS_SUB_ABS, ABS_NEG, 12998 REAL_ARITH ``(a - x) - (a - y) = -(x - y):real``]); 12999 13000(* ------------------------------------------------------------------------- *) 13001(* For *minimal* distance, we only need closure, not compactness. *) 13002(* ------------------------------------------------------------------------- *) 13003 13004val DISTANCE_ATTAINS_INF = store_thm ("DISTANCE_ATTAINS_INF", 13005 ``!s a:real. 13006 closed s /\ ~(s = {}) 13007 ==> ?x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)``, 13008 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 13009 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN 13010 DISCH_THEN(X_CHOOSE_TAC ``b:real``) THEN 13011 MP_TAC(ISPECL [``\x:real. dist(a,x)``, ``cball(a:real,dist(b,a)) INTER s``] 13012 CONTINUOUS_ATTAINS_INF) THEN 13013 KNOW_TAC ``compact 13014 (cball ((a :real),(dist ((b :real),a) :real)) INTER 13015 (s :real -> bool)) /\ 13016 cball (a,(dist (b,a) :real)) INTER s <> ({} :real -> bool) /\ 13017 (\(x :real). (dist (a,x) :real)) continuous_on 13018 cball (a,(dist (b,a) :real)) INTER s`` THENL 13019 [ASM_SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_INTER, BOUNDED_INTER, 13020 BOUNDED_CBALL, CLOSED_CBALL, GSYM MEMBER_NOT_EMPTY] THEN 13021 SIMP_TAC std_ss [dist, CONTINUOUS_ON_RANGE, IN_INTER, IN_CBALL] THEN 13022 METIS_TAC[REAL_LET_TRANS, ABS_SUB_ABS, ABS_NEG, REAL_LE_REFL, 13023 ABS_SUB, REAL_ARITH ``(a - x) - (a - y) = -(x - y:real):real``], 13024 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 13025 DISCH_THEN (X_CHOOSE_TAC ``x:real``) THEN EXISTS_TAC ``x:real`` THEN 13026 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [IN_INTER, IN_CBALL] THEN 13027 METIS_TAC[DIST_SYM, REAL_LE_TOTAL, REAL_LE_TRANS]]); 13028 13029(* ------------------------------------------------------------------------- *) 13030(* We can now extend limit compositions to consider the scalar multiplier. *) 13031(* ------------------------------------------------------------------------- *) 13032 13033val LIM_MUL = store_thm ("LIM_MUL", 13034 ``!net:('a)net f l:real c d. 13035 (c --> d) net /\ (f --> l) net 13036 ==> ((\x. c(x) * f(x)) --> (d * l)) net``, 13037 REPEAT STRIP_TAC THEN 13038 MP_TAC(ISPECL [``net:('a)net``, ``\x y:real. x * y``, ``c:'a->real``, 13039 ``f:'a->real``, ``d:real``, ``l:real``] LIM_BILINEAR) THEN 13040 BETA_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_THEN MATCH_MP_TAC THEN 13041 REWRITE_TAC[bilinear, linear] THEN BETA_TAC THEN 13042 REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 13043 13044val LIM_VMUL = store_thm ("LIM_VMUL", 13045 ``!net:('a)net c d v:real. 13046 (c --> d) net ==> ((\x. c(x) * v) --> (d * v)) net``, 13047 REPEAT STRIP_TAC THEN 13048 KNOW_TAC ``(((\(x :'a). (c :'a -> real) x * (v :real)) --> 13049 ((d :real) * v)) (net :'a net)) = 13050 (((\(x :'a). (c :'a -> real) x * (\x. v :real) x) --> 13051 ((d :real) * v)) (net :'a net))`` THENL 13052 [SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 13053 MATCH_MP_TAC LIM_MUL THEN ASM_REWRITE_TAC[LIM_CONST]); 13054 13055val CONTINUOUS_VMUL = store_thm ("CONTINUOUS_VMUL", 13056 ``!net c v. c continuous net ==> (\x. c(x) * v) continuous net``, 13057 SIMP_TAC std_ss [continuous, LIM_VMUL, o_THM]); 13058 13059val CONTINUOUS_MUL = store_thm ("CONTINUOUS_MUL", 13060 ``!net f c. c continuous net /\ f continuous net 13061 ==> (\x. c(x) * f(x)) continuous net``, 13062 SIMP_TAC std_ss [continuous, LIM_MUL, o_THM]); 13063 13064val CONTINUOUS_ON_VMUL = store_thm ("CONTINUOUS_ON_VMUL", 13065 ``!s c v. c continuous_on s ==> (\x. c(x) * v) continuous_on s``, 13066 REWRITE_TAC [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 13067 SIMP_TAC std_ss [CONTINUOUS_VMUL]); 13068 13069val CONTINUOUS_ON_MUL = store_thm ("CONTINUOUS_ON_MUL", 13070 ``!s c f. c continuous_on s /\ f continuous_on s 13071 ==> (\x. c(x) * f(x)) continuous_on s``, 13072 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 13073 SIMP_TAC std_ss [CONTINUOUS_MUL]); 13074 13075val CONTINUOUS_POW = store_thm ("CONTINUOUS_POW", 13076 ``!net f:'a->real n. 13077 (\x. f x) continuous net 13078 ==> (\x. f x pow n) continuous net``, 13079 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN 13080 INDUCT_TAC THEN ASM_SIMP_TAC std_ss [pow, CONTINUOUS_CONST] THEN 13081 KNOW_TAC ``((\x:'a. f x * f x pow n) continuous net) = 13082 ((\x:'a. f x * (\x. f x pow n) x) continuous net)`` THENL 13083 [SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 13084 MATCH_MP_TAC CONTINUOUS_MUL THEN METIS_TAC [o_DEF, ETA_AX]); 13085 13086val CONTINUOUS_ON_POW = store_thm ("CONTINUOUS_ON_POW", 13087 ``!f:real->real s n. 13088 (\x. f x) continuous_on s 13089 ==> (\x. f x pow n) continuous_on s``, 13090 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN 13091 DISCH_TAC THEN INDUCT_TAC THEN 13092 ASM_SIMP_TAC std_ss[pow, CONTINUOUS_ON_CONST] THEN 13093 KNOW_TAC ``((\x. (f:real->real) x * f x pow n) continuous_on s:real->bool) = 13094 ((\x. f x * (\x. f x pow n) x) continuous_on s)`` THENL 13095 [SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 13096 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN METIS_TAC [o_DEF, ETA_AX]); 13097 13098val CONTINUOUS_PRODUCT = store_thm ("CONTINUOUS_PRODUCT", 13099 ``!net:('a)net f (t:'b->bool). 13100 FINITE t /\ 13101 (!i. i IN t ==> (\x. (f x i)) continuous net) 13102 ==> (\x. (product t (f x))) continuous net``, 13103 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[CONJ_EQ_IMP] THEN 13104 ONCE_REWRITE_TAC [METIS [] 13105 ``!t. ((!i. i IN t ==> (\x. f x i) continuous net) ==> 13106 (\x. product t (f x)) continuous net) = 13107 (\t. (!i. i IN t ==> (\x. f x i) continuous net) ==> 13108 (\x. product t (f x)) continuous net) t``] THEN 13109 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN SIMP_TAC std_ss [PRODUCT_CLAUSES] THEN 13110 SIMP_TAC std_ss [CONTINUOUS_CONST, FORALL_IN_INSERT] THEN 13111 REPEAT STRIP_TAC THEN 13112 ONCE_REWRITE_TAC [METIS [] ``(\x. f x e * product s (f x)) = 13113 (\x. (\x. f x e) x * (\x. product s (f x)) x)``] THEN 13114 MATCH_MP_TAC CONTINUOUS_MUL THEN ASM_SIMP_TAC std_ss [o_DEF]); 13115 13116val CONTINUOUS_ON_PRODUCT = store_thm ("CONTINUOUS_ON_PRODUCT", 13117 ``!f:real->'a->real s t. 13118 FINITE t /\ 13119 (!i. i IN t ==> (\x. (f x i)) continuous_on s) 13120 ==> (\x. (product t (f x))) continuous_on s``, 13121 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_PRODUCT]); 13122 13123(* ------------------------------------------------------------------------- *) 13124(* And so we have continuity of inverse. *) 13125(* ------------------------------------------------------------------------- *) 13126 13127val LIM_INV = store_thm ("LIM_INV", 13128 ``!net:('a)net f l. 13129 (f --> l) net /\ ~(l = &0) 13130 ==> ((inv o f) --> (inv l)) net``, 13131 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN 13132 ASM_CASES_TAC ``trivial_limit(net:('a)net)`` THEN ASM_REWRITE_TAC[] THEN 13133 REWRITE_TAC[o_THM, dist] THEN STRIP_TAC THEN 13134 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 13135 FIRST_X_ASSUM(MP_TAC o SPEC ``min (abs(l) / &2) ((l pow 2 * e) / &2:real)``) THEN 13136 REWRITE_TAC[REAL_LT_MIN] THEN 13137 KNOW_TAC ``0 < abs l / 2 /\ 0 < l pow 2 * e / 2:real`` THENL 13138 [ASM_SIMP_TAC arith_ss [GSYM ABS_NZ, REAL_LT_DIV, REAL_LT] THEN 13139 MATCH_MP_TAC REAL_LT_DIV THEN SIMP_TAC arith_ss [REAL_LT] THEN 13140 ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN 13141 ASM_SIMP_TAC std_ss [REAL_LT_MUL, GSYM ABS_NZ, REAL_POW_LT], 13142 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 13143 DISCH_THEN (X_CHOOSE_TAC ``a:'a``) THEN EXISTS_TAC ``a:'a`` THEN 13144 POP_ASSUM MP_TAC THEN 13145 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN 13146 DISCH_TAC THEN X_GEN_TAC ``b:'a`` THEN POP_ASSUM (MP_TAC o Q.SPEC `b:'a`) THEN 13147 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN 13148 SIMP_TAC arith_ss [REAL_LT_RDIV_EQ, REAL_LT] THEN STRIP_TAC THEN 13149 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH 13150 ``abs(x - l) * &2 < abs l ==> ~(x = &0:real)``)) THEN 13151 ASM_SIMP_TAC std_ss [REAL_SUB_INV2, ABS_DIV, REAL_LT_LDIV_EQ, 13152 GSYM ABS_NZ, REAL_ENTIRE] THEN 13153 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH 13154 ``abs(x - y) * &2 < b * c ==> c * b <= d * &2 ==> abs(y - x) < d:real``)) THEN 13155 ASM_SIMP_TAC std_ss [GSYM REAL_MUL_ASSOC, REAL_LE_LMUL] THEN 13156 ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN 13157 ASM_SIMP_TAC std_ss [ABS_MUL, POW_2, REAL_MUL_ASSOC, GSYM ABS_NZ, 13158 REAL_LE_RMUL] THEN 13159 ASM_SIMP_TAC std_ss [REAL_ARITH ``abs(x - y) * &2 < abs y ==> abs y <= &2 * abs x:real``]); 13160 13161val CONTINUOUS_INV = store_thm ("CONTINUOUS_INV", 13162 ``!net f. f continuous net /\ ~(f(netlimit net) = &0) 13163 ==> (inv o f) continuous net``, 13164 SIMP_TAC std_ss [continuous, LIM_INV, o_THM]); 13165 13166val CONTINUOUS_AT_WITHIN_INV = store_thm ("CONTINUOUS_AT_WITHIN_INV", 13167 ``!f s a:real. 13168 f continuous (at a within s) /\ ~(f a = &0) 13169 ==> (inv o f) continuous (at a within s)``, 13170 REPEAT GEN_TAC THEN 13171 ASM_CASES_TAC ``trivial_limit (at (a:real) within s)`` THENL 13172 [ASM_REWRITE_TAC[continuous, LIM], 13173 ASM_SIMP_TAC std_ss [NETLIMIT_WITHIN, CONTINUOUS_INV]]); 13174 13175val CONTINUOUS_AT_INV = store_thm ("CONTINUOUS_AT_INV", 13176 ``!f a. f continuous at a /\ ~(f a = &0) 13177 ==> (inv o f) continuous at a``, 13178 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 13179 REWRITE_TAC[CONTINUOUS_AT_WITHIN_INV]); 13180 13181val CONTINUOUS_ON_INV = store_thm ("CONTINUOUS_ON_INV", 13182 ``!f s. f continuous_on s /\ (!x. x IN s ==> ~(f x = &0)) 13183 ==> (inv o f) continuous_on s``, 13184 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_AT_WITHIN_INV]); 13185 13186(* ------------------------------------------------------------------------- *) 13187(* Hence some useful properties follow quite easily. *) 13188(* ------------------------------------------------------------------------- *) 13189 13190val CONNECTED_SCALING = store_thm ("CONNECTED_SCALING", 13191 ``!s:real->bool c. connected s ==> connected (IMAGE (\x. c * x) s)``, 13192 REPEAT STRIP_TAC THEN 13193 MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 13194 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 13195 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN 13196 REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 13197 13198val CONNECTED_NEGATIONS = store_thm ("CONNECTED_NEGATIONS", 13199 ``!s:real->bool. connected s ==> connected (IMAGE (\x. -x) s)``, 13200 REPEAT STRIP_TAC THEN 13201 MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 13202 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 13203 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN 13204 REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 13205 13206val COMPACT_SCALING = store_thm ("COMPACT_SCALING", 13207 ``!s:real->bool c. compact s ==> compact (IMAGE (\x. c * x) s)``, 13208 REPEAT STRIP_TAC THEN 13209 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 13210 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 13211 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN 13212 REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 13213 13214val COMPACT_NEGATIONS = store_thm ("COMPACT_NEGATIONS", 13215 ``!s:real->bool. compact s ==> compact (IMAGE (\x. -x) s)``, 13216 REPEAT STRIP_TAC THEN 13217 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 13218 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 13219 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN 13220 REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 13221 13222val COMPACT_AFFINITY = store_thm ("COMPACT_AFFINITY", 13223 ``!s a:real c. 13224 compact s ==> compact (IMAGE (\x. a + c * x) s)``, 13225 REPEAT STRIP_TAC THEN 13226 SUBGOAL_THEN ``(\x:real. a + c * x) = (\x. a + x) o (\x. c * x)`` 13227 SUBST1_TAC THENL [REWRITE_TAC[o_DEF], ALL_TAC] THEN 13228 ASM_SIMP_TAC std_ss [IMAGE_COMPOSE, COMPACT_TRANSLATION, COMPACT_SCALING]); 13229 13230(* ------------------------------------------------------------------------- *) 13231(* We can state this in terms of diameter of a set. *) 13232(* ------------------------------------------------------------------------- *) 13233 13234val diameter = new_definition ("diameter", 13235 ``diameter s = 13236 if s = {} then (&0:real) 13237 else sup {abs(x - y) | x IN s /\ y IN s}``); 13238 13239val DIAMETER_BOUNDED = store_thm ("DIAMETER_BOUNDED", 13240 ``!s. bounded s 13241 ==> (!x:real y. x IN s /\ y IN s ==> abs(x - y) <= diameter s) /\ 13242 (!d. &0 <= d /\ d < diameter s 13243 ==> ?x y. x IN s /\ y IN s /\ abs(x - y) > d)``, 13244 GEN_TAC THEN DISCH_TAC THEN 13245 ASM_CASES_TAC ``s:real->bool = {}`` THEN 13246 ASM_REWRITE_TAC[diameter, NOT_IN_EMPTY, REAL_LET_ANTISYM] THENL 13247 [SIMP_TAC std_ss [REAL_NOT_LE, REAL_NOT_LT, REAL_LTE_TOTAL], ALL_TAC] THEN 13248 MP_TAC(SPEC ``{abs(x - y:real) | x IN s /\ y IN s}`` SUP) THEN 13249 ABBREV_TAC ``b = sup {abs(x - y:real) | x IN s /\ y IN s}`` THEN 13250 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 13251 REWRITE_TAC[NOT_IN_EMPTY, real_gt] THEN 13252 KNOW_TAC ``(?(x :real) (p_1 :real) (p_2 :real). 13253 (x = abs (p_1 - p_2)) /\ p_1 IN (s :real -> bool) /\ p_2 IN s) /\ 13254 (?(b :real). 13255 !(x :real). 13256 (?(p_1 :real) (p_2 :real). 13257 (x = abs (p_1 - p_2)) /\ p_1 IN s /\ p_2 IN s) ==> 13258 x <= b)`` THENL 13259 [CONJ_TAC THENL [METIS_TAC[MEMBER_NOT_EMPTY], ALL_TAC], 13260 METIS_TAC[REAL_NOT_LE]] THEN 13261 SIMP_TAC std_ss [REAL_SUB, LEFT_IMP_EXISTS_THM] THEN 13262 UNDISCH_TAC ``bounded s`` THEN DISCH_TAC THEN 13263 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [bounded_def]) THEN 13264 REWRITE_TAC [real_sub] THEN 13265 METIS_TAC [REAL_ARITH ``x <= y + z /\ y <= b /\ z <= b ==> x <= b + b:real``, 13266 ABS_TRIANGLE, ABS_NEG]); 13267 13268val DIAMETER_BOUNDED_BOUND = store_thm ("DIAMETER_BOUNDED_BOUND", 13269 ``!s x y. bounded s /\ x IN s /\ y IN s ==> abs(x - y) <= diameter s``, 13270 MESON_TAC[DIAMETER_BOUNDED]); 13271 13272val DIAMETER_LINEAR_IMAGE = store_thm ("DIAMETER_LINEAR_IMAGE", 13273 ``!f:real->real s. 13274 linear f /\ (!x. abs(f x) = abs x) 13275 ==> (diameter(IMAGE f s) = diameter s)``, 13276 REWRITE_TAC[diameter] THEN 13277 REPEAT STRIP_TAC THEN REWRITE_TAC[diameter, IMAGE_EQ_EMPTY] THEN 13278 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN 13279 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 13280 ONCE_REWRITE_TAC [CONJ_SYM] THEN 13281 SIMP_TAC std_ss [GSYM CONJ_ASSOC, RIGHT_EXISTS_AND_THM, EXISTS_IN_IMAGE] THEN 13282 METIS_TAC[LINEAR_SUB]); 13283 13284val DIAMETER_EMPTY = store_thm ("DIAMETER_EMPTY", 13285 ``diameter {} = &0``, 13286 REWRITE_TAC[diameter]); 13287 13288val DIAMETER_SING = store_thm ("DIAMETER_SING", 13289 ``!a. diameter {a} = &0``, 13290 REWRITE_TAC[diameter, NOT_INSERT_EMPTY, IN_SING] THEN 13291 ONCE_REWRITE_TAC [METIS [] ``abs (x - y:real) = (\x y. abs (x - y:real)) x y``] THEN 13292 KNOW_TAC ``!a:real f x:real y:real. {f x y | (x = a) /\ (y = a)} = {(f a a):real }`` THENL 13293 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, IN_SING], 13294 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 13295 SIMP_TAC std_ss [REAL_SUB_REFL, ABS_0] THEN 13296 MATCH_MP_TAC REAL_SUP_UNIQUE THEN 13297 REWRITE_TAC [METIS [SPECIFICATION] ``{0:real} x <=> x IN {0}``] THEN 13298 SET_TAC [REAL_LE_LT]); 13299 13300val DIAMETER_POS_LE = store_thm ("DIAMETER_POS_LE", 13301 ``!s:real->bool. bounded s ==> &0 <= diameter s``, 13302 REPEAT STRIP_TAC THEN REWRITE_TAC[diameter] THEN 13303 COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN 13304 MP_TAC(SPEC ``{abs(x - y:real) | x IN s /\ y IN s}`` SUP) THEN 13305 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 13306 KNOW_TAC ``{abs (x - y) | x IN (s :real -> bool) /\ y IN s} <> 13307 ({} :real -> bool) /\ (?(b :real). 13308 !(x :real) (y :real). x IN s /\ y IN s ==> abs (x - y) <= b)`` THENL 13309 [CONJ_TAC THENL [FULL_SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, 13310 EXISTS_PROD, NOT_IN_EMPTY] THEN METIS_TAC [MEMBER_NOT_EMPTY], ALL_TAC] THEN 13311 UNDISCH_TAC ``bounded s`` THEN DISCH_TAC THEN 13312 FIRST_X_ASSUM(X_CHOOSE_TAC ``B:real`` o REWRITE_RULE [BOUNDED_POS]) THEN 13313 EXISTS_TAC ``&2 * B:real`` THEN 13314 ASM_SIMP_TAC std_ss [REAL_ARITH 13315 ``abs x <= B /\ abs y <= B ==> abs(x - y) <= &2 * B:real``], 13316 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 13317 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 13318 DISCH_THEN(X_CHOOSE_TAC ``a:real``) THEN 13319 DISCH_THEN(MP_TAC o SPECL [``a:real``, ``a:real``] o CONJUNCT1) THEN 13320 ASM_REWRITE_TAC[REAL_SUB_REFL, ABS_0]]); 13321 13322val DIAMETER_SUBSET = store_thm ("DIAMETER_SUBSET", 13323 ``!s t:real->bool. s SUBSET t /\ bounded t ==> diameter s <= diameter t``, 13324 REPEAT STRIP_TAC THEN 13325 ASM_CASES_TAC ``s:real->bool = {}`` THEN 13326 ASM_SIMP_TAC std_ss [DIAMETER_EMPTY, DIAMETER_POS_LE] THEN 13327 ASM_REWRITE_TAC[diameter] THEN 13328 COND_CASES_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 13329 MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN 13330 REPEAT(CONJ_TAC THENL 13331 [FULL_SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, SUBSET_DEF, 13332 EXISTS_PROD, NOT_IN_EMPTY] THEN METIS_TAC [MEMBER_NOT_EMPTY], ALL_TAC]) THEN 13333 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 13334 UNDISCH_TAC ``bounded t`` THEN DISCH_TAC THEN 13335 FIRST_X_ASSUM(X_CHOOSE_TAC ``B:real`` o REWRITE_RULE [BOUNDED_POS]) THEN 13336 EXISTS_TAC ``&2 * B:real`` THEN 13337 ASM_SIMP_TAC std_ss [REAL_ARITH 13338 ``abs x <= B /\ abs y <= B ==> abs(x - y) <= &2 * B:real``]); 13339 13340val DIAMETER_CLOSURE = store_thm ("DIAMETER_CLOSURE", 13341 ``!s:real->bool. bounded s ==> (diameter(closure s) = diameter s)``, 13342 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN REPEAT STRIP_TAC THEN 13343 ASM_SIMP_TAC std_ss [DIAMETER_SUBSET, BOUNDED_CLOSURE, CLOSURE_SUBSET] THEN 13344 REWRITE_TAC[GSYM REAL_NOT_LT] THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN 13345 DISCH_TAC THEN MP_TAC(ISPEC ``closure s:real->bool`` DIAMETER_BOUNDED) THEN 13346 ABBREV_TAC ``d = diameter(closure s) - diameter(s:real->bool)`` THEN 13347 ASM_SIMP_TAC std_ss [BOUNDED_CLOSURE] THEN 13348 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 13349 POP_ASSUM (MP_TAC o 13350 SPEC ``diameter(closure(s:real->bool)) - d / &2:real``) THEN 13351 SIMP_TAC std_ss [NOT_IMP, GSYM CONJ_ASSOC, NOT_EXISTS_THM] THEN 13352 ONCE_REWRITE_TAC [SET_RULE ``(x:real) NOTIN y <=> ~(x IN y)``, GSYM DE_MORGAN_THM] THEN 13353 ONCE_REWRITE_TAC [SET_RULE ``(x:real) NOTIN y <=> ~(x IN y)``, GSYM DE_MORGAN_THM] THEN 13354 FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIAMETER_POS_LE) THEN 13355 CONJ_TAC THENL 13356 [SIMP_TAC std_ss [REAL_SUB_LE, REAL_LE_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 13357 EXPAND_TAC "d" THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 13358 SIMP_TAC std_ss [GSYM REAL_DOUBLE, real_sub] THEN 13359 MATCH_MP_TAC REAL_LE_ADD2 THEN SIMP_TAC std_ss [REAL_LE_REFL] THEN 13360 FULL_SIMP_TAC std_ss [REAL_ARITH ``(a - b = c) <=> (a = c + b:real)``] THEN 13361 ONCE_REWRITE_TAC [GSYM REAL_SUB_LE] THEN 13362 REWRITE_TAC [REAL_ARITH ``0 < a + b - -c <=> 0 + 0 < a + (b + c):real``, REAL_LE_LT] THEN 13363 DISJ1_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC [] THEN 13364 ONCE_REWRITE_TAC [REAL_ARITH ``0 = 0 + 0:real``] THEN 13365 MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC [], ALL_TAC] THEN 13366 CONJ_TAC THENL 13367 [ONCE_REWRITE_TAC [REAL_ARITH ``a - b < c <=> a - c < b:real``] THEN 13368 SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 13369 ASM_REWRITE_TAC [REAL_SUB_REFL, REAL_MUL_LZERO], ALL_TAC] THEN 13370 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN 13371 SIMP_TAC std_ss [CLOSURE_APPROACHABLE, CONJ_ASSOC, GSYM FORALL_AND_THM] THEN 13372 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 13373 UNDISCH_TAC ``!e. ~(0 < e) \/ ?y'. y' IN s /\ dist (y',y) < e:real`` THEN DISCH_TAC THEN 13374 POP_ASSUM (MP_TAC o Q.SPEC `d / 4:real`) THEN 13375 UNDISCH_TAC ``!e. ~(0 < e) \/ ?y. y IN s /\ dist (y,x) < e:real`` THEN DISCH_TAC THEN 13376 POP_ASSUM (MP_TAC o Q.SPEC `d / 4:real`) THEN REWRITE_TAC [AND_IMP_INTRO] THEN 13377 ASM_REWRITE_TAC[METIS [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 4:real``, REAL_MUL_LZERO] 13378 ``&0 < d / &4 <=> &0 < d:real``] THEN 13379 DISCH_THEN(CONJUNCTS_THEN2 13380 (X_CHOOSE_THEN ``u:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) 13381 (X_CHOOSE_THEN ``v:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))) THEN 13382 FIRST_ASSUM(MP_TAC o MATCH_MP DIAMETER_BOUNDED) THEN 13383 DISCH_THEN(MP_TAC o SPECL [``u:real``, ``v:real``] o CONJUNCT1) THEN 13384 ASM_REWRITE_TAC[dist] THEN 13385 RULE_ASSUM_TAC (REWRITE_RULE [real_gt]) THEN 13386 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``a - b < c <=> a - c < b:real``]) THEN 13387 RULE_ASSUM_TAC (SIMP_RULE std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``]) THEN 13388 UNDISCH_TAC `` (diameter (closure s) - abs (x - y)) * 2 < d:real`` THEN 13389 EXPAND_TAC "d" THEN SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 4:real``] THEN 13390 REAL_ARITH_TAC); 13391 13392val DIAMETER_SUBSET_CBALL_NONEMPTY = store_thm ("DIAMETER_SUBSET_CBALL_NONEMPTY", 13393 ``!s:real->bool. 13394 bounded s /\ ~(s = {}) ==> ?z. z IN s /\ s SUBSET cball(z,diameter s)``, 13395 REPEAT STRIP_TAC THEN 13396 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 13397 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 13398 ASM_REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``b:real`` THEN 13399 DISCH_TAC THEN REWRITE_TAC[IN_CBALL, dist] THEN 13400 ASM_MESON_TAC[DIAMETER_BOUNDED]); 13401 13402val DIAMETER_SUBSET_CBALL = store_thm ("DIAMETER_SUBSET_CBALL", 13403 ``!s:real->bool. bounded s ==> ?z. s SUBSET cball(z,diameter s)``, 13404 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 13405 ASM_MESON_TAC[DIAMETER_SUBSET_CBALL_NONEMPTY, EMPTY_SUBSET]); 13406 13407val DIAMETER_EQ_0 = store_thm ("DIAMETER_EQ_0", 13408 ``!s:real->bool. 13409 bounded s ==> ((diameter s = &0) <=> (s = {}) \/ ?a. (s = {a}))``, 13410 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THEN 13411 ASM_REWRITE_TAC[DIAMETER_EMPTY, DIAMETER_SING] THEN 13412 REWRITE_TAC[SET_RULE 13413 ``(s = {}) \/ (?a. s = {a}) <=> !a b. a IN s /\ b IN s ==> (a = b)``] THEN 13414 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN STRIP_TAC THEN 13415 MP_TAC(ISPECL [``s:real->bool``, ``a:real``, ``b:real``] 13416 DIAMETER_BOUNDED_BOUND) THEN 13417 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC); 13418 13419val DIAMETER_LE = store_thm ("DIAMETER_LE", 13420 ``!s:real->bool d. 13421 (~(s = {}) \/ &0 <= d) /\ 13422 (!x y. x IN s /\ y IN s ==> abs(x - y) <= d) ==> diameter s <= d``, 13423 NTAC 2 GEN_TAC THEN REWRITE_TAC[diameter] THEN 13424 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [] THEN 13425 STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_LE' THEN 13426 CONJ_TAC THENL [ 13427 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[], 13428 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC []]); 13429 13430val DIAMETER_CBALL = store_thm ("DIAMETER_CBALL", 13431 ``!a:real r. diameter(cball(a,r)) = if r < &0 then &0 else &2 * r``, 13432 REPEAT GEN_TAC THEN COND_CASES_TAC THENL 13433 [ASM_MESON_TAC[CBALL_EQ_EMPTY, DIAMETER_EMPTY], ALL_TAC] THEN 13434 RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT]) THEN 13435 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL 13436 [MATCH_MP_TAC DIAMETER_LE THEN 13437 ASM_SIMP_TAC std_ss [CBALL_EQ_EMPTY, REAL_LE_MUL, REAL_POS, REAL_NOT_LT] THEN 13438 REWRITE_TAC[IN_CBALL, dist] THEN REAL_ARITH_TAC, 13439 MATCH_MP_TAC REAL_LE_TRANS THEN 13440 EXISTS_TAC ``abs((a + r) - (a - r):real)`` THEN 13441 CONJ_TAC THENL 13442 [REWRITE_TAC[REAL_ARITH ``(a + r) - (a - r) = (&2 * r:real)``] THEN 13443 ASM_REAL_ARITH_TAC, 13444 MATCH_MP_TAC DIAMETER_BOUNDED_BOUND THEN 13445 REWRITE_TAC[BOUNDED_CBALL, IN_CBALL, dist] THEN 13446 REWRITE_TAC[REAL_ARITH 13447 ``(abs(a - (a + b)) = abs b) /\ (abs(a - (a - b)) = abs b:real)``] THEN 13448 ASM_REAL_ARITH_TAC]]); 13449 13450val DIAMETER_BALL = store_thm ("DIAMETER_BALL", 13451 ``!a:real r. diameter(ball(a,r)) = if r < &0 then &0 else &2 * r``, 13452 REPEAT GEN_TAC THEN COND_CASES_TAC THENL 13453 [ASM_SIMP_TAC std_ss [BALL_EMPTY, REAL_LT_IMP_LE, DIAMETER_EMPTY], ALL_TAC] THEN 13454 ASM_CASES_TAC ``r = &0:real`` THEN 13455 ASM_SIMP_TAC std_ss [BALL_EMPTY, REAL_LE_REFL, DIAMETER_EMPTY, REAL_MUL_RZERO] THEN 13456 MATCH_MP_TAC EQ_TRANS THEN 13457 EXISTS_TAC ``diameter(cball(a:real,r))`` THEN CONJ_TAC THENL 13458 [SUBGOAL_THEN ``&0 < r:real`` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC, ALL_TAC] THEN 13459 ASM_SIMP_TAC std_ss [GSYM CLOSURE_BALL, DIAMETER_CLOSURE, BOUNDED_BALL], 13460 ASM_SIMP_TAC std_ss [DIAMETER_CBALL]]); 13461 13462val DIAMETER_SUMS = store_thm ("DIAMETER_SUMS", 13463 ``!s t:real->bool. 13464 bounded s /\ bounded t 13465 ==> diameter {x + y | x IN s /\ y IN t} <= diameter s + diameter t``, 13466 REPEAT STRIP_TAC THEN 13467 KNOW_TAC ``!x y:real. {x + y| F} = {}:real->bool`` THENL 13468 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN SET_TAC [], DISCH_TAC] THEN 13469 ASM_CASES_TAC ``s:real->bool = {}`` THEN 13470 ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, DIAMETER_EMPTY, REAL_ADD_LID, DIAMETER_POS_LE] THEN 13471 ASM_CASES_TAC ``t:real->bool = {}`` THEN 13472 ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, DIAMETER_EMPTY, REAL_ADD_RID, DIAMETER_POS_LE] THEN 13473 MATCH_MP_TAC DIAMETER_LE THEN CONJ_TAC THENL 13474 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, NOT_IN_EMPTY] THEN 13475 ASM_SET_TAC [], ALL_TAC] THEN 13476 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM, CONJ_EQ_IMP, FORALL_IN_GSPEC] THEN 13477 REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH 13478 ``abs(x - x') <= s /\ abs(y - y') <= t 13479 ==> abs((x + y) - (x' + y'):real) <= s + t``) THEN 13480 ASM_SIMP_TAC std_ss [DIAMETER_BOUNDED_BOUND]); 13481 13482val LEBESGUE_COVERING_LEMMA = store_thm ("LEBESGUE_COVERING_LEMMA", 13483 ``!s:real->bool c. 13484 compact s /\ ~(c = {}) /\ s SUBSET BIGUNION c /\ (!b. b IN c ==> open b) 13485 ==> ?d. &0 < d /\ 13486 !t. t SUBSET s /\ diameter t <= d 13487 ==> ?b. b IN c /\ t SUBSET b``, 13488 REPEAT STRIP_TAC THEN 13489 FIRST_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN 13490 DISCH_THEN(MP_TAC o SPEC ``c:(real->bool)->bool``) THEN ASM_SIMP_TAC std_ss [] THEN 13491 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC ``e:real`` THEN 13492 STRIP_TAC THEN EXISTS_TAC ``e / &2:real`` THEN ASM_REWRITE_TAC[REAL_HALF] THEN 13493 X_GEN_TAC ``t:real->bool`` THEN STRIP_TAC THEN 13494 ASM_CASES_TAC ``t:real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN 13495 MP_TAC(ISPEC ``t:real->bool`` DIAMETER_SUBSET_CBALL_NONEMPTY) THEN 13496 KNOW_TAC ``(bounded (t :real -> bool) :bool) /\ t <> ({} :real -> bool)`` THENL 13497 [ASM_MESON_TAC[BOUNDED_SUBSET, COMPACT_IMP_BOUNDED], 13498 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 13499 DISCH_THEN(X_CHOOSE_THEN ``x:real`` STRIP_ASSUME_TAC) THEN 13500 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN 13501 KNOW_TAC ``(x :real) IN (s :real -> bool)`` THENL 13502 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 13503 DISCH_THEN (X_CHOOSE_TAC ``b:real->bool``) THEN EXISTS_TAC ``b:real->bool`` THEN 13504 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN 13505 EXISTS_TAC ``cball(x:real,diameter(t:real->bool))`` THEN 13506 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN 13507 EXISTS_TAC ``ball(x:real,e)`` THEN ASM_REWRITE_TAC[] THEN 13508 REWRITE_TAC[SUBSET_DEF, IN_CBALL, IN_BALL] THEN 13509 MAP_EVERY UNDISCH_TAC [``&0 < e:real``, ``diameter(t:real->bool) <= e / &2:real``] THEN 13510 SIMP_TAC std_ss [dist, REAL_LE_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN REAL_ARITH_TAC); 13511 13512(* ------------------------------------------------------------------------- *) 13513(* Related results with closure as the conclusion. *) 13514(* ------------------------------------------------------------------------- *) 13515 13516val CLOSED_SCALING = store_thm ("CLOSED_SCALING", 13517 ``!s:real->bool c. closed s ==> closed (IMAGE (\x. c * x) s)``, 13518 REPEAT GEN_TAC THEN 13519 ASM_CASES_TAC ``s :real->bool = {}`` THEN 13520 ASM_REWRITE_TAC[CLOSED_EMPTY, IMAGE_EMPTY, IMAGE_INSERT] THEN 13521 ASM_CASES_TAC ``c = &0:real`` THENL 13522 [SUBGOAL_THEN ``IMAGE (\x:real. c * x) s = {(0)}`` 13523 (fn th => REWRITE_TAC[th, CLOSED_SING]) THEN 13524 ASM_REWRITE_TAC[EXTENSION, IN_IMAGE, IN_SING, REAL_MUL_LZERO] THEN 13525 ASM_MESON_TAC[MEMBER_NOT_EMPTY], 13526 ALL_TAC] THEN 13527 SIMP_TAC std_ss [CLOSED_SEQUENTIAL_LIMITS, IN_IMAGE, SKOLEM_THM] THEN 13528 STRIP_TAC THEN X_GEN_TAC ``x:num->real`` THEN X_GEN_TAC ``l:real`` THEN 13529 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 13530 DISCH_THEN(X_CHOOSE_THEN ``y:num->real`` MP_TAC) THEN 13531 SIMP_TAC std_ss [FORALL_AND_THM] THEN STRIP_TAC THEN 13532 EXISTS_TAC ``inv(c) * l :real`` THEN 13533 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_MUL_LID] THEN 13534 FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC ``\n:num. inv(c) * x n:real`` THEN 13535 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THENL 13536 [ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID], 13537 ONCE_REWRITE_TAC [METIS [] ``(\n:num. inv c * (c * (y:num->real) n)) = 13538 (\n. inv c:real * (\n. (c * y n)) n)``] THEN 13539 MATCH_MP_TAC LIM_CMUL THEN 13540 FIRST_ASSUM(fn th => REWRITE_TAC[SYM(SPEC_ALL th)]) THEN 13541 ASM_SIMP_TAC std_ss [ETA_AX]]); 13542 13543val CLOSED_NEGATIONS = store_thm ("CLOSED_NEGATIONS", 13544 ``!s:real->bool. closed s ==> closed (IMAGE (\x. -x) s)``, 13545 REPEAT GEN_TAC THEN 13546 SUBGOAL_THEN ``IMAGE (\x. -x) s = IMAGE (\x:real. -(&1) * x) s`` 13547 SUBST1_TAC THEN SIMP_TAC std_ss [CLOSED_SCALING] THEN 13548 REWRITE_TAC[REAL_ARITH ``-(&1) * x = -x:real``] THEN SIMP_TAC std_ss [ETA_AX]); 13549 13550val COMPACT_CLOSED_SUMS = store_thm ("COMPACT_CLOSED_SUMS", 13551 ``!s:real->bool t. 13552 compact s /\ closed t ==> closed {x + y | x IN s /\ y IN t}``, 13553 REPEAT GEN_TAC THEN 13554 SIMP_TAC std_ss [compact, GSPECIFICATION, CLOSED_SEQUENTIAL_LIMITS, EXISTS_PROD] THEN 13555 STRIP_TAC THEN X_GEN_TAC ``f:num->real`` THEN X_GEN_TAC ``l:real`` THEN 13556 SIMP_TAC std_ss [SKOLEM_THM, FORALL_AND_THM] THEN 13557 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 13558 DISCH_THEN(X_CHOOSE_THEN ``a:num->real`` MP_TAC) THEN 13559 DISCH_THEN(X_CHOOSE_THEN ``b:num->real`` STRIP_ASSUME_TAC) THEN 13560 UNDISCH_TAC `` !f:num->real. 13561 (!n. f n IN s) ==> 13562 ?l r. 13563 l IN s /\ (!m n. m < n ==> r m < r n) /\ 13564 (f o r --> l) sequentially`` THEN DISCH_TAC THEN 13565 FIRST_X_ASSUM(MP_TAC o SPEC ``a:num->real``) THEN 13566 ASM_REWRITE_TAC[] THEN 13567 DISCH_THEN(X_CHOOSE_THEN ``la:real`` (X_CHOOSE_THEN ``sub:num->num`` 13568 STRIP_ASSUME_TAC)) THEN 13569 MAP_EVERY EXISTS_TAC [``la:real``, ``l - la:real``] THEN 13570 ASM_REWRITE_TAC[REAL_ARITH ``a + (b - a) = b:real``] THEN 13571 FIRST_X_ASSUM MATCH_MP_TAC THEN 13572 EXISTS_TAC ``\n. (f o (sub:num->num)) n - (a o sub) n:real`` THEN 13573 CONJ_TAC THENL [ASM_SIMP_TAC std_ss [REAL_ADD_SUB, o_THM], ALL_TAC] THEN 13574 MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC std_ss [LIM_SUBSEQUENCE, ETA_AX]); 13575 13576val CLOSED_COMPACT_SUMS = store_thm ("CLOSED_COMPACT_SUMS", 13577 ``!s:real->bool t. 13578 closed s /\ compact t ==> closed {x + y | x IN s /\ y IN t}``, 13579 REPEAT GEN_TAC THEN 13580 SUBGOAL_THEN ``{x + y:real | x IN s /\ y IN t} = {y + x | y IN t /\ x IN s}`` 13581 SUBST1_TAC THEN SIMP_TAC std_ss [COMPACT_CLOSED_SUMS] THEN 13582 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN METIS_TAC [REAL_ADD_SYM]); 13583 13584val CLOSURE_SUMS = store_thm ("CLOSURE_SUMS", 13585 ``!s t:real->bool. 13586 bounded s \/ bounded t 13587 ==> (closure {x + y | x IN s /\ y IN t} = 13588 {x + y | x IN closure s /\ y IN closure t})``, 13589 REWRITE_TAC[TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN 13590 SIMP_TAC std_ss [FORALL_AND_THM] THEN 13591 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SUMS_SYM] THEN 13592 MATCH_MP_TAC(TAUT `(p ==> q) /\ p ==> p /\ q`) THEN 13593 SIMP_TAC std_ss [] THEN 13594 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [EXTENSION, CLOSURE_SEQUENTIAL] THEN 13595 X_GEN_TAC ``z:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN EQ_TAC THENL 13596 [GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [CONJ_SYM] THEN 13597 SIMP_TAC std_ss [GSPECIFICATION, IN_DELETE, SKOLEM_THM, GSYM LEFT_EXISTS_AND_THM] THEN 13598 SIMP_TAC std_ss [FORALL_AND_THM] THEN 13599 ONCE_REWRITE_TAC[TAUT `(p /\ q) /\ r <=> q /\ p /\ r`] THEN 13600 KNOW_TAC ``(?(x' :num -> real) (f :num -> real) (f' :num -> real). 13601 (\x' f f'. ((!(n :num). f n IN (s :real -> bool)) /\ 13602 !(n :num). f' n IN (t :real -> bool)) /\ 13603 (!(n :num). x' n = f n + f' n) /\ 13604 ((x' --> (z :real)) sequentially :bool)) x' f f') ==> 13605?(p_1 :real) (p_2 :real) (x' :num -> real). 13606 (\p_1 p_2 x'. (?(x :num -> real). 13607 (!(n :num). x n IN t) /\ ((x --> p_2) sequentially :bool)) /\ 13608 ((!(n :num). x' n IN s) /\ ((x' --> p_1) sequentially :bool)) /\ 13609 (z = p_1 + p_2)) p_1 p_2 x'`` THENL 13610 [ALL_TAC, METIS_TAC []] THEN 13611 ONCE_REWRITE_TAC[MESON[] ``(?f x y. P f x y) <=> (?x y f. P f x y)``] THEN 13612 SIMP_TAC std_ss [GSYM FUN_EQ_THM] THEN 13613 SIMP_TAC std_ss [ETA_AX, UNWIND_THM2] THEN 13614 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 13615 MAP_EVERY X_GEN_TAC [``a:num->real``, ``b:num->real``] THEN 13616 STRIP_TAC THEN 13617 MP_TAC(ISPEC ``closure s:real->bool`` compact) THEN 13618 ASM_SIMP_TAC std_ss [COMPACT_CLOSURE] THEN 13619 DISCH_THEN(MP_TAC o SPEC ``a:num->real``) THEN 13620 ASM_SIMP_TAC std_ss [SIMP_RULE std_ss [SUBSET_DEF] CLOSURE_SUBSET, LEFT_IMP_EXISTS_THM] THEN 13621 MAP_EVERY X_GEN_TAC [``u:real``, ``r:num->num``] THEN STRIP_TAC THEN 13622 EXISTS_TAC ``z - u:real`` THEN 13623 EXISTS_TAC ``(a:num->real) o (r:num->num)`` THEN EXISTS_TAC ``u:real`` THEN 13624 ASM_SIMP_TAC std_ss [o_THM] THEN 13625 CONJ_TAC THENL [ALL_TAC, REAL_ARITH_TAC] THEN 13626 EXISTS_TAC ``(\n. ((\n. a n + b n) o (r:num->num)) n - (a o r) n) 13627 :num->real`` THEN 13628 CONJ_TAC THENL 13629 [ASM_SIMP_TAC real_ss [o_DEF, REAL_ARITH ``(a + b) - a:real = b``], 13630 MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC std_ss [ETA_AX] THEN 13631 MATCH_MP_TAC LIM_SUBSEQUENCE THEN ASM_REWRITE_TAC[]], 13632 SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM] THEN 13633 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, GSYM LEFT_EXISTS_AND_THM, 13634 GSYM RIGHT_EXISTS_AND_THM] THEN 13635 MAP_EVERY X_GEN_TAC 13636 [``x:real``, ``y:real``, ``a:num->real``, ``b:num->real``] THEN 13637 STRIP_TAC THEN EXISTS_TAC ``(\n. a n + b n):num->real`` THEN 13638 ASM_SIMP_TAC std_ss [LIM_ADD] THEN ASM_MESON_TAC[]]); 13639 13640val COMPACT_CLOSED_DIFFERENCES = store_thm ("COMPACT_CLOSED_DIFFERENCES", 13641 ``!s:real->bool t. 13642 compact s /\ closed t ==> closed {x - y | x IN s /\ y IN t}``, 13643 REPEAT STRIP_TAC THEN 13644 SUBGOAL_THEN ``{x - y | x:real IN s /\ y IN t} = 13645 {x + y | x IN s /\ y IN (IMAGE (\x. -x) t)}`` 13646 (fn th => ASM_SIMP_TAC std_ss [th, COMPACT_CLOSED_SUMS, CLOSED_NEGATIONS]) THEN 13647 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, IN_IMAGE] THEN 13648 ONCE_REWRITE_TAC[REAL_ARITH ``(x:real = -y) <=> (y = -x:real)``] THEN 13649 SIMP_TAC std_ss [real_sub, GSYM CONJ_ASSOC, UNWIND_THM2] THEN 13650 METIS_TAC[REAL_NEG_NEG]); 13651 13652val CLOSED_COMPACT_DIFFERENCES = store_thm ("CLOSED_COMPACT_DIFFERENCES", 13653 ``!s:real->bool t. 13654 closed s /\ compact t ==> closed {x - y | x IN s /\ y IN t}``, 13655 REPEAT STRIP_TAC THEN 13656 SUBGOAL_THEN ``{x - y | x:real IN s /\ y IN t} = 13657 {x + y | x IN s /\ y IN (IMAGE (\x. -x) t)}`` 13658 (fn th => ASM_SIMP_TAC std_ss [th, CLOSED_COMPACT_SUMS, COMPACT_NEGATIONS]) THEN 13659 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, IN_IMAGE] THEN 13660 ONCE_REWRITE_TAC[REAL_ARITH ``(x:real = -y) <=> (y = -x)``] THEN 13661 SIMP_TAC std_ss [real_sub, GSYM CONJ_ASSOC, UNWIND_THM2] THEN 13662 METIS_TAC[REAL_NEG_NEG]); 13663 13664val TRANSLATION_DIFF = store_thm ("TRANSLATION_DIFF", 13665 ``!s t:real->bool. 13666 IMAGE (\x. a + x) (s DIFF t) = 13667 (IMAGE (\x. a + x) s) DIFF (IMAGE (\x. a + x) t)``, 13668 SIMP_TAC std_ss [EXTENSION, IN_DIFF, IN_IMAGE] THEN 13669 ONCE_REWRITE_TAC[REAL_ARITH ``(x:real = a + y) <=> (y = x - a)``] THEN 13670 SIMP_TAC std_ss [UNWIND_THM2]); 13671 13672(* ------------------------------------------------------------------------- *) 13673(* Separation between points and sets. *) 13674(* ------------------------------------------------------------------------- *) 13675 13676val SEPARATE_POINT_CLOSED = store_thm ("SEPARATE_POINT_CLOSED", 13677 ``!s a:real. 13678 closed s /\ ~(a IN s) 13679 ==> ?d. &0 < d /\ !x. x IN s ==> d <= dist(a,x)``, 13680 REPEAT STRIP_TAC THEN 13681 ASM_CASES_TAC ``s:real->bool = {}`` THENL 13682 [EXISTS_TAC ``&1:real`` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY, REAL_LT_01], 13683 ALL_TAC] THEN 13684 MP_TAC(ISPECL [``s:real->bool``, ``a:real``] DISTANCE_ATTAINS_INF) THEN 13685 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC ``b:real`` THEN 13686 STRIP_TAC THEN EXISTS_TAC ``dist(a:real,b)`` THEN 13687 METIS_TAC[DIST_POS_LT]); 13688 13689val SEPARATE_COMPACT_CLOSED = store_thm ("SEPARATE_COMPACT_CLOSED", 13690 ``!s t:real->bool. 13691 compact s /\ closed t /\ (s INTER t = {}) 13692 ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)``, 13693 REPEAT STRIP_TAC THEN 13694 MP_TAC(ISPECL [``{x - y:real | x IN s /\ y IN t}``, ``0:real``] 13695 SEPARATE_POINT_CLOSED) THEN 13696 ASM_SIMP_TAC std_ss [COMPACT_CLOSED_DIFFERENCES, GSPECIFICATION, EXISTS_PROD] THEN 13697 REWRITE_TAC[REAL_ARITH ``(0 = x - y) <=> (x = y:real)``] THEN 13698 KNOW_TAC ``(!(p_1 :real) (p_2 :real). 13699 p_1 <> p_2 \/ p_1 NOTIN (s :real -> bool) \/ 13700 p_2 NOTIN (t :real -> bool))`` THENL 13701 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 13702 DISCH_THEN (X_CHOOSE_TAC ``d:real``) THEN EXISTS_TAC ``d:real`` THEN 13703 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 13704 REWRITE_TAC [dist] THEN 13705 METIS_TAC[REAL_ARITH ``abs(0 - (x - y)) = abs(x - y:real)``]); 13706 13707val SEPARATE_CLOSED_COMPACT = store_thm ("SEPARATE_CLOSED_COMPACT", 13708 ``!s t:real->bool. 13709 closed s /\ compact t /\ (s INTER t = {}) 13710 ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)``, 13711 ONCE_REWRITE_TAC[DIST_SYM, INTER_COMM] THEN 13712 MESON_TAC[SEPARATE_COMPACT_CLOSED]); 13713 13714(* ------------------------------------------------------------------------- *) 13715(* Representing sets as the union of a chain of compact sets. *) 13716(* ------------------------------------------------------------------------- *) 13717 13718val CLOSED_UNION_COMPACT_SUBSETS = store_thm ("CLOSED_UNION_COMPACT_SUBSETS", 13719 ``!s. closed s 13720 ==> ?f:num->real->bool. 13721 (!n. compact(f n)) /\ 13722 (!n. (f n) SUBSET s) /\ 13723 (!n. (f n) SUBSET f(n + 1)) /\ 13724 (BIGUNION {f n | n IN univ(:num)} = s) /\ 13725 (!k. compact k /\ k SUBSET s 13726 ==> ?N. !n. n >= N ==> k SUBSET (f n))``, 13727 REPEAT STRIP_TAC THEN 13728 EXISTS_TAC ``\n. s INTER cball(0:real,&n)`` THEN 13729 ASM_SIMP_TAC std_ss [INTER_SUBSET, COMPACT_CBALL, CLOSED_INTER_COMPACT] THEN 13730 REPEAT CONJ_TAC THENL 13731 [GEN_TAC THEN MATCH_MP_TAC(SET_RULE 13732 ``t SUBSET u ==> s INTER t SUBSET s INTER u``) THEN 13733 REWRITE_TAC[SUBSET_BALLS, DIST_REFL, GSYM REAL_OF_NUM_ADD] THEN 13734 REAL_ARITH_TAC, 13735 SIMP_TAC std_ss [EXTENSION, BIGUNION_GSPEC, GSPECIFICATION, IN_UNIV, IN_INTER] THEN 13736 X_GEN_TAC ``x:real`` THEN REWRITE_TAC[IN_CBALL_0] THEN 13737 MESON_TAC[SIMP_REAL_ARCH], 13738 X_GEN_TAC ``k:real->bool`` THEN SIMP_TAC std_ss [SUBSET_INTER] THEN 13739 REPEAT STRIP_TAC THEN 13740 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN DISCH_THEN 13741 (MP_TAC o SPEC ``0:real`` o MATCH_MP BOUNDED_SUBSET_CBALL) THEN 13742 DISCH_THEN(X_CHOOSE_THEN ``r:real`` STRIP_ASSUME_TAC) THEN 13743 MP_TAC(ISPEC ``r:real`` SIMP_REAL_ARCH) THEN 13744 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 13745 POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM REAL_OF_NUM_GE] THEN 13746 REPEAT STRIP_TAC THEN 13747 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 13748 SUBSET_TRANS)) THEN 13749 REWRITE_TAC[SUBSET_BALLS, DIST_REFL] THEN ASM_REAL_ARITH_TAC]); 13750 13751val OPEN_UNION_COMPACT_SUBSETS = store_thm ("OPEN_UNION_COMPACT_SUBSETS", 13752 ``!s. open s 13753 ==> ?f:num->real->bool. 13754 (!n. compact(f n)) /\ 13755 (!n. (f n) SUBSET s) /\ 13756 (!n. (f n) SUBSET interior(f(n + 1))) /\ 13757 (BIGUNION {f n | n IN univ(:num)} = s) /\ 13758 (!k. compact k /\ k SUBSET s 13759 ==> ?N. !n. n >= N ==> k SUBSET (f n))``, 13760 GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THENL 13761 [DISCH_TAC THEN EXISTS_TAC ``(\n. {}):num->real->bool`` THEN 13762 ASM_SIMP_TAC std_ss [EMPTY_SUBSET, SUBSET_EMPTY, COMPACT_EMPTY] THEN 13763 SIMP_TAC std_ss [EXTENSION, BIGUNION_GSPEC, GSPECIFICATION, NOT_IN_EMPTY], 13764 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 13765 DISCH_THEN(X_CHOOSE_TAC ``a:real``) THEN STRIP_TAC] THEN 13766 KNOW_TAC ``?(f :num -> real -> bool). 13767 (\f. !(n :num). compact (f n)) f /\ 13768 (\f. !(n :num). f n SUBSET (s :real -> bool)) f /\ 13769 (\f. !(n :num). f n SUBSET interior (f (n + (1 :num)))) f /\ 13770 (\f. BIGUNION {f n | n IN univ((:num) :num itself)} = s) f /\ 13771 (\f. !(k :real -> bool). 13772 compact k /\ k SUBSET s ==> 13773 ?(N :num). !(n :num). n >= N ==> k SUBSET f n) f`` THENL 13774 [ALL_TAC, METIS_TAC []] THEN 13775 MATCH_MP_TAC(METIS[] 13776 ``(!f. p1 f /\ p3 f /\ p4 f ==> p5 f) /\ 13777 (?f. p1 f /\ p2 f /\ p3 f /\ (p2 f ==> p4 f)) 13778 ==> ?f. p1 f /\ p2 f /\ p3 f /\ p4 f /\ p5 f``) THEN 13779 CONJ_TAC THENL 13780 [BETA_TAC THEN X_GEN_TAC ``f:num->real->bool`` THEN STRIP_TAC THEN 13781 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN 13782 X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN 13783 UNDISCH_TAC ``compact k`` THEN DISCH_TAC THEN 13784 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [COMPACT_EQ_HEINE_BOREL]) THEN 13785 DISCH_THEN(MP_TAC o SPEC ``{interior(f n):real->bool | n IN univ(:num)}``) THEN 13786 SIMP_TAC std_ss [FORALL_IN_GSPEC, OPEN_INTERIOR] THEN 13787 KNOW_TAC ``(k :real -> bool) SUBSET 13788 BIGUNION {interior ((f :num -> real -> bool) n) | 13789 n IN univ((:num) :num itself)}`` THENL 13790 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 13791 SUBSET_TRANS)) THEN 13792 SIMP_TAC std_ss [SUBSET_DEF, BIGUNION_GSPEC, GSPECIFICATION] THEN ASM_SET_TAC[], 13793 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 13794 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN 13795 ONCE_REWRITE_TAC [METIS [] ``interior (f n) = (\n. interior (f n)) (n:num)``] THEN 13796 SIMP_TAC std_ss [GSYM IMAGE_DEF, EXISTS_FINITE_SUBSET_IMAGE] THEN 13797 REWRITE_TAC[SUBSET_UNIV] THEN 13798 DISCH_THEN(X_CHOOSE_THEN ``i:num->bool`` STRIP_ASSUME_TAC) THEN 13799 FIRST_ASSUM(MP_TAC o SPEC ``\n:num. n`` o 13800 MATCH_MP UPPER_BOUND_FINITE_SET) THEN 13801 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 13802 POP_ASSUM MP_TAC THEN 13803 REWRITE_TAC[GE] THEN DISCH_TAC THEN X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 13804 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 13805 SUBSET_TRANS)) THEN 13806 SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_IMAGE] THEN 13807 X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN MATCH_MP_TAC SUBSET_TRANS THEN 13808 EXISTS_TAC ``(f:num->real->bool) m`` THEN 13809 REWRITE_TAC[INTERIOR_SUBSET] THEN 13810 SUBGOAL_THEN ``!m n. m <= n ==> (f:num->real->bool) m SUBSET f n`` 13811 (fn th => METIS_TAC[th, LESS_EQ_TRANS]) THEN 13812 ONCE_REWRITE_TAC [METIS [] ``f m SUBSET f n <=> (\m n. f m SUBSET f n) m n``] THEN 13813 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN 13814 METIS_TAC[SUBSET_DEF, ADD1, INTERIOR_SUBSET]], 13815 BETA_TAC THEN EXISTS_TAC ``\n. cball(a,&n) DIFF 13816 {x + e | x IN univ(:real) DIFF s /\ e IN ball(0,inv(&n + &1))}`` THEN 13817 SIMP_TAC std_ss [] THEN REPEAT CONJ_TAC THENL 13818 [X_GEN_TAC ``n:num`` THEN MATCH_MP_TAC COMPACT_DIFF THEN 13819 SIMP_TAC std_ss [COMPACT_CBALL, OPEN_SUMS, OPEN_BALL], 13820 GEN_TAC THEN MATCH_MP_TAC(SET_RULE 13821 ``(UNIV DIFF s) SUBSET t ==> c DIFF t SUBSET s``) THEN 13822 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN 13823 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 13824 MAP_EVERY EXISTS_TAC [``x:real``, ``0:real``] THEN 13825 ASM_SIMP_TAC std_ss [REAL_ADD_RID, CENTRE_IN_BALL, REAL_LT_INV_EQ] THEN 13826 SIMP_TAC std_ss [REAL_LT, REAL_OF_NUM_ADD] THEN ARITH_TAC, 13827 GEN_TAC THEN REWRITE_TAC[INTERIOR_DIFF] THEN MATCH_MP_TAC(SET_RULE 13828 ``s SUBSET s' /\ t' SUBSET t ==> (s DIFF t) SUBSET (s' DIFF t')``) THEN 13829 CONJ_TAC THENL 13830 [REWRITE_TAC[INTERIOR_CBALL, SUBSET_DEF, IN_BALL, IN_CBALL] THEN 13831 SIMP_TAC std_ss [GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC, 13832 MATCH_MP_TAC SUBSET_TRANS THEN 13833 EXISTS_TAC ``{x + e | x IN univ(:real) DIFF s /\ 13834 e IN cball(0,inv(&n + &2))}`` THEN 13835 CONJ_TAC THENL 13836 [MATCH_MP_TAC CLOSURE_MINIMAL THEN 13837 ASM_SIMP_TAC std_ss [CLOSED_COMPACT_SUMS, COMPACT_CBALL, 13838 GSYM OPEN_CLOSED] THEN 13839 KNOW_TAC ``ball (0,inv (&n + 1)) SUBSET ball (0,inv (&n + 1))`` THENL 13840 [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN 13841 SIMP_TAC std_ss [ball, cball, dist, GSYM REAL_OF_NUM_ADD, 13842 REAL_ARITH ``n + 1 + 1:real = n + 2``, 13843 GSPECIFICATION] THEN 13844 METIS_TAC [REAL_LE_LT], ALL_TAC] THEN 13845 SIMP_TAC std_ss [SUBSET_DEF, IN_BALL, IN_CBALL, GSYM REAL_OF_NUM_ADD] THEN 13846 SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD, dist, 13847 REAL_ARITH ``n + 1 + 1:real = n + 2``] THEN 13848 METIS_TAC [REAL_LE_LT], 13849 KNOW_TAC ``cball (0,inv (&n + &2)) SUBSET ball (0,inv (&n + &1))`` THENL 13850 [ALL_TAC, 13851 SIMP_TAC std_ss [cball, ball, dist, SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN 13852 METIS_TAC [REAL_LE_LT]] THEN 13853 REWRITE_TAC[SUBSET_DEF, IN_BALL, IN_CBALL, GSYM REAL_OF_NUM_ADD] THEN 13854 GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH 13855 ``a < b ==> x <= a ==> x < b:real``) THEN 13856 MATCH_MP_TAC REAL_LT_INV2 THEN 13857 SIMP_TAC arith_ss [REAL_LT, REAL_OF_NUM_ADD]]], 13858 DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 13859 ASM_SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_GSPEC] THEN 13860 SIMP_TAC std_ss [SUBSET_DEF, BIGUNION_GSPEC, IN_UNIV, GSPECIFICATION] THEN 13861 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN REWRITE_TAC[IN_DIFF] THEN 13862 SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, IN_BALL_0, EXISTS_PROD] THEN 13863 REWRITE_TAC[REAL_ARITH ``(x:real = y + e) <=> (e = x - y)``] THEN 13864 SIMP_TAC std_ss [TAUT `(p /\ q) /\ r <=> r /\ p /\ q`, UNWIND_THM2] THEN 13865 ONCE_REWRITE_TAC [METIS [DE_MORGAN_THM] 13866 ``(!p_1:real. p_1 IN s \/ ~(abs (x - p_1) < inv (&n + 1))) <=> 13867 ~(?p_1:real. (~(\p_1. (p_1 IN s)) p_1 /\ 13868 (\p_1. abs (x - p_1) < inv (&n + 1)) p_1))``] THEN 13869 REWRITE_TAC[METIS [] ``~(?x. ~P x /\ Q x) <=> !x. Q x ==> P x``] THEN 13870 UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN BETA_TAC THEN 13871 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_BALL]) THEN 13872 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 13873 ASM_REWRITE_TAC[SUBSET_DEF, IN_BALL, dist] THEN 13874 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 13875 UNDISCH_TAC ``0 < e:real`` THEN DISCH_TAC THEN 13876 FIRST_ASSUM(MP_TAC o ONCE_REWRITE_RULE [REAL_ARCH_INV]) THEN 13877 DISCH_THEN(X_CHOOSE_THEN ``N1:num`` STRIP_ASSUME_TAC) THEN 13878 MP_TAC(ISPEC ``abs(x - a:real)`` SIMP_REAL_ARCH) THEN 13879 DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN EXISTS_TAC ``N1 + N2:num`` THEN 13880 CONJ_TAC THENL 13881 [REWRITE_TAC[IN_CBALL] THEN ONCE_REWRITE_TAC[DIST_SYM, dist] THEN 13882 UNDISCH_TAC ``abs(x - a:real) <= &N2`` THEN 13883 REWRITE_TAC[dist, GSYM REAL_OF_NUM_ADD] THEN 13884 FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ] THEN 13885 DISCH_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN 13886 EXISTS_TAC ``&N2:real`` THEN ASM_REWRITE_TAC [] THEN 13887 SIMP_TAC arith_ss [REAL_OF_NUM_LE, REAL_OF_NUM_ADD], 13888 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 13889 SUBGOAL_THEN ``inv(&(N1 + N2) + &1) <= inv(&N1:real)`` MP_TAC THENL 13890 [MATCH_MP_TAC REAL_LE_INV2 THEN 13891 ASM_SIMP_TAC arith_ss [REAL_LT, LE_1] THEN 13892 REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN 13893 SIMP_TAC arith_ss [REAL_OF_NUM_LE, REAL_OF_NUM_ADD], 13894 METIS_TAC [REAL_LTE_TRANS, REAL_LET_TRANS, REAL_LE_TRANS, REAL_LT_TRANS]]]]]); 13895 13896(* ------------------------------------------------------------------------- *) 13897(* A cute way of denoting open and closed intervals using overloading. *) 13898(* ------------------------------------------------------------------------- *) 13899 13900Definition OPEN_interval : 13901 OPEN_interval ((a:real),(b:real)) = {x:real | a < x /\ x < b} 13902End 13903 13904Definition CLOSED_interval : 13905 CLOSED_interval (l :(real # real) list) = 13906 {x:real | FST (HD l) <= x /\ x <= SND (HD l)} 13907End 13908 13909val _ = overload_on ("interval", ``OPEN_interval``); 13910val _ = overload_on ("interval", ``CLOSED_interval``); 13911 13912val interval = store_thm ("interval", 13913 ``(interval (a,b) = {x:real | a < x /\ x < b}) /\ 13914 (interval [a,b] = {x:real | a <= x /\ x <= b})``, 13915 REWRITE_TAC [OPEN_interval, CLOSED_interval, HD]); 13916 13917val IN_INTERVAL = store_thm ("IN_INTERVAL", 13918 ``(x IN interval (a,b) <=> a < x /\ x < b) /\ 13919 (x IN interval [a,b] <=> a <= x /\ x <= b)``, 13920 SIMP_TAC std_ss [interval, GSPECIFICATION]); 13921 13922val IN_INTERVAL_REFLECT = store_thm ("IN_INTERVAL_REFLECT", 13923 ``(!a b x. (-x) IN interval[-b,-a] <=> x IN interval[a,b]) /\ 13924 (!a b x. (-x) IN interval(-b,-a) <=> x IN interval(a,b))``, 13925 SIMP_TAC std_ss [IN_INTERVAL, REAL_LT_NEG, REAL_LE_NEG] THEN 13926 METIS_TAC[]); 13927 13928val REFLECT_INTERVAL = store_thm ("REFLECT_INTERVAL", 13929 ``(!a b:real. IMAGE (\x. -x) (interval[a,b]) = interval[-b,-a]) /\ 13930 (!a b:real. IMAGE (\x. -x) (interval(a,b)) = interval(-b,-a))``, 13931 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_INTERVAL, 13932 IN_IMAGE] THEN REPEAT STRIP_TAC THEN EQ_TAC THEN 13933 METIS_TAC [REAL_LE_NEG, REAL_LT_NEG, REAL_NEG_NEG]); 13934 13935val INTERVAL_EQ_EMPTY = store_thm ("INTERVAL_EQ_EMPTY", 13936 ``!a b. (b < a <=> (interval [a,b] = {})) /\ 13937 (b <= a <=> (interval (a,b) = {}))``, 13938 REPEAT GEN_TAC THEN CONJ_TAC THENL 13939 [EQ_TAC THENL [RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN EQ_TAC THENL 13940 [SIMP_TAC std_ss [NOT_IN_EMPTY] THEN CCONTR_TAC THEN 13941 FULL_SIMP_TAC std_ss [REAL_NEG_NEG] THEN UNDISCH_TAC (Term `b < a:real`) THEN 13942 FULL_SIMP_TAC std_ss [REAL_NOT_LT] THEN MATCH_MP_TAC REAL_LE_TRANS THEN 13943 EXISTS_TAC ``x:real`` THEN ASM_REWRITE_TAC [], SIMP_TAC std_ss [NOT_IN_EMPTY]], 13944 RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN 13945 CCONTR_TAC THEN UNDISCH_TAC (Term `!x:real. a <= x /\ x <= b <=> x IN {}`) THEN 13946 FULL_SIMP_TAC std_ss [NOT_IN_EMPTY, REAL_NOT_LT] THEN EXISTS_TAC ``a:real`` 13947 THEN FULL_SIMP_TAC std_ss [REAL_LE_LT]], 13948 EQ_TAC THENL [RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN EQ_TAC THENL 13949 [SIMP_TAC std_ss [NOT_IN_EMPTY] THEN CCONTR_TAC THEN 13950 FULL_SIMP_TAC std_ss [REAL_NEG_NEG] THEN UNDISCH_TAC (Term `b <= a:real`) THEN 13951 FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN MATCH_MP_TAC REAL_LT_TRANS THEN 13952 EXISTS_TAC ``x:real`` THEN ASM_REWRITE_TAC [], SIMP_TAC std_ss [NOT_IN_EMPTY]], 13953 RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN 13954 CCONTR_TAC THEN UNDISCH_TAC (Term `!x:real. a < x /\ x < b <=> x IN {}`) THEN 13955 FULL_SIMP_TAC std_ss [NOT_IN_EMPTY, REAL_NOT_LE, REAL_MEAN]]]); 13956 13957val INTERVAL_NE_EMPTY = store_thm ("INTERVAL_NE_EMPTY", 13958 ``(~(interval [a:real,b] = {}) <=> a <= b) /\ 13959 (~(interval (a:real,b) = {}) <=> a < b)``, 13960 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, NOT_IN_EMPTY, IN_INTERVAL] THEN 13961 CONJ_TAC THEN EQ_TAC THENL [SIMP_TAC std_ss [REAL_LE_TRANS], 13962 DISCH_TAC THEN EXISTS_TAC ``a:real`` THEN ASM_SIMP_TAC std_ss [REAL_LE_LT], 13963 SIMP_TAC std_ss [REAL_LT_TRANS], FULL_SIMP_TAC std_ss [REAL_MEAN]]); 13964 13965val SUBSET_INTERVAL_IMP = store_thm ("SUBSET_INTERVAL_IMP", 13966 ``((a <= c /\ d <= b) ==> interval[c,d] SUBSET interval[a:real,b]) /\ 13967 ((a < c /\ d < b) ==> interval[c,d] SUBSET interval(a:real,b)) /\ 13968 ((a <= c /\ d <= b) ==> interval(c,d) SUBSET interval[a:real,b]) /\ 13969 ((a <= c /\ d <= b) ==> interval(c,d) SUBSET interval(a:real,b))``, 13970 REWRITE_TAC[SUBSET_DEF, IN_INTERVAL] THEN REPEAT CONJ_TAC THEN 13971 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM MP_TAC THEN REPEAT STRIP_TAC THEN 13972 METIS_TAC [REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS, REAL_LT_IMP_LE]); 13973 13974val INTERVAL_SING = store_thm ("INTERVAL_SING", 13975 ``(interval[a,a] = {a}) /\ (interval(a,a) = {})``, 13976 REWRITE_TAC[EXTENSION, IN_SING, NOT_IN_EMPTY, IN_INTERVAL] THEN 13977 REWRITE_TAC[REAL_LE_ANTISYM, REAL_LT_ANTISYM] THEN 13978 MESON_TAC[EQ_SYM_EQ]); 13979 13980val SUBSET_INTERVAL = store_thm ("SUBSET_INTERVAL", 13981 ``(interval[c,d] SUBSET interval[a:real,b] <=> 13982 (c <= d) ==> (a <= c /\ d <= b)) /\ 13983 (interval[c,d] SUBSET interval(a:real,b) <=> 13984 (c <= d) ==> (a < c /\ d < b)) /\ 13985 (interval(c,d) SUBSET interval[a:real,b] <=> 13986 (c < d) ==> (a <= c /\ d <= b)) /\ 13987 (interval(c,d) SUBSET interval(a:real,b) <=> 13988 (c < d) ==> (a <= c /\ d <= b))``, 13989 REPEAT STRIP_TAC THEN 13990 (MATCH_MP_TAC(TAUT 13991 `(~q ==> p) /\ (q ==> (p <=> r)) ==> (p <=> q ==> r)`) THEN 13992 CONJ_TAC THENL 13993 [DISCH_TAC THEN MATCH_MP_TAC(SET_RULE ``(s = {}) ==> s SUBSET t``) THEN 13994 ASM_MESON_TAC[INTERVAL_EQ_EMPTY, REAL_NOT_LE], ALL_TAC] THEN 13995 DISCH_TAC THEN EQ_TAC THEN REWRITE_TAC[SUBSET_INTERVAL_IMP] THEN 13996 REWRITE_TAC[SUBSET_DEF, IN_INTERVAL]) THENL 13997 [KNOW_TAC ``((?y. c <= y /\ y <= d) 13998 ==> (!y. c <= y /\ y <= d 13999 ==> a <= y /\ y <= b)) 14000 ==> (a <= c:real /\ d <= b:real)`` THENL 14001 [ALL_TAC, METIS_TAC []] THEN 14002 KNOW_TAC ``(?y:real. c <= y /\ y <= d)`` THENL 14003 [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 14004 STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_TRANS, REAL_LE_REFL], 14005 KNOW_TAC ``((?y. c <= y /\ y <= d) 14006 ==> (!y. c <= y /\ y <= d 14007 ==> a < y /\ y < b)) 14008 ==> (a < c:real /\ d < b:real)`` THENL 14009 [ALL_TAC, METIS_TAC []] THEN 14010 KNOW_TAC ``(?y:real. c <= y /\ y <= d)`` THENL 14011 [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 14012 STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_TRANS, REAL_LE_REFL], 14013 KNOW_TAC ``((?y. c < y /\ y < d) 14014 ==> (!y. c < y /\ y < d 14015 ==> a <= y /\ y <= b)) 14016 ==> (a <= c:real /\ d <= b:real)`` THENL 14017 [ALL_TAC, METIS_TAC []] THEN 14018 KNOW_TAC ``(?y:real. c < y /\ y < d)`` THENL 14019 [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 14020 REPEAT STRIP_TAC THENL 14021 [CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a <= y /\ y <= b`` THEN 14022 FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN 14023 EXISTS_TAC ``((c:real) + min ((a:real)) ((d:real))) / &2:real`` THEN 14024 METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ, 14025 GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2, 14026 REAL_LTE_ADD2, REAL_NOT_LE], 14027 CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a <= y /\ y <= b`` THEN 14028 FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN 14029 EXISTS_TAC ``(max ((b:real)) ((c:real)) + (d:real)) / &2:real`` THEN 14030 METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ, 14031 GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2, 14032 REAL_LTE_ADD2, REAL_NOT_LE]], 14033 KNOW_TAC ``((?y. c < y /\ y < d) 14034 ==> (!y. c < y /\ y < d 14035 ==> a < y /\ y < b)) 14036 ==> (a <= c:real /\ d <= b:real)`` THENL 14037 [ALL_TAC, METIS_TAC []] THEN 14038 KNOW_TAC ``(?y:real. c < y /\ y < d)`` THENL 14039 [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 14040 REPEAT STRIP_TAC THENL 14041 [CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a < y /\ y < b`` THEN 14042 FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN 14043 EXISTS_TAC ``((c:real) + min ((a:real)) ((d:real))) / &2:real`` THEN 14044 METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ, 14045 GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2, 14046 REAL_LTE_ADD2, REAL_NOT_LE, REAL_NOT_LT, REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ, 14047 REAL_LE_LADD, REAL_LE_ADD2, REAL_LE_RADD, REAL_LE_LT], 14048 CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a < y /\ y < b`` THEN 14049 FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN 14050 EXISTS_TAC ``(max ((b:real)) ((c:real)) + (d:real)) / &2:real`` THEN 14051 METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ, 14052 GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2, 14053 REAL_LTE_ADD2, REAL_NOT_LE, REAL_NOT_LT, REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ, 14054 REAL_LE_LADD, REAL_LE_ADD2, REAL_LE_RADD, REAL_LE_LT]]]); 14055 14056val DISJOINT_INTERVAL = store_thm ("DISJOINT_INTERVAL", 14057 ``!a b c d:real. 14058 ((interval[a,b] INTER interval[c,d] = {}) <=> 14059 b < a \/ d < c \/ 14060 b < c \/ d < a) /\ 14061 ((interval[a,b] INTER interval(c,d) = {}) <=> 14062 b < a \/ d <= c \/ 14063 b <= c \/ d <= a) /\ 14064 ((interval(a,b) INTER interval[c,d] = {}) <=> 14065 b <= a \/ d < c \/ 14066 b <= c \/ d <= a) /\ 14067 ((interval(a,b) INTER interval(c,d) = {}) <=> 14068 b <= a \/ d <= c \/ 14069 b <= c \/ d <= a)``, 14070 REWRITE_TAC [EXTENSION, IN_INTER, IN_INTERVAL, NOT_IN_EMPTY] THEN 14071 SIMP_TAC std_ss [GSYM FORALL_AND_THM, NOT_FORALL_THM] THEN 14072 REWRITE_TAC [TAUT `~((p ==> q) /\ (p ==> r)) <=> p /\ (~q \/ ~r)`] THEN 14073 REWRITE_TAC [DE_MORGAN_THM] THEN 14074 REPEAT STRIP_TAC THEN (* 4 subgoals *) 14075 (EQ_TAC THENL 14076 [DISCH_THEN (MP_TAC o SPEC ``(@f. f = (max ((a:real)) ((c:real)) + 14077 min ((b:real)) ((d:real))) / &2):real``) THEN 14078 DISCH_TAC THEN 14079 FULL_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ, 14080 REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ, 14081 REAL_ARITH ``0 < 2:real``] THEN (* 4 subgoals *) 14082 FULL_SIMP_TAC bool_ss [REAL_NOT_LE, min_def, max_def] THEN 14083 POP_ASSUM MP_TAC THEN 14084 REPEAT COND_CASES_TAC THEN ASM_REAL_ARITH_TAC, 14085 14086 DISCH_THEN (fn th => GEN_TAC THEN MP_TAC th) THEN 14087 SIMP_TAC std_ss [] THEN REAL_ARITH_TAC ])); 14088 14089val ENDS_IN_INTERVAL = store_thm ("ENDS_IN_INTERVAL", 14090 ``(!a b. a IN interval[a,b] <=> ~(interval[a,b] = {})) /\ 14091 (!a b. b IN interval[a,b] <=> ~(interval[a,b] = {})) /\ 14092 (!a b. ~(a IN interval(a,b))) /\ 14093 (!a b. ~(b IN interval(a,b)))``, 14094 REWRITE_TAC[IN_INTERVAL, INTERVAL_NE_EMPTY] THEN 14095 REWRITE_TAC[REAL_LE_REFL, REAL_LT_REFL] THEN 14096 MESON_TAC[REAL_LE_REFL]); 14097 14098val ENDS_IN_UNIT_INTERVAL = store_thm ("ENDS_IN_UNIT_INTERVAL", 14099 ``0 IN interval[0,1] /\ 1 IN interval[0,1] /\ 14100 ~(0 IN interval(0,1)) /\ ~(1 IN interval(0,1))``, 14101 REWRITE_TAC[ENDS_IN_INTERVAL, INTERVAL_NE_EMPTY] THEN 14102 REWRITE_TAC[REAL_POS]); 14103 14104val INTER_INTERVAL = store_thm ("INTER_INTERVAL", 14105 ``interval[a,b] INTER interval[c,d] = 14106 interval[(max (a) (c)),(min (b) (d))]``, 14107 REWRITE_TAC[EXTENSION, IN_INTER, IN_INTERVAL] THEN 14108 SIMP_TAC std_ss [REAL_MAX_LE, REAL_LE_MIN] THEN MESON_TAC[]); 14109 14110val INTERVAL_OPEN_SUBSET_CLOSED = store_thm ("INTERVAL_OPEN_SUBSET_CLOSED", 14111 ``!a b. interval(a,b) SUBSET interval[a,b]``, 14112 REWRITE_TAC[SUBSET_DEF, IN_INTERVAL] THEN MESON_TAC[REAL_LT_IMP_LE]); 14113 14114val OPEN_INTERVAL_LEMMA = store_thm ("OPEN_INTERVAL_LEMMA", 14115 ``!a b x. a < x /\ x < b 14116 ==> ?d. (0:real) < d /\ !x'. abs(x' - x) < d ==> a < x' /\ x' < b``, 14117 REPEAT STRIP_TAC THEN 14118 EXISTS_TAC ``min (x - a) (b - x:real)`` THEN REWRITE_TAC[REAL_LT_MIN] THEN 14119 REPEAT (POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC); 14120 14121val OPEN_INTERVAL = store_thm ("OPEN_INTERVAL", 14122 ``!a:real b. open(interval (a,b))``, 14123 REPEAT GEN_TAC THEN 14124 SIMP_TAC std_ss [open_def, interval, GSPECIFICATION, dist, OPEN_INTERVAL_LEMMA]); 14125 14126val CLOSED_INTERVAL = store_thm ("CLOSED_INTERVAL", 14127 ``!a:real b. closed(interval [a,b])``, 14128 REWRITE_TAC[CLOSED_LIMPT, LIMPT_APPROACHABLE, IN_INTERVAL] THEN 14129 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THENL 14130 [FIRST_X_ASSUM(MP_TAC o SPEC ``(a:real) - (x:real)``), 14131 FIRST_X_ASSUM(MP_TAC o SPEC ``(x:real) - (b:real)``)] THEN 14132 ASM_REWRITE_TAC[REAL_SUB_LT] THEN 14133 DISCH_THEN(X_CHOOSE_THEN ``z:real`` MP_TAC) THEN 14134 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 14135 REWRITE_TAC[dist, REAL_NOT_LT] THEN 14136 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``abs((z - x :real))`` THEN 14137 ASM_SIMP_TAC std_ss [REAL_ARITH ``x < a /\ a <= z ==> a - x:real <= abs(z - x)``, 14138 REAL_ARITH ``z <= b /\ b < x ==> x - b:real <= abs(z - x)``, 14139 REAL_LE_REFL]); 14140 14141val INTERIOR_CLOSED_INTERVAL = store_thm ("INTERIOR_CLOSED_INTERVAL", 14142 ``!a:real b. interior(interval [a,b]) = interval (a,b)``, 14143 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 14144 [ALL_TAC, 14145 MATCH_MP_TAC INTERIOR_MAXIMAL THEN 14146 REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED, OPEN_INTERVAL]] THEN 14147 SIMP_TAC std_ss [interior, SUBSET_DEF, IN_INTERVAL, GSPECIFICATION] THEN 14148 X_GEN_TAC ``x:real`` THEN 14149 DISCH_THEN(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN 14150 ASM_SIMP_TAC std_ss [REAL_LT_LE] THEN REPEAT STRIP_TAC THEN 14151 UNDISCH_TAC ``open s`` THEN REWRITE_TAC [open_def] THEN 14152 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 14153 DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THENL 14154 [DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x - (e / 2:real)`), 14155 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x + (e / 2:real)`)] THEN 14156 ASM_SIMP_TAC std_ss [dist, REAL_ADD_SUB, REAL_ARITH ``x - y - x = -y:real``, 14157 REAL_ARITH ``x + y - x = y:real``] THEN 14158 ASM_SIMP_TAC std_ss [ABS_MUL, ABS_NEG, REAL_MUL_RID] THENL [CONJ_TAC THENL 14159 [METIS_TAC [ABS_REFL, REAL_LT_HALF1, REAL_LT_HALF2, REAL_LE_LT], ALL_TAC], 14160 CONJ_TAC THENL [METIS_TAC [ABS_REFL, REAL_LT_HALF1, REAL_LT_HALF2, REAL_LE_LT], 14161 ALL_TAC]] THEN CCONTR_TAC THEN 14162 UNDISCH_TAC ``!x. x IN s ==> a <= x /\ x <= b:real`` THEN DISCH_TAC THENL 14163 [POP_ASSUM (MP_TAC o Q.SPEC `x - e / 2:real`), 14164 POP_ASSUM (MP_TAC o Q.SPEC `x + e / 2:real`)] THEN FULL_SIMP_TAC std_ss [] THENL 14165 [DISJ1_TAC THEN REWRITE_TAC[REAL_ARITH ``a <= a - b <=> ~(&0 < b:real)``], 14166 DISJ2_TAC THEN REWRITE_TAC[REAL_ARITH ``a + b <= a <=> ~(&0 < b:real)``]] THEN 14167 FULL_SIMP_TAC std_ss [REAL_LT_HALF1]); 14168 14169val INTERIOR_INTERVAL = store_thm ("INTERIOR_INTERVAL", 14170 ``(!a b. interior(interval[a,b]) = interval(a,b)) /\ 14171 (!a b. interior(interval(a,b)) = interval(a,b))``, 14172 SIMP_TAC std_ss [INTERIOR_CLOSED_INTERVAL, INTERIOR_OPEN, OPEN_INTERVAL]); 14173 14174val BOUNDED_CLOSED_INTERVAL = store_thm ("BOUNDED_CLOSED_INTERVAL", 14175 ``!a b:real. bounded (interval [a,b])``, 14176 REPEAT STRIP_TAC THEN REWRITE_TAC[bounded_def, interval] THEN 14177 SIMP_TAC std_ss [GSPECIFICATION] THEN 14178 EXISTS_TAC ``abs(a) + abs(b:real)`` THEN REAL_ARITH_TAC); 14179 14180val BOUNDED_INTERVAL = store_thm ("BOUNDED_INTERVAL", 14181 ``(!a b. bounded (interval [a,b])) /\ (!a b. bounded (interval (a,b)))``, 14182 MESON_TAC[BOUNDED_CLOSED_INTERVAL, BOUNDED_SUBSET, 14183 INTERVAL_OPEN_SUBSET_CLOSED]); 14184 14185val NOT_INTERVAL_UNIV = store_thm ("NOT_INTERVAL_UNIV", 14186 ``(!a b. ~(interval[a,b] = UNIV)) /\ 14187 (!a b. ~(interval(a,b) = UNIV))``, 14188 MESON_TAC[BOUNDED_INTERVAL, NOT_BOUNDED_UNIV]); 14189 14190val COMPACT_INTERVAL = store_thm ("COMPACT_INTERVAL", 14191 ``!a b. compact (interval [a,b])``, 14192 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTERVAL, CLOSED_INTERVAL]); 14193 14194val OPEN_INTERVAL_MIDPOINT = store_thm ("OPEN_INTERVAL_MIDPOINT", 14195 ``!a b:real. 14196 ~(interval(a,b) = {}) ==> (inv(&2) * (a + b)) IN interval(a,b)``, 14197 REWRITE_TAC[INTERVAL_NE_EMPTY, IN_INTERVAL] THEN 14198 ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN ONCE_REWRITE_TAC [GSYM real_div] THEN 14199 KNOW_TAC ``0 < 2:real`` THENL [REAL_ARITH_TAC, ALL_TAC] THEN 14200 REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ] THEN 14201 REWRITE_TAC [REAL_MUL_COMM, GSYM REAL_DOUBLE] THEN 14202 FULL_SIMP_TAC std_ss [REAL_LT_LADD, REAL_LT_RADD]); 14203 14204val OPEN_CLOSED_INTERVAL_CONVEX = store_thm ("OPEN_CLOSED_INTERVAL_CONVEX", 14205 ``!a b x y:real e. 14206 x IN interval(a,b) /\ y IN interval[a,b] /\ &0 < e /\ e <= &1 14207 ==> (e * x + (&1 - e) * y) IN interval(a,b)``, 14208 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT 14209 `(c /\ d ==> a /\ b ==> e) ==> a /\ b /\ c /\ d ==> e`) THEN 14210 STRIP_TAC THEN REWRITE_TAC[IN_INTERVAL] THEN STRIP_TAC THEN 14211 SUBST1_TAC(REAL_ARITH ``(a:real) = e * a + (&1 - e) * a``) THEN 14212 SUBST1_TAC(REAL_ARITH ``(b:real) = e * b + (&1 - e) * b``) THEN 14213 KNOW_TAC ``0:real <= 1 - e`` THENL 14214 [FULL_SIMP_TAC std_ss [REAL_SUB_LE], ALL_TAC] THEN 14215 REWRITE_TAC [REAL_LE_LT] THEN STRIP_TAC THENL 14216 [CONJ_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN 14217 ASM_SIMP_TAC std_ss [REAL_LT_LMUL, REAL_LE_LMUL, REAL_SUB_LE], 14218 POP_ASSUM MP_TAC THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN 14219 DISCH_TAC THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN 14220 ASM_SIMP_TAC std_ss [REAL_LT_LMUL, REAL_LE_LMUL, REAL_SUB_LE, REAL_MUL_LZERO, REAL_LE_REFL]]); 14221 14222val REAL_LE_INV2 = store_thm ("REAL_LE_INV2", 14223 ``!x:real y. &0 < x /\ x <= y ==> inv(y) <= inv(x)``, 14224 REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN 14225 ASM_CASES_TAC ``x:real = y`` THEN ASM_REWRITE_TAC[] THEN 14226 STRIP_TAC THEN DISJ1_TAC THEN MATCH_MP_TAC REAL_LT_INV THEN 14227 ASM_REWRITE_TAC[]); 14228 14229val REAL_INV_LE_1 = store_thm ("REAL_INV_LE_1", 14230 ``!x:real. &1 <= x ==> inv(x) <= &1``, 14231 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_INV1] THEN 14232 MATCH_MP_TAC REAL_LE_INV2 THEN ASM_REWRITE_TAC[REAL_LT_01]); 14233 14234val CLOSURE_OPEN_INTERVAL = store_thm ("CLOSURE_OPEN_INTERVAL", 14235 ``!a b:real. 14236 ~(interval(a,b) = {}) ==> (closure(interval(a,b)) = interval[a,b])``, 14237 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 14238 [MATCH_MP_TAC CLOSURE_MINIMAL THEN 14239 REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED, CLOSED_INTERVAL], 14240 ALL_TAC] THEN 14241 REWRITE_TAC[SUBSET_DEF, closure, IN_UNION] THEN X_GEN_TAC ``x:real`` THEN 14242 DISCH_TAC THEN MATCH_MP_TAC(TAUT `(~b ==> c) ==> b \/ c`) THEN DISCH_TAC THEN 14243 SIMP_TAC std_ss [GSPECIFICATION, LIMPT_SEQUENTIAL] THEN 14244 ABBREV_TAC ``(c:real) = inv(&2:real) * (a + b)`` THEN 14245 EXISTS_TAC ``\n. (x:real) + inv(&n + &1:real) * (c - x)`` THEN CONJ_TAC THENL 14246 [X_GEN_TAC ``n:num`` THEN REWRITE_TAC[IN_DELETE] THEN BETA_TAC THEN 14247 REWRITE_TAC[REAL_ARITH ``(x + a = x) <=> (a = 0:real)``] THEN 14248 REWRITE_TAC[REAL_ENTIRE, REAL_INV_EQ_0] THEN 14249 SIMP_TAC std_ss [REAL_SUB_0, REAL_OF_NUM_SUC, SUC_NOT, REAL_OF_NUM_EQ, EQ_SYM_EQ] THEN 14250 CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT]] THEN 14251 REWRITE_TAC[REAL_ARITH ``x + a * (y - x) = a * y + (&1 - a) * x:real``] THEN 14252 MATCH_MP_TAC OPEN_CLOSED_INTERVAL_CONVEX THEN 14253 CONJ_TAC THENL [ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT], ALL_TAC] THEN 14254 KNOW_TAC ``&0:real < &n + &1`` THENL [SIMP_TAC std_ss [REAL_OF_NUM_SUC] THEN 14255 ASM_REWRITE_TAC[REAL_LT_INV_EQ, REAL_OF_NUM_SUC, REAL_LT, LESS_0], ALL_TAC] THEN 14256 DISCH_TAC THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ, REAL_OF_NUM_SUC, REAL_LT, LESS_0] THEN 14257 MATCH_MP_TAC REAL_INV_LE_1 THEN REWRITE_TAC [REAL_LE, ONE, LESS_EQ_MONO, 14258 ZERO_LESS_EQ], ALL_TAC] THEN 14259 GEN_REWR_TAC LAND_CONV [REAL_ARITH ``x:real = x + &0 * (c - x)``] THEN 14260 KNOW_TAC ``!n:num x:real. (\n. x + inv (&n + 1) * (c - x)) = 14261 (\n. (\n. x) n + (\n. inv (&n + 1) * (c - x)) n)`` THENL 14262 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 14263 MATCH_MP_TAC LIM_ADD THEN REWRITE_TAC[LIM_CONST] THEN 14264 KNOW_TAC ``!n:num. (\n. inv (&n + 1) * (c - x:real)) = 14265 (\n. (\n. inv (&n + 1)) n * (\n. (c - x)) n)`` THENL 14266 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 14267 MATCH_MP_TAC LIM_MUL THEN REWRITE_TAC[LIM_CONST] THEN 14268 REWRITE_TAC[LIM_SEQUENTIALLY, o_THM, REAL_SUB_RZERO] THEN BETA_TAC THEN 14269 X_GEN_TAC ``e:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_ARCH_INV] THEN 14270 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 14271 X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 14272 KNOW_TAC ``&n + 1 <> 0:real`` THENL 14273 [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN 14274 SIMP_TAC arith_ss [REAL_OF_NUM_SUC, REAL_LT, ADD1], ALL_TAC] THEN DISCH_TAC THEN 14275 ASM_SIMP_TAC std_ss [DIST_0, ABS_INV] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 14276 EXISTS_TAC ``inv(&N:real)`` THEN ASM_REWRITE_TAC[] THEN 14277 MATCH_MP_TAC REAL_LE_INV2 THEN FULL_SIMP_TAC std_ss [] THEN 14278 UNDISCH_TAC ``N:num <= n`` THEN UNDISCH_TAC ``N <> 0:num`` THEN 14279 REWRITE_TAC[NOT_ZERO_LT_ZERO, GSYM REAL_OF_NUM_LE, GSYM REAL_LT] THEN 14280 REAL_ARITH_TAC); 14281 14282val CLOSURE_INTERVAL = store_thm ("CLOSURE_INTERVAL", 14283 ``(!a b. closure(interval[a,b]) = interval[a,b]) /\ 14284 (!a b. closure(interval(a,b)) = 14285 if interval(a,b) = {} then {} else interval[a,b])``, 14286 SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_INTERVAL] THEN REPEAT GEN_TAC THEN 14287 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [CLOSURE_OPEN_INTERVAL, CLOSURE_EMPTY]); 14288 14289val BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC = store_thm ("BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC", 14290 ``!s:real->bool. bounded s ==> ?a. s SUBSET interval(-a,a)``, 14291 SIMP_TAC std_ss [BOUNDED_POS, LEFT_IMP_EXISTS_THM] THEN 14292 MAP_EVERY X_GEN_TAC [``s:real->bool``, ``B:real``] THEN STRIP_TAC THEN 14293 EXISTS_TAC ``(B + &1):real`` THEN 14294 REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 14295 SIMP_TAC std_ss [IN_INTERVAL, REAL_BOUNDS_LT] THEN 14296 METIS_TAC[REAL_LE_REFL, REAL_ARITH ``x <= y ==> a <= x ==> a < y + &1:real``]); 14297 14298val BOUNDED_SUBSET_OPEN_INTERVAL = store_thm ("BOUNDED_SUBSET_OPEN_INTERVAL", 14299 ``!s:real->bool. bounded s ==> ?a b. s SUBSET interval(a,b)``, 14300 MESON_TAC[BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC]); 14301 14302val BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC = store_thm ("BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC", 14303 ``!s:real->bool. bounded s ==> ?a. s SUBSET interval[-a,a]``, 14304 GEN_TAC THEN 14305 DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC) THEN 14306 STRIP_TAC THEN EXISTS_TAC ``a:real`` THEN POP_ASSUM MP_TAC THEN 14307 SIMP_TAC std_ss [IN_BALL, IN_INTERVAL, SUBSET_DEF, REAL_LT_IMP_LE]); 14308 14309val BOUNDED_SUBSET_CLOSED_INTERVAL = store_thm ("BOUNDED_SUBSET_CLOSED_INTERVAL", 14310 ``!s:real->bool. bounded s ==> ?a b. s SUBSET interval[a,b]``, 14311 MESON_TAC[BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC]); 14312 14313val FRONTIER_CLOSED_INTERVAL = store_thm ("FRONTIER_CLOSED_INTERVAL", 14314 ``!a b. frontier(interval[a,b]) = interval[a,b] DIFF interval(a,b)``, 14315 SIMP_TAC std_ss [frontier, INTERIOR_CLOSED_INTERVAL, CLOSURE_CLOSED, 14316 CLOSED_INTERVAL]); 14317 14318val FRONTIER_OPEN_INTERVAL = store_thm ("FRONTIER_OPEN_INTERVAL", 14319 ``!a b. frontier(interval(a,b)) = 14320 if interval(a,b) = {} then {} 14321 else interval[a,b] DIFF interval(a,b)``, 14322 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[FRONTIER_EMPTY] THEN 14323 ASM_SIMP_TAC std_ss [frontier, CLOSURE_OPEN_INTERVAL, INTERIOR_OPEN, 14324 OPEN_INTERVAL]); 14325 14326val INTER_INTERVAL_MIXED_EQ_EMPTY = store_thm ("INTER_INTERVAL_MIXED_EQ_EMPTY", 14327 ``!a b c d:real. 14328 ~(interval(c,d) = {}) 14329 ==> ((interval(a,b) INTER interval[c,d] = {}) <=> 14330 (interval(a,b) INTER interval(c,d) = {}))``, 14331 SIMP_TAC std_ss [GSYM CLOSURE_OPEN_INTERVAL, OPEN_INTER_CLOSURE_EQ_EMPTY, 14332 OPEN_INTERVAL]); 14333 14334val INTERVAL_TRANSLATION = store_thm ("INTERVAL_TRANSLATION", 14335 ``(!c a b. interval[c + a,c + b] = IMAGE (\x. c + x) (interval[a,b])) /\ 14336 (!c a b. interval(c + a,c + b) = IMAGE (\x. c + x) (interval(a,b)))``, 14337 REWRITE_TAC[interval] THEN CONJ_TAC THEN 14338 (SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN 14339 REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN 14340 TRY (EXISTS_TAC ``-c + x:real``) THEN ASM_REAL_ARITH_TAC)); 14341 14342val EMPTY_AS_INTERVAL = store_thm ("EMPTY_AS_INTERVAL", 14343 ``{} = interval[1,0]``, 14344 SIMP_TAC std_ss [EXTENSION, NOT_IN_EMPTY, IN_INTERVAL] THEN 14345 REAL_ARITH_TAC); 14346 14347val UNIT_INTERVAL_NONEMPTY = store_thm ("UNIT_INTERVAL_NONEMPTY", 14348 ``~(interval[0:real,1] = {}) /\ 14349 ~(interval(0:real,1) = {})``, 14350 SIMP_TAC std_ss [INTERVAL_NE_EMPTY, REAL_LT_01, REAL_POS]); 14351 14352val IMAGE_STRETCH_INTERVAL = store_thm 14353 ("IMAGE_STRETCH_INTERVAL", 14354 ``!a b:real m. 14355 IMAGE (\x. @f. f = m(1:num) * x) (interval[a,b]) = 14356 if interval[a,b] = {} then {} 14357 else interval[(@f. f = min (m(1:num) * a) (m(1:num) * b)):real, 14358 (@f. f = max (m(1:num) * a) (m(1:num) * b))]``, 14359 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [IMAGE_EMPTY, IMAGE_INSERT] THEN 14360 ASM_SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_INTERVAL, GSYM FORALL_AND_THM, 14361 TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN 14362 X_GEN_TAC ``x:real`` THEN 14363 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [INTERVAL_NE_EMPTY]) THEN 14364 ASM_CASES_TAC ``(m:num->real) (1:num) = &0`` THENL 14365 [ASM_SIMP_TAC std_ss [REAL_MUL_LZERO, REAL_MAX_ACI, REAL_MIN_ACI] THEN 14366 METIS_TAC[REAL_LE_ANTISYM, REAL_LE_REFL], 14367 ALL_TAC] THEN 14368 KNOW_TAC ``!m x y:real. ~(m = 0:real) ==> ((x = m * y) <=> (y = x / m))`` THENL 14369 [REPEAT GEN_TAC THEN DISCH_TAC THEN ASSUME_TAC REAL_LE_TOTAL THEN 14370 GEN_REWR_TAC RAND_CONV [EQ_SYM_EQ] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 14371 POP_ASSUM (MP_TAC o Q.SPECL [`m':real`,`0:real`]) THEN 14372 ASM_SIMP_TAC std_ss [REAL_LE_LT] THEN STRIP_TAC THENL 14373 [ALL_TAC, METIS_TAC [REAL_EQ_LDIV_EQ]] THEN 14374 ONCE_REWRITE_TAC [GSYM REAL_EQ_NEG] THEN REWRITE_TAC [real_div] THEN 14375 REWRITE_TAC [REAL_ARITH ``-(a * b) = a * -b:real``] THEN 14376 ASM_SIMP_TAC std_ss [REAL_NEG_INV, GSYM real_div] THEN POP_ASSUM MP_TAC THEN 14377 GEN_REWR_TAC LAND_CONV [GSYM REAL_LT_NEG] THEN REWRITE_TAC [REAL_NEG_0] THEN 14378 DISCH_TAC THEN REWRITE_TAC [REAL_ARITH ``(-x = y * -m) <=> (x = -y * -m:real)``] THEN 14379 METIS_TAC [REAL_EQ_LDIV_EQ], DISCH_TAC THEN ASM_SIMP_TAC std_ss []] THEN 14380 SIMP_TAC std_ss [UNWIND_THM2] THEN FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP 14381 (REAL_ARITH ``~(z = &0) ==> &0 < z \/ &0 < -z:real``)) 14382 >- ( ASM_SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ] \\ 14383 DISCH_TAC \\ 14384 `(m 1) * a <= (m 1) * b` by PROVE_TAC [REAL_LE_LMUL] \\ 14385 ASM_SIMP_TAC std_ss [min_def, max_def] \\ 14386 METIS_TAC [REAL_MUL_SYM] ) 14387 >> ONCE_REWRITE_TAC[GSYM REAL_LE_NEG2] 14388 >> ONCE_REWRITE_TAC[REAL_MUL_SYM] 14389 >> KNOW_TAC ``!a b. -(max a b) = min (-a) (-b:real)`` 14390 >- PROVE_TAC [REAL_MAX_MIN, REAL_NEG_NEG] >> DISCH_TAC 14391 >> KNOW_TAC ``!a b. -(min a b) = max (-a) (-b:real)`` 14392 >- PROVE_TAC [REAL_MIN_MAX, REAL_NEG_NEG] >> DISCH_TAC 14393 >> ASM_SIMP_TAC std_ss [real_div, GSYM REAL_MUL_RNEG, REAL_NEG_INV] 14394 >> REWRITE_TAC [GSYM real_div] 14395 >> ASM_SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ] 14396 >> ONCE_REWRITE_TAC [REAL_LE_NEG2] 14397 >> DISCH_TAC 14398 >> `a * -(m 1) <= b * -(m 1)` by PROVE_TAC [REAL_LE_RMUL] 14399 >> ASM_SIMP_TAC std_ss [min_def, max_def] 14400 >> REAL_ARITH_TAC); 14401 14402val INTERVAL_IMAGE_STRETCH_INTERVAL = store_thm ("INTERVAL_IMAGE_STRETCH_INTERVAL", 14403 ``!a b:real m. ?u v:real. 14404 IMAGE (\x. @f. f = m (1:num) * x) (interval[a,b]) = interval[u,v]``, 14405 SIMP_TAC std_ss [IMAGE_STRETCH_INTERVAL] THEN METIS_TAC[EMPTY_AS_INTERVAL]); 14406 14407val CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL = store_thm ("CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL", 14408 ``!a b:real. 14409 ~(interval[a,b] = {}) 14410 ==> (interval[a,b] = IMAGE (\x:real. a + x) 14411 (IMAGE (\x. (@f. f = (b - a) * x)) 14412 (interval[0:real,1])))``, 14413 REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN 14414 ONCE_REWRITE_TAC [METIS [] ``(\x. @f. f = (b - a) * x) = 14415 (\x. @f. f = (\x. (b - a)) (1:num) * x:real)``] THEN 14416 REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN 14417 SIMP_TAC std_ss [REAL_MUL_RZERO, REAL_MUL_RID, UNIT_INTERVAL_NONEMPTY] THEN 14418 REWRITE_TAC[EXTENSION, IN_INTERVAL] THEN 14419 GEN_TAC THEN SIMP_TAC std_ss [IN_IMAGE, IN_INTERVAL, min_def, max_def] THEN 14420 ASM_SIMP_TAC std_ss [REAL_SUB_LE] THEN EQ_TAC THENL 14421 [DISCH_TAC THEN EXISTS_TAC ``x - a:real`` THEN ASM_REAL_ARITH_TAC, ASM_REAL_ARITH_TAC]); 14422 14423val SUMS_INTERVALS = store_thm ("SUMS_INTERVALS", 14424 ``(!a b c d:real. 14425 ~(interval[a,b] = {}) /\ ~(interval[c,d] = {}) 14426 ==> ({x + y | x IN interval[a,b] /\ y IN interval[c,d]} = 14427 interval[a+c,b+d])) /\ 14428 (!a b c d:real. 14429 ~(interval(a,b) = {}) /\ ~(interval(c,d) = {}) 14430 ==> ({x + y | x IN interval(a,b) /\ y IN interval(c,d)} = 14431 interval(a+c,b+d)))``, 14432 CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[INTERVAL_NE_EMPTY] THEN 14433 STRIP_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_INTERVAL, GSPECIFICATION, EXISTS_PROD] THEN 14434 ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c <=> c /\ a /\ b`] THEN 14435 REWRITE_TAC[REAL_ARITH ``(x:real = y + z) <=> (z = x - y)``] THEN 14436 SIMP_TAC std_ss [UNWIND_THM2] THEN (* 2 subgoals *) 14437 ( X_GEN_TAC ``x:real`` THEN EQ_TAC 14438 >- ( DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) >> ASM_REAL_ARITH_TAC ) 14439 >> STRIP_TAC 14440 >> ONCE_REWRITE_TAC [CONJ_SYM] 14441 >> KNOW_TAC 14442 ``(!y. (a <= y /\ y <= b) /\ c <= x - y /\ x - y <= d <=> 14443 ((if a <= x - d then x - d else a) <= y /\ 14444 y <= if b <= x - c then b else x - c:real)) /\ 14445 (!y. (a < y /\ y < b) /\ c < x - y /\ x - y < d <=> 14446 ((if a <= x - d then x - d else a) < y /\ 14447 y < if b <= x - c then b else x - c:real))`` 14448 >- ( CONJ_TAC >> GEN_TAC >> rpt COND_CASES_TAC >> ASM_REAL_ARITH_TAC ) 14449 >> STRIP_TAC >> ASM_REWRITE_TAC [] 14450 >> REWRITE_TAC [GSYM min_def, GSYM max_def, GSYM REAL_LE_BETWEEN, GSYM REAL_LT_BETWEEN] 14451 >> ASM_REWRITE_TAC [min_def, max_def] 14452 >> rpt COND_CASES_TAC (* 4 subgoals *) 14453 >> METIS_TAC [REAL_LE_SUB_LADD, REAL_LE_SUB_RADD, REAL_LE_LADD, REAL_LE_NEG, real_sub, 14454 REAL_LT_SUB_LADD, REAL_LT_SUB_RADD, REAL_LT_LADD, REAL_LT_NEG] )); 14455 14456val OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL = store_thm ("OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL", 14457 ``(!s:real->bool. 14458 open s <=> 14459 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval[a,b] SUBSET s) /\ 14460 (!s:real->bool. 14461 open s <=> 14462 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval(a,b) SUBSET s)``, 14463 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN GEN_TAC THEN 14464 MATCH_MP_TAC(TAUT 14465 `(q ==> r) /\ (r ==> p) /\ (p ==> q) ==> (p <=> q) /\ (p <=> r)`) THEN 14466 REPEAT CONJ_TAC THENL 14467 [MESON_TAC[SUBSET_TRANS, INTERVAL_OPEN_SUBSET_CLOSED], 14468 DISCH_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN 14469 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 14470 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN 14471 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 14472 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN STRIP_TAC THEN 14473 MP_TAC(ISPEC ``interval(a:real,b)`` OPEN_CONTAINS_BALL) THEN 14474 REWRITE_TAC[OPEN_INTERVAL] THEN 14475 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 14476 REPEAT STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN 14477 ASM_MESON_TAC[SUBSET_TRANS, INTERVAL_OPEN_SUBSET_CLOSED], 14478 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 14479 FIRST_ASSUM(MP_TAC o SPEC ``x:real`` o 14480 REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN 14481 ASM_REWRITE_TAC[] THEN 14482 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 14483 EXISTS_TAC ``x - e:real`` THEN 14484 EXISTS_TAC ``x + e:real`` THEN 14485 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE 14486 ``b SUBSET s ==> x IN i /\ j SUBSET b ==> x IN i /\ j SUBSET s``)) THEN 14487 SIMP_TAC std_ss [IN_INTERVAL, IN_CBALL, SUBSET_DEF, REAL_MUL_RID] THEN 14488 REWRITE_TAC[REAL_ARITH ``x - e < x /\ x < x + e <=> &0 < e:real``, 14489 REAL_ARITH ``x - e <= y /\ y <= x + e <=> abs(x - y) <= e:real``] THEN 14490 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT, LE_1] THEN 14491 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN ASM_REWRITE_TAC[dist]]); 14492 14493val OPEN_CONTAINS_INTERVAL = store_thm ("OPEN_CONTAINS_INTERVAL", 14494 ``(!s:real->bool. 14495 open s <=> 14496 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval[a,b] SUBSET s)``, 14497 REWRITE_TAC [OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL]); 14498 14499val OPEN_CONTAINS_OPEN_INTERVAL = store_thm ("OPEN_CONTAINS_OPEN_INTERVAL", 14500 ``(!s:real->bool. 14501 open s <=> 14502 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval(a,b) SUBSET s)``, 14503 METIS_TAC [OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL]); 14504 14505val DIAMETER_INTERVAL = store_thm ("DIAMETER_INTERVAL", 14506 ``(!a b:real. 14507 diameter(interval[a,b]) = 14508 if interval[a,b] = {} then &0 else abs(b - a)) /\ 14509 (!a b:real. 14510 diameter(interval(a,b)) = 14511 if interval(a,b) = {} then &0 else abs(b - a))``, 14512 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN 14513 ASM_CASES_TAC ``interval[a:real,b] = {}`` THENL 14514 [METIS_TAC[INTERVAL_OPEN_SUBSET_CLOSED, SUBSET_EMPTY, DIAMETER_EMPTY], 14515 ASM_REWRITE_TAC[]] THEN 14516 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL 14517 [REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN 14518 ASM_SIMP_TAC std_ss [DIAMETER_BOUNDED_BOUND, 14519 ENDS_IN_INTERVAL, BOUNDED_INTERVAL] THEN 14520 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC 14521 ``diameter(cball(inv(&2) * (a + b):real,abs(b - a) / &2))`` THEN 14522 CONJ_TAC THENL 14523 [MATCH_MP_TAC DIAMETER_SUBSET THEN REWRITE_TAC[BOUNDED_CBALL] THEN 14524 REWRITE_TAC[SUBSET_DEF, IN_INTERVAL, IN_CBALL] THEN 14525 GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[dist] THEN 14526 KNOW_TAC ``x = x * (2 / 2:real)`` THENL 14527 [METIS_TAC [REAL_DIV_REFL, REAL_MUL_RID, REAL_ARITH ``2 <> 0:real``], 14528 DISCH_TAC THEN ONCE_ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 14529 REWRITE_TAC [real_div]] THEN 14530 REWRITE_TAC [REAL_ARITH ``a * (b * inv b) = inv b * (a * b:real)``] THEN 14531 REWRITE_TAC [GSYM REAL_SUB_LDISTRIB, ABS_MUL] THEN 14532 SIMP_TAC std_ss [ABS_INV, REAL_ARITH ``2 <> 0:real``, ABS_N] THEN 14533 GEN_REWR_TAC RAND_CONV [REAL_MUL_SYM] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN 14534 SIMP_TAC std_ss [ABS_POS, REAL_LE_REFL, REAL_INV_1OVER, REAL_HALF_BETWEEN] THEN 14535 ASM_REAL_ARITH_TAC, 14536 REWRITE_TAC[DIAMETER_CBALL] THEN COND_CASES_TAC THEN 14537 REWRITE_TAC [ABS_POS, real_div] THEN 14538 ONCE_REWRITE_TAC [REAL_ARITH ``a * (b * c) = (a * c) * b:real``] THEN 14539 SIMP_TAC std_ss [REAL_MUL_RINV, REAL_ARITH ``2 <> 0:real``] THEN 14540 REAL_ARITH_TAC], 14541 DISCH_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[DIAMETER_EMPTY] THEN 14542 SUBGOAL_THEN ``interval[a:real,b] = closure(interval(a,b))`` 14543 SUBST_ALL_TAC THEN ASM_REWRITE_TAC[CLOSURE_INTERVAL] THEN 14544 ASM_MESON_TAC[DIAMETER_CLOSURE, BOUNDED_INTERVAL]]); 14545 14546val IMAGE_TWIZZLE_INTERVAL = store_thm ("IMAGE_TWIZZLE_INTERVAL", 14547 ``!p a b. IMAGE ((\x. x):real->real) (interval[a,b]) = 14548 interval[a,b]``, 14549 SET_TAC [interval]); 14550 14551val EQ_INTERVAL = store_thm ("EQ_INTERVAL", 14552 ``(!a b c d:real. 14553 (interval[a,b] = interval[c,d]) <=> 14554 ((interval[a,b] = {}) /\ (interval[c,d] = {})) \/ ((a = c) /\ (b = d))) /\ 14555 (!a b c d:real. 14556 (interval[a,b] = interval(c,d)) <=> 14557 (interval[a,b] = {}) /\ (interval(c,d) = {})) /\ 14558 (!a b c d:real. 14559 (interval(a,b) = interval[c,d]) <=> 14560 (interval(a,b) = {}) /\ (interval[c,d] = {})) /\ 14561 (!a b c d:real. 14562 (interval(a,b) = interval(c,d)) <=> 14563 ((interval(a,b) = {}) /\ (interval(c,d) = {})) \/ ((a = c) /\ (b = d)))``, 14564 REPEAT CONJ_TAC THEN REPEAT GEN_TAC THEN 14565 (EQ_TAC THENL [ALL_TAC, STRIP_TAC THEN ASM_REWRITE_TAC[]]) THEN 14566 MATCH_MP_TAC(MESON[] 14567 ``((p = {}) /\ (q = {}) ==> r) /\ (~(p = {}) /\ ~(q = {}) ==> (p = q) ==> r) 14568 ==> (p = q) ==> r``) THEN 14569 SIMP_TAC std_ss [] THENL 14570 [REWRITE_TAC[INTERVAL_NE_EMPTY] THEN 14571 REWRITE_TAC[GSYM SUBSET_ANTISYM] THEN 14572 METIS_TAC [SUBSET_INTERVAL, GSYM REAL_LE_ANTISYM], 14573 STRIP_TAC THEN MATCH_MP_TAC(MESON[CLOPEN] 14574 ``closed s /\ open t /\ ~(s = {}) /\ ~(s = UNIV) ==> ~(s = t)``) THEN 14575 ASM_REWRITE_TAC[CLOSED_INTERVAL, OPEN_INTERVAL, NOT_INTERVAL_UNIV], 14576 STRIP_TAC THEN MATCH_MP_TAC(MESON[CLOPEN] 14577 ``closed s /\ open t /\ ~(s = {}) /\ ~(s = UNIV) ==> ~(t = s)``) THEN 14578 ASM_REWRITE_TAC[CLOSED_INTERVAL, OPEN_INTERVAL, NOT_INTERVAL_UNIV], 14579 REWRITE_TAC[INTERVAL_NE_EMPTY] THEN 14580 REWRITE_TAC[GSYM SUBSET_ANTISYM] THEN 14581 METIS_TAC [SUBSET_INTERVAL, GSYM REAL_LE_ANTISYM]]); 14582 14583val CLOSED_INTERVAL_EQ = store_thm ("CLOSED_INTERVAL_EQ", 14584 ``(!a b:real. closed(interval[a,b])) /\ 14585 (!a b:real. closed(interval(a,b)) <=> (interval(a,b) = {}))``, 14586 REWRITE_TAC[CLOSED_INTERVAL] THEN 14587 REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN 14588 ASM_REWRITE_TAC[CLOSED_EMPTY] THEN 14589 MP_TAC(ISPEC ``interval(a:real,b)`` CLOPEN) THEN 14590 ASM_REWRITE_TAC[OPEN_INTERVAL] THEN 14591 METIS_TAC[BOUNDED_INTERVAL, NOT_BOUNDED_UNIV]); 14592 14593val OPEN_INTERVAL_EQ = store_thm ("OPEN_INTERVAL_EQ", 14594 ``(!a b:real. open(interval[a,b]) <=> (interval[a,b] = {})) /\ 14595 (!a b:real. open(interval(a,b)))``, 14596 REWRITE_TAC[OPEN_INTERVAL] THEN 14597 REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN 14598 ASM_REWRITE_TAC[CLOSED_EMPTY] THEN 14599 MP_TAC(ISPEC ``interval[a:real,b]`` CLOPEN) THEN 14600 ASM_REWRITE_TAC[CLOSED_INTERVAL] THEN 14601 METIS_TAC[BOUNDED_INTERVAL, NOT_BOUNDED_UNIV]); 14602 14603val COMPACT_INTERVAL_EQ = store_thm ("COMPACT_INTERVAL_EQ", 14604 ``(!a b:real. compact(interval[a,b])) /\ 14605 (!a b:real. compact(interval(a,b)) <=> (interval(a,b) = {}))``, 14606 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTERVAL] THEN 14607 REWRITE_TAC[CLOSED_INTERVAL_EQ]); 14608 14609val EQ_BALLS = store_thm ("EQ_BALLS", 14610 ``(!a a':real r r'. 14611 (ball(a,r) = ball(a',r')) <=> (a = a') /\ (r = r') \/ r <= &0 /\ r' <= &0) /\ 14612 (!a a':real r r'. 14613 (ball(a,r) = cball(a',r')) <=> r <= &0 /\ r' < &0) /\ 14614 (!a a':real r r'. 14615 (cball(a,r) = ball(a',r')) <=> r < &0 /\ r' <= &0) /\ 14616 (!a a':real r r'. 14617 (cball(a,r) = cball(a',r')) <=> (a = a') /\ (r = r') \/ r < &0 /\ r' < &0)``, 14618 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT STRIP_TAC THEN 14619 (EQ_TAC THENL 14620 [ALL_TAC, REWRITE_TAC[EXTENSION, IN_BALL, IN_CBALL, dist] THEN REAL_ARITH_TAC]) 14621 THENL 14622 [SIMP_TAC std_ss [SET_EQ_SUBSET, SUBSET_BALLS, dist] THEN REAL_ARITH_TAC, 14623 ONCE_REWRITE_TAC[EQ_SYM_EQ], 14624 ALL_TAC, 14625 REWRITE_TAC[SET_EQ_SUBSET, SUBSET_BALLS, dist] THEN REAL_ARITH_TAC] THEN 14626 DISCH_THEN(MP_TAC o MATCH_MP (METIS [CLOPEN, BOUNDED_BALL, NOT_BOUNDED_UNIV] 14627 ``(s = t) ==> closed s /\ open t /\ bounded t ==> (s = {}) /\ (t = {})``)) THEN 14628 REWRITE_TAC[OPEN_BALL, CLOSED_CBALL, BOUNDED_BALL, 14629 BALL_EQ_EMPTY, CBALL_EQ_EMPTY] THEN 14630 REAL_ARITH_TAC); 14631 14632(* ------------------------------------------------------------------------- *) 14633(* Some special cases for intervals in R^1. *) 14634(* ------------------------------------------------------------------------- *) 14635 14636val INTERVAL_CASES = store_thm ("INTERVAL_CASES", 14637 ``!x:real. x IN interval[a,b] ==> x IN interval(a,b) \/ (x = a) \/ (x = b)``, 14638 REWRITE_TAC[IN_INTERVAL] THEN REAL_ARITH_TAC); 14639 14640val OPEN_CLOSED_INTERVAL = store_thm ("OPEN_CLOSED_INTERVAL", 14641 ``!a b:real. interval(a,b) = interval[a,b] DIFF {a;b}``, 14642 REWRITE_TAC[EXTENSION, IN_INTERVAL, IN_DIFF, IN_INSERT, NOT_IN_EMPTY] THEN 14643 SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 14644 14645val CLOSED_OPEN_INTERVAL = store_thm ("CLOSED_OPEN_INTERVAL", 14646 ``!a b:real. a <= b ==> (interval[a,b] = interval(a,b) UNION {a;b})``, 14647 REWRITE_TAC[EXTENSION, IN_INTERVAL, IN_UNION, IN_INSERT, NOT_IN_EMPTY] THEN 14648 SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 14649 14650val BALL = store_thm ("BALL", 14651 ``!x:real r. (cball(x,r) = interval[x - r,x + r]) /\ 14652 (ball(x,r) = interval(x - r,x + r))``, 14653 REWRITE_TAC[EXTENSION, IN_BALL, IN_CBALL, IN_INTERVAL] THEN 14654 REWRITE_TAC[dist] THEN REAL_ARITH_TAC); 14655 14656val SPHERE = store_thm ("SPHERE", 14657 ``!a:real r. sphere(a,r) = if r < (&0:real) then {} else {a - r;a + r}``, 14658 REPEAT GEN_TAC THEN REWRITE_TAC[sphere] THEN COND_CASES_TAC THEN 14659 SIMP_TAC std_ss [EXTENSION, IN_INSERT, NOT_IN_EMPTY, GSPECIFICATION, dist] THEN 14660 ASM_REAL_ARITH_TAC); 14661 14662val FINITE_SPHERE = store_thm ("FINITE_SPHERE", 14663 ``!a:real r. FINITE(sphere(a,r))``, 14664 REPEAT GEN_TAC THEN REWRITE_TAC[SPHERE] THEN 14665 METIS_TAC[FINITE_INSERT, FINITE_EMPTY]); 14666 14667val FINITE_INTERVAL = store_thm ("FINITE_INTERVAL", 14668 ``(!a b. FINITE(interval[a,b]) <=> b <= a) /\ 14669 (!a b. FINITE(interval(a,b)) <=> b <= a)``, 14670 REWRITE_TAC[OPEN_CLOSED_INTERVAL] THEN 14671 REWRITE_TAC[SET_RULE ``s DIFF {a;b} = s DELETE a DELETE b``] THEN 14672 REWRITE_TAC[FINITE_DELETE] THEN REPEAT GEN_TAC THEN 14673 SIMP_TAC std_ss [interval, FINITE_IMAGE_INJ_EQ, FINITE_REAL_INTERVAL]); 14674 14675val BALL_INTERVAL = store_thm ("BALL_INTERVAL", 14676 ``!x:real e. ball(x,e) = interval(x - e,x + e)``, 14677 REWRITE_TAC[EXTENSION, IN_BALL, IN_INTERVAL, dist] THEN 14678 REAL_ARITH_TAC); 14679 14680val CBALL_INTERVAL = store_thm ("CBALL_INTERVAL", 14681 ``!x:real e. cball(x,e) = interval[x - e,x + e]``, 14682 REWRITE_TAC[EXTENSION, IN_CBALL, IN_INTERVAL, dist] THEN 14683 REAL_ARITH_TAC); 14684 14685val BALL_INTERVAL_0 = store_thm ("BALL_INTERVAL_0", 14686 ``!e. ball(0:real,e) = interval(-e,e)``, 14687 GEN_TAC THEN REWRITE_TAC[BALL_INTERVAL] THEN AP_TERM_TAC THEN 14688 BINOP_TAC THEN REAL_ARITH_TAC); 14689 14690val CBALL_INTERVAL_0 = store_thm ("CBALL_INTERVAL_0", 14691 ``!e. cball(0:real,e) = interval[-e,e]``, 14692 GEN_TAC THEN REWRITE_TAC[CBALL_INTERVAL] THEN AP_TERM_TAC THEN 14693 AP_THM_TAC THEN AP_TERM_TAC THEN BINOP_TAC THEN REAL_ARITH_TAC); 14694 14695val CLOSED_DIFF_OPEN_INTERVAL = store_thm ("CLOSED_DIFF_OPEN_INTERVAL", 14696 ``!a b:real. 14697 interval[a,b] DIFF interval(a,b) = 14698 if interval[a,b] = {} then {} else {a;b}``, 14699 REWRITE_TAC[EXTENSION, IN_DIFF, GSYM INTERVAL_EQ_EMPTY, IN_INTERVAL] THEN 14700 REPEAT GEN_TAC THEN COND_CASES_TAC THEN 14701 ASM_REWRITE_TAC[NOT_IN_EMPTY, IN_INSERT, NOT_IN_EMPTY] THEN 14702 FULL_SIMP_TAC std_ss [NOT_IN_EMPTY] THEN 14703 ASM_REAL_ARITH_TAC); 14704 14705val INTERVAL = store_thm ("INTERVAL", 14706 ``(!a b:real. interval[a,b] = 14707 if a <= b then cball(midpoint(a,b),dist(a,b) / &2) 14708 else {}) /\ 14709 (!a b:real. interval(a,b) = 14710 if a < b then ball(midpoint(a,b),dist(a,b) / &2) 14711 else {})``, 14712 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN 14713 RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE, REAL_NOT_LT]) THEN 14714 ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN 14715 REWRITE_TAC[BALL, dist] THEN 14716 ASM_SIMP_TAC std_ss [REAL_SUB_LE, REAL_LT_IMP_LE, 14717 REAL_ARITH ``a <= b ==> (abs(a - b) = b - a:real)``] THEN 14718 REWRITE_TAC[METIS [real_div, REAL_MUL_SYM] ``x / &2 = inv(&2:real) * x``] THEN 14719 REWRITE_TAC[midpoint] THEN 14720 TRY AP_TERM_TAC THEN ASM_SIMP_TAC std_ss [PAIR_EQ, CONS_11, GSYM INTERVAL_EQ_EMPTY] THEN 14721 REWRITE_TAC [GSYM REAL_SUB_LDISTRIB, GSYM REAL_ADD_LDISTRIB] THEN 14722 REWRITE_TAC [REAL_ARITH ``a + b - (b - a) = 2 * a:real``] THEN 14723 REWRITE_TAC [REAL_ARITH ``a + b + (b - a) = 2 * b:real``] THEN 14724 SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_ARITH ``2 <> 0:real``, REAL_MUL_LINV] THEN REAL_ARITH_TAC); 14725 14726val SEGMENT = store_thm ("SEGMENT", 14727 ``(!a b. segment[a,b] = 14728 if a <= b then interval[a,b] else interval[b,a]) /\ 14729 (!a b. segment(a,b) = 14730 if a <= b then interval(a,b) else interval(b,a))``, 14731 CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN 14732 COND_CASES_TAC THEN 14733 REWRITE_TAC[IN_DIFF, IN_INSERT, NOT_IN_EMPTY, 14734 EXTENSION, GSYM BETWEEN_IN_SEGMENT, between, IN_INTERVAL] THEN 14735 REWRITE_TAC[dist] THEN ASM_REAL_ARITH_TAC); 14736 14737val OPEN_SEGMENT = store_thm ("OPEN_SEGMENT", 14738 ``!a b:real. open(segment(a,b))``, 14739 REPEAT GEN_TAC THEN REWRITE_TAC[SEGMENT] THEN 14740 COND_CASES_TAC THEN REWRITE_TAC[OPEN_INTERVAL]); 14741 14742val SEGMENT_SCALAR_MULTIPLE = store_thm ("SEGMENT_SCALAR_MULTIPLE", 14743 ``(!a b v:real. segment[a * v,b * v] = 14744 {x * v:real | a <= x /\ x <= b \/ b <= x /\ x <= a}) /\ 14745 (!a b v:real. ~(v = 0) 14746 ==> (segment(a * v,b * v) = 14747 {x * v:real | a < x /\ x < b \/ b < x /\ x < a}))``, 14748 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN REPEAT STRIP_TAC THENL 14749 [REPEAT GEN_TAC THEN 14750 MP_TAC(SPECL [``a * 1:real``, ``b * 1:real``] 14751 (CONJUNCT1 SEGMENT)) THEN 14752 REWRITE_TAC[segment, REAL_MUL_ASSOC, GSYM REAL_ADD_RDISTRIB] THEN 14753 ONCE_REWRITE_TAC [METIS [] ``((1 - u) * a + u * b:real) = 14754 (\u. ((1 - u) * a + u * b)) u``] THEN 14755 ONCE_REWRITE_TAC [METIS [] ``(0 <= u /\ u <= 1:real) = 14756 (\u. 0 <= u /\ u <= 1) u``] THEN 14757 ONCE_REWRITE_TAC [METIS [] 14758 ``{x:real * v | a <= x /\ x <= b \/ b <= x /\ x <= a} = 14759 {(\x. x) x * v | (\x. a <= x /\ x <= b \/ b <= x /\ x <= a) x}``] THEN 14760 REWRITE_TAC [SET_RULE ``{f x * b:real | p (x:real)} = 14761 IMAGE (\a. a * b) {f x | p x}``] THEN 14762 BETA_TAC THEN DISCH_TAC THEN AP_TERM_TAC THEN 14763 FIRST_X_ASSUM(MP_TAC o SIMP_RULE std_ss [REAL_MUL_RID, IMAGE_ID]) THEN 14764 DISCH_THEN SUBST1_TAC THEN COND_CASES_TAC THEN 14765 SIMP_TAC std_ss [EXTENSION, IN_INTERVAL, GSPECIFICATION] THEN ASM_REAL_ARITH_TAC, 14766 ASM_REWRITE_TAC[open_segment] THEN 14767 ONCE_REWRITE_TAC [METIS [] ``{x * v | a <= x /\ x <= b \/ b <= x /\ x <= a:real} = 14768 {(\x. x) x * v | (\x. a <= x /\ x <= b \/ b <= x /\ x <= a) x}``] THEN 14769 ASM_SIMP_TAC std_ss [REAL_EQ_RMUL, SET_RULE 14770 ``(!x y:real. (x * v = y * v) <=> (x = y)) 14771 ==> ({x * v | P x} DIFF {a * v;b * v} = 14772 {x * v | P x /\ ~(x = a) /\ ~(x = b)})``] THEN 14773 ONCE_REWRITE_TAC [SET_RULE 14774 ``{x * v | (a <= x /\ x <= b \/ b <= x /\ x <= a) /\ x <> a /\ x <> b:real} = 14775 {(\x. x * v) x | x IN (\x. (a <= x /\ x <= b \/ b <= x /\ x <= a) /\ x <> a /\ x <> b)}``] THEN 14776 ONCE_REWRITE_TAC [SET_RULE 14777 ``{x * v | a < x /\ x < b \/ b < x /\ x < a:real} = 14778 {(\x. x * v) x | x IN (\x. (a < x /\ x < b \/ b < x /\ x < a))}``] THEN 14779 ONCE_REWRITE_TAC[GSYM IMAGE_DEF] THEN AP_TERM_TAC THEN 14780 ABS_TAC THEN REAL_ARITH_TAC]); 14781 14782(* ------------------------------------------------------------------------- *) 14783(* Intervals in general, including infinite and mixtures of open and closed. *) 14784(* ------------------------------------------------------------------------- *) 14785 14786val is_interval = new_definition ("is_interval", 14787 ``is_interval(s:real->bool) <=> 14788 !a b x. a IN s /\ b IN s 14789 ==> (a <= x /\ x <= b) \/ 14790 (b <= x /\ x <= a) 14791 ==> x IN s``); 14792 14793val IS_INTERVAL_INTERVAL = store_thm ("IS_INTERVAL_INTERVAL", 14794 ``!a:real b. is_interval(interval (a,b)) /\ is_interval(interval [a,b])``, 14795 REWRITE_TAC[is_interval, IN_INTERVAL] THEN 14796 METIS_TAC[REAL_LT_TRANS, REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS]); 14797 14798val IS_INTERVAL_EMPTY = store_thm ("IS_INTERVAL_EMPTY", 14799 ``is_interval {}``, 14800 REWRITE_TAC[is_interval, NOT_IN_EMPTY]); 14801 14802val IS_INTERVAL_UNIV = store_thm ("IS_INTERVAL_UNIV", 14803 ``is_interval(UNIV:real->bool)``, 14804 REWRITE_TAC[is_interval, IN_UNIV]); 14805 14806val IS_INTERVAL_POINTWISE = store_thm ("IS_INTERVAL_POINTWISE", 14807 ``!s:real->bool x. 14808 is_interval s ==> (?a. a IN s /\ (a = x)) 14809 ==> x IN s``, 14810 METIS_TAC [is_interval]); 14811 14812Theorem IS_INTERVAL_COMPACT : 14813 !s:real->bool. is_interval s /\ compact s <=> ?a b. s = interval[a,b] 14814Proof 14815 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN 14816 ASM_SIMP_TAC std_ss [IS_INTERVAL_INTERVAL, COMPACT_INTERVAL] THEN 14817 ASM_CASES_TAC ``s:real->bool = {}`` 14818 >- ASM_MESON_TAC[EMPTY_AS_INTERVAL] THEN (* one goal left *) 14819 EXISTS_TAC ``(@f. f = inf { (x:real) | x IN s}):real`` THEN 14820 EXISTS_TAC ``(@f. f = sup { (x:real) | x IN s}):real`` THEN 14821 SIMP_TAC std_ss [EXTENSION, IN_INTERVAL] THEN X_GEN_TAC ``x:real`` THEN 14822 EQ_TAC THENL (* 2 subgoals *) 14823 [ (* goal 1 (of 2) *) 14824 DISCH_TAC THEN 14825 MP_TAC(ISPEC ``{ (x:real) | x IN s}`` INF) THEN 14826 MP_TAC(ISPEC ``{ (x:real) | x IN s}`` SUP) THEN 14827 SIMP_TAC std_ss [METIS [] ``x = (\x. x) x``, GSYM IMAGE_DEF] THEN 14828 ASM_SIMP_TAC std_ss [IMAGE_EQ_EMPTY, FORALL_IN_IMAGE] THEN 14829 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN 14830 REWRITE_TAC[bounded_def] THEN 14831 ASM_MESON_TAC[REAL_LE_TRANS, MEMBER_NOT_EMPTY, 14832 REAL_ARITH ``abs(x) <= B ==> -B <= x /\ x <= B:real``], 14833 (* goal 2 (of 2) *) 14834 DISCH_TAC THEN 14835 SUFF_TAC ``?a:real. a IN s /\ (a = x)`` 14836 >- (MATCH_MP_TAC IS_INTERVAL_POINTWISE >> ASM_REWRITE_TAC []) THEN 14837 SUBGOAL_THEN 14838 ``?a b:real. a IN s /\ b IN s /\ a <= (x:real) /\ x <= b`` 14839 STRIP_ASSUME_TAC THENL (* 2 subgoals *) 14840 [ (* goal 2.1 (of 2) *) 14841 MP_TAC (ISPECL [``\x:real. x``, ``s:real->bool``] 14842 CONTINUOUS_ATTAINS_INF) THEN 14843 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ID, o_DEF] THEN 14844 DISCH_THEN (X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 14845 EXISTS_TAC ``a:real`` THEN 14846 MP_TAC (ISPECL [``\x:real. x``, ``s:real->bool``] 14847 CONTINUOUS_ATTAINS_SUP) THEN 14848 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ID, o_DEF] THEN 14849 DISCH_THEN (X_CHOOSE_THEN ``b:real`` STRIP_ASSUME_TAC) THEN 14850 EXISTS_TAC ``b:real`` THEN ASM_REWRITE_TAC [] THEN 14851 CONJ_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THENL (* 2 subgoals *) 14852 [ (* goal 2.1.1 (of 2) *) 14853 EXISTS_TAC ``inf {(x:real) | x IN s}`` THEN ASM_SIMP_TAC std_ss [] THEN 14854 MATCH_MP_TAC REAL_LE_INF THEN 14855 ONCE_REWRITE_TAC [METIS [SPECIFICATION] ``{x | x IN s} x <=> x IN {x | x IN s}``] THEN 14856 ASM_SET_TAC [], 14857 (* goal 2.1.2 (of 2) *) 14858 EXISTS_TAC ``sup {(x:real) | x IN s}`` THEN ASM_SIMP_TAC std_ss [] THEN 14859 MATCH_MP_TAC REAL_SUP_LE' THEN 14860 ONCE_REWRITE_TAC [METIS [SPECIFICATION] ``{x | x IN s} x <=> x IN {x | x IN s}``] THEN 14861 ASM_SET_TAC [] ], 14862 (* goal 2.2 (of 2) *) 14863 EXISTS_TAC ``x:real`` THEN ASM_SIMP_TAC std_ss [] THEN 14864 UNDISCH_TAC ``is_interval s`` THEN DISCH_TAC THEN 14865 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[is_interval, AND_IMP_INTRO]) THEN 14866 MAP_EVERY EXISTS_TAC [``a:real``, ``b:real``] THEN 14867 ASM_SIMP_TAC std_ss [] ] ] 14868QED 14869 14870val IS_INTERVAL = store_thm ("IS_INTERVAL", 14871 ``!s:real->bool. 14872 is_interval s <=> 14873 !a b x. a IN s /\ b IN s /\ a <= x /\ x <= b 14874 ==> x IN s``, 14875 REWRITE_TAC[is_interval] THEN MESON_TAC[]); 14876 14877val IS_INTERVAL_CASES = store_thm ("IS_INTERVAL_CASES", 14878 ``!s:real->bool. 14879 is_interval s <=> 14880 (s = {}) \/ 14881 (s = univ(:real)) \/ 14882 (?a. s = {x | a < x}) \/ 14883 (?a. s = {x | a <= x}) \/ 14884 (?b. s = {x | x <= b}) \/ 14885 (?b. s = {x | x < b}) \/ 14886 (?a b. s = {x | a < x /\ x < b}) \/ 14887 (?a b. s = {x | a < x /\ x <= b}) \/ 14888 (?a b. s = {x | a <= x /\ x < b}) \/ 14889 (?a b. s = {x | a <= x /\ x <= b})``, 14890 GEN_TAC THEN REWRITE_TAC[IS_INTERVAL] THEN EQ_TAC THENL 14891 [DISCH_TAC, 14892 STRIP_TAC THEN ASM_SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, NOT_IN_EMPTY] THEN 14893 REAL_ARITH_TAC] THEN 14894 ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[] THEN 14895 MP_TAC(ISPEC ``s:real->bool`` SUP) THEN 14896 MP_TAC(ISPEC ``s:real->bool`` INF) THEN 14897 ASM_SIMP_TAC std_ss [IMAGE_EQ_EMPTY, FORALL_IN_IMAGE] THEN 14898 ASM_CASES_TAC ``?a. !x:real. x IN s ==> a <= x`` THEN 14899 ASM_CASES_TAC ``?b. !x:real. x IN s ==> x <= b`` THEN 14900 ASM_REWRITE_TAC[] THENL 14901 [STRIP_TAC THEN STRIP_TAC THEN 14902 MAP_EVERY ASM_CASES_TAC 14903 [``inf(s) IN s:real->bool``, ``sup(s) IN s:real->bool``] 14904 THENL 14905 [DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN 14906 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC, 14907 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN 14908 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC, 14909 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN 14910 DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC, 14911 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN 14912 DISJ2_TAC THEN DISJ1_TAC] THEN 14913 MAP_EVERY EXISTS_TAC [``inf(s:real->bool)``, ``sup(s:real->bool)``], 14914 STRIP_TAC THEN ASM_CASES_TAC ``inf(s:real->bool) IN s`` THENL 14915 [DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC, 14916 DISJ2_TAC THEN DISJ1_TAC] THEN 14917 EXISTS_TAC ``inf(s:real->bool)``, 14918 STRIP_TAC THEN ASM_CASES_TAC ``sup(s:real->bool) IN s`` THENL 14919 [DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC, 14920 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN 14921 DISJ1_TAC] THEN 14922 EXISTS_TAC ``sup(s:real->bool)``, 14923 DISJ1_TAC] THEN 14924 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_UNIV] THEN 14925 RULE_ASSUM_TAC(REWRITE_RULE[IN_IMAGE]) THEN 14926 REWRITE_TAC[GSYM REAL_NOT_LE] THEN 14927 ASM_MESON_TAC [REAL_LE_TRANS, REAL_LE_TOTAL, REAL_LE_ANTISYM]); 14928 14929val IS_INTERVAL_INTER = store_thm ("IS_INTERVAL_INTER", 14930 ``!s t:real->bool. 14931 is_interval s /\ is_interval t ==> is_interval(s INTER t)``, 14932 REWRITE_TAC[is_interval, IN_INTER] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN 14933 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``, ``x:real``] THEN 14934 REPEAT STRIP_TAC THENL 14935 [UNDISCH_TAC ``!a b x. 14936 a IN s /\ b IN s ==> 14937 a <= x /\ x <= b \/ b <= x /\ x <= a ==> 14938 x IN s:real->bool`` THEN DISCH_TAC THEN 14939 FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO]), 14940 UNDISCH_TAC ``!a b x. 14941 a IN t /\ b IN t ==> 14942 a <= x /\ x <= b \/ b <= x /\ x <= a ==> 14943 x IN t:real->bool`` THEN DISCH_TAC THEN 14944 FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO]), 14945 UNDISCH_TAC ``!a b x. 14946 a IN s /\ b IN s ==> 14947 a <= x /\ x <= b \/ b <= x /\ x <= a ==> 14948 x IN s:real->bool`` THEN DISCH_TAC THEN 14949 FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO]), 14950 UNDISCH_TAC ``!a b x. 14951 a IN t /\ b IN t ==> 14952 a <= x /\ x <= b \/ b <= x /\ x <= a ==> 14953 x IN t:real->bool`` THEN DISCH_TAC THEN 14954 FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO])] THEN 14955 MAP_EVERY EXISTS_TAC [``a:real``, ``b:real``] THEN ASM_REWRITE_TAC[]); 14956 14957val INTERVAL_SUBSET_IS_INTERVAL = store_thm ("INTERVAL_SUBSET_IS_INTERVAL", 14958 ``!s a b:real. 14959 is_interval s 14960 ==> (interval[a,b] SUBSET s <=> (interval[a,b] = {}) \/ a IN s /\ b IN s)``, 14961 REWRITE_TAC[is_interval] THEN REPEAT STRIP_TAC THEN 14962 ASM_CASES_TAC ``interval[a:real,b] = {}`` THEN 14963 ASM_REWRITE_TAC[EMPTY_SUBSET] THEN 14964 EQ_TAC THENL [ASM_MESON_TAC[ENDS_IN_INTERVAL, SUBSET_DEF], ALL_TAC] THEN 14965 REWRITE_TAC[SUBSET_DEF, IN_INTERVAL] THEN ASM_MESON_TAC[]); 14966 14967val INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD = store_thm 14968 ("INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD", 14969 ``!s x:real. 14970 is_interval s /\ x IN s 14971 ==> ?a b d. &0 < d /\ x IN interval[a,b] /\ 14972 interval[a,b] SUBSET s /\ 14973 ball(x,d) INTER s SUBSET interval[a,b]``, 14974 REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [INTERVAL_SUBSET_IS_INTERVAL] THEN 14975 SUBGOAL_THEN ``?a. (?y. y IN s /\ (y = a)) /\ 14976 (a < x \/ (a = (x:real)) /\ 14977 !y:real. y IN s ==> a <= y)`` 14978 MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT], SIMP_TAC std_ss []] THEN 14979 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 14980 SUBGOAL_THEN 14981 ``?b. (?y. y IN s /\ (y = b)) /\ 14982 (x < b \/ (b = (x:real)) /\ 14983 !y:real. y IN s ==> y <= b)`` 14984 MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT], SIMP_TAC std_ss []] THEN 14985 DISCH_THEN (X_CHOOSE_TAC ``b:real``) THEN EXISTS_TAC ``b:real`` THEN 14986 EXISTS_TAC ``min (if a < x then (x:real) - a else &1) 14987 (if x < b then (b:real) - x else &1)`` THEN 14988 REWRITE_TAC[REAL_LT_MIN, SUBSET_DEF, IN_BALL, IN_INTER] THEN 14989 SIMP_TAC std_ss [REAL_LT_INF_FINITE, IMAGE_EQ_EMPTY, IMAGE_FINITE, 14990 FINITE_NUMSEG, NUMSEG_EMPTY, GSYM NOT_LESS_EQUAL] THEN 14991 SIMP_TAC std_ss [FORALL_IN_IMAGE, IN_INTERVAL] THEN REPEAT CONJ_TAC THENL 14992 [METIS_TAC[REAL_SUB_LT, REAL_LT_01], 14993 METIS_TAC[REAL_SUB_LT, REAL_LT_01], 14994 ASM_MESON_TAC[REAL_LE_LT], 14995 ASM_MESON_TAC[REAL_LE_LT], 14996 METIS_TAC [], ALL_TAC] THEN 14997 X_GEN_TAC ``y:real`` THEN 14998 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 14999 MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN 15000 (COND_CASES_TAC THENL [REWRITE_TAC[dist], ASM_MESON_TAC[]]) THEN 15001 REWRITE_TAC [abs] THEN COND_CASES_TAC THEN DISCH_TAC THENL 15002 [FULL_SIMP_TAC std_ss [REAL_ARITH ``x - y < x - a <=> a < y:real``, REAL_LE_LT], 15003 FULL_SIMP_TAC std_ss [REAL_NOT_LE, REAL_ARITH ``x - y < 0 <=> x < y:real``] THEN 15004 METIS_TAC [REAL_LE_TRANS, REAL_LE_LT], 15005 FULL_SIMP_TAC std_ss [REAL_SUB_LE] THEN METIS_TAC [REAL_LE_TRANS, REAL_LE_LT], 15006 FULL_SIMP_TAC std_ss [REAL_NEG_SUB, 15007 REAL_ARITH ``y - x < b - x <=> y < b:real``, REAL_LE_LT]]); 15008 15009Theorem IS_INTERVAL_SUMS : 15010 !s t:real->bool. 15011 is_interval s /\ is_interval t 15012 ==> is_interval {x + y | x IN s /\ y IN t} 15013Proof 15014 REPEAT GEN_TAC THEN REWRITE_TAC[is_interval] THEN 15015 SIMP_TAC std_ss [IMP_CONJ, RIGHT_FORALL_IMP_THM] THEN 15016 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 15017 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN 15018 REWRITE_TAC[AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN 15019 MAP_EVERY X_GEN_TAC 15020 [``a:real``, ``a':real``, ``b:real``, ``b':real``, ``y:real``] THEN 15021 DISCH_THEN(CONJUNCTS_THEN2 15022 (MP_TAC o SPECL [``a:real``, ``b:real``]) MP_TAC) THEN 15023 DISCH_THEN(CONJUNCTS_THEN2 15024 (MP_TAC o SPECL [``a':real``, ``b':real``]) ASSUME_TAC) THEN 15025 ASM_SIMP_TAC std_ss [AND_IMP_INTRO, GSPECIFICATION, EXISTS_PROD] THEN 15026 ONCE_REWRITE_TAC[REAL_ARITH ``(z:real = x + y) <=> (y = z - x)``] THEN 15027 SIMP_TAC std_ss [UNWIND_THM2] THEN 15028 ONCE_REWRITE_TAC [METIS [] 15029 ``!a b s. (!x. a <= x /\ x <= b \/ b <= x /\ x <= a ==> x IN s:real->bool) = 15030 (!x. (\x. a <= x /\ x <= b \/ b <= x /\ x <= a) x ==> x IN s)``] THEN 15031 ONCE_REWRITE_TAC [METIS [] ``(y - p_1) = (\x. y - x) (p_1:real)``] THEN 15032 MATCH_MP_TAC(METIS [] 15033 ``(?x. P x /\ Q(f x)) 15034 ==> (!x. Q x ==> x IN t) /\ (!x. P x ==> x IN s) 15035 ==> ?x. x IN s /\ f x IN t``) THEN 15036 POP_ASSUM MP_TAC THEN DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 15037 DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 15038 DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 15039 DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 15040 SIMP_TAC std_ss [REAL_ARITH 15041 ``c <= y - x /\ y - x <= d <=> y - d <= x /\ x <= y - c:real``] THEN 15042 Know `!a b x. a <= x /\ x <= b \/ b <= x /\ x <= a:real <=> 15043 min a b <= x /\ x <= max a b` 15044 >- (KILL_TAC >> RW_TAC std_ss [max_def, min_def] \\ 15045 REAL_ASM_ARITH_TAC) >> Rewr \\ 15046 ONCE_REWRITE_TAC[TAUT `(p /\ q) /\ (r /\ s) <=> (p /\ r) /\ (q /\ s)`] THEN 15047 REWRITE_TAC[GSYM REAL_LE_MIN, GSYM REAL_MAX_LE] THEN 15048 REWRITE_TAC[GSYM REAL_LE_BETWEEN] THEN 15049 SIMP_TAC std_ss [min_def, max_def] THEN REPEAT COND_CASES_TAC THEN 15050 FULL_SIMP_TAC std_ss [] THEN ASM_REAL_ARITH_TAC 15051QED 15052 15053val IS_INTERVAL_SING = store_thm ("IS_INTERVAL_SING", 15054 ``!a:real. is_interval {a}``, 15055 SIMP_TAC std_ss [is_interval, IN_SING, CONJ_EQ_IMP, REAL_LE_ANTISYM]); 15056 15057val IS_INTERVAL_SCALING = store_thm ("IS_INTERVAL_SCALING", 15058 ``!s:real->bool c. is_interval s ==> is_interval(IMAGE (\x. c * x) s)``, 15059 REPEAT GEN_TAC THEN ASM_CASES_TAC ``c = &0:real`` THENL 15060 [ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN 15061 SUBGOAL_THEN ``(IMAGE ((\x. 0):real->real) (s:real->bool) = {}) \/ 15062 (IMAGE ((\x. 0):real->real) s = {0})`` 15063 STRIP_ASSUME_TAC THENL 15064 [SET_TAC[], 15065 ASM_REWRITE_TAC[IS_INTERVAL_EMPTY], 15066 ASM_REWRITE_TAC[IS_INTERVAL_SING]], 15067 SIMP_TAC std_ss [is_interval, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 15068 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN DISCH_TAC THEN 15069 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN 15070 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_FORALL_THM]) THEN 15071 REWRITE_TAC[AND_IMP_INTRO] THEN 15072 DISCH_TAC THEN MAP_EVERY X_GEN_TAC [``a:real``,``b:real``] THEN 15073 POP_ASSUM (MP_TAC o Q.SPECL [`a:real`,`b:real`]) THEN 15074 DISCH_THEN(fn th => X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 15075 MP_TAC(SPEC ``inv(c) * x:real`` th)) THEN 15076 ASM_SIMP_TAC std_ss [IN_IMAGE] THEN 15077 KNOW_TAC ``a <= inv c * x /\ inv c * x <= b \/ 15078 b <= inv c * x /\ inv c * x <= a:real`` THENL 15079 [FIRST_X_ASSUM(MP_TAC) THEN 15080 DISCH_THEN (CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN 15081 ASM_REWRITE_TAC[] THEN 15082 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN 15083 UNDISCH_TAC ``c <> 0:real`` THEN DISCH_TAC THEN 15084 FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH 15085 ``~(c = &0:real) ==> &0 < c \/ &0 < -c``)) THEN 15086 ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ] THEN 15087 GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_LE_NEG2] THEN 15088 ASM_SIMP_TAC std_ss [GSYM REAL_MUL_RNEG, GSYM REAL_LE_RDIV_EQ, GSYM 15089 REAL_LE_LDIV_EQ] THEN 15090 ASM_SIMP_TAC std_ss [real_div, GSYM REAL_NEG_INV] THEN REAL_ARITH_TAC, 15091 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 15092 DISCH_TAC THEN EXISTS_TAC ``inv c * x:real`` THEN 15093 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_MUL_LID]]]); 15094 15095val IS_INTERVAL_SCALING_EQ = store_thm ("IS_INTERVAL_SCALING_EQ", 15096 ``!s:real->bool c. 15097 is_interval(IMAGE (\x. c * x) s) <=> (c = &0) \/ is_interval s``, 15098 REPEAT GEN_TAC THEN ASM_CASES_TAC ``c = &0:real`` THENL 15099 [ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN 15100 SUBGOAL_THEN ``(IMAGE ((\x. 0):real->real) s = {}) \/ 15101 (IMAGE ((\x. 0):real->real) s = {0})`` 15102 STRIP_ASSUME_TAC THENL 15103 [SET_TAC[], 15104 ASM_REWRITE_TAC[IS_INTERVAL_EMPTY], 15105 ASM_REWRITE_TAC[IS_INTERVAL_SING]], 15106 ASM_REWRITE_TAC[] THEN EQ_TAC THEN REWRITE_TAC[IS_INTERVAL_SCALING] THEN 15107 DISCH_THEN(MP_TAC o SPEC ``inv c:real`` o MATCH_MP IS_INTERVAL_SCALING) THEN 15108 ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, REAL_MUL_ASSOC, o_DEF, REAL_MUL_LINV, 15109 REAL_MUL_LID, IMAGE_ID]]); 15110 15111val lemma0 = prove ((* unused *) 15112 ``!c. &0 < c 15113 ==> !s:real->bool. is_interval(IMAGE (\x. c * x) s) <=> 15114 is_interval s``, 15115 SIMP_TAC std_ss [IS_INTERVAL_SCALING_EQ, REAL_LT_IMP_NE]); 15116 15117val lemma = prove ( 15118 ``~(?a b c:real. a < b /\ b < c /\ 15119 a IN s /\ b IN s /\ c IN s) 15120 ==> FINITE s /\ CARD(s) <= 2``, 15121 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 15122 REWRITE_TAC[TAUT `~(p /\ q) <=> p ==> ~q`] THEN 15123 REWRITE_TAC[ARITH_PROVE ``~(n <= 2) <=> 3 <= n:num``] THEN 15124 DISCH_THEN(MP_TAC o MATCH_MP CHOOSE_SUBSET_STRONG) THEN 15125 REWRITE_TAC [ARITH_PROVE ``3 = SUC 2``, TWO, ONE, HAS_SIZE_CLAUSES] THEN 15126 DISCH_TAC THEN KNOW_TAC ``(?a b c:real. 15127 ((~(b = c) /\ ~(a = c)) /\ ~(a = b)) /\ {a; b; c} SUBSET s)`` THENL 15128 [POP_ASSUM MP_TAC THEN 15129 REWRITE_TAC [ARITH_PROVE ``3 = SUC 2``, TWO, ONE, HAS_SIZE_CLAUSES] THEN 15130 SET_TAC [], POP_ASSUM K_TAC] THEN 15131 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, GSYM CONJ_ASSOC] THEN 15132 REWRITE_TAC[INSERT_SUBSET, EMPTY_SUBSET] THEN 15133 ONCE_REWRITE_TAC [METIS [] 15134 ``(b <> c /\ a <> c /\ a <> b /\ a IN s /\ b IN s /\ c IN s ==> 15135 ?a b c:real. a < b /\ b < c /\ a IN s /\ b IN s /\ c IN s) = 15136 (\a b c. b <> c /\ a <> c /\ a <> b /\ a IN s /\ b IN s /\ c IN s ==> 15137 ?a b c:real. a < b /\ b < c /\ a IN s /\ b IN s /\ c IN s) a b c``] THEN 15138 MATCH_MP_TAC(METIS [REAL_LE_TOTAL] 15139 ``(!m n p:real. P m n p ==> P n p m /\ P n m p) /\ 15140 (!m n p. m <= n /\ n <= p ==> P m n p) 15141 ==> !m n p. P m n p``) THEN 15142 CONJ_TAC THENL [METIS_TAC[], ALL_TAC] THEN 15143 SIMP_TAC std_ss [REAL_LT_LE] THEN METIS_TAC[]); 15144 15145val CARD_FRONTIER_INTERVAL = store_thm ("CARD_FRONTIER_INTERVAL", 15146 ``!s:real->bool. 15147 is_interval s ==> FINITE(frontier s) /\ CARD(frontier s) <= 2``, 15148 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC lemma THEN 15149 SIMP_TAC std_ss [NOT_EXISTS_THM, FRONTIER_CLOSURES, IN_INTER] THEN 15150 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``, ``c:real``] THEN 15151 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 15152 MAP_EVERY UNDISCH_TAC 15153 [``b IN closure (univ(:real) DIFF s)``, 15154 ``(a:real) IN closure s``, ``(c:real) IN closure s``] THEN 15155 SIMP_TAC std_ss [CLOSURE_APPROACHABLE, IN_DIFF, IN_UNIV, dist] THEN 15156 DISCH_THEN(MP_TAC o SPEC ``(c - b) / &2:real``) THEN 15157 ASM_REWRITE_TAC[REAL_HALF, REAL_SUB_LT] THEN 15158 DISCH_THEN(X_CHOOSE_THEN ``v:real`` STRIP_ASSUME_TAC) THEN 15159 DISCH_THEN(MP_TAC o SPEC ``(b - a) / &2:real``) THEN 15160 ASM_REWRITE_TAC[REAL_HALF, REAL_SUB_LT] THEN 15161 DISCH_THEN(X_CHOOSE_THEN ``u:real`` STRIP_ASSUME_TAC) THEN 15162 EXISTS_TAC ``min ((b - a) / &2:real) ((c - b) / &2:real)`` THEN 15163 ASM_REWRITE_TAC[REAL_HALF, REAL_SUB_LT, REAL_LT_MIN] THEN 15164 X_GEN_TAC ``w:real`` THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 15165 UNDISCH_TAC ``is_interval s`` THEN DISCH_TAC THEN 15166 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [IS_INTERVAL]) THEN 15167 DISCH_THEN(MP_TAC o SPECL [``u:real``, ``v:real``, ``w:real``]) THEN 15168 ASM_REWRITE_TAC[] THEN FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 15169 ASM_REAL_ARITH_TAC); 15170 15171(* ------------------------------------------------------------------------- *) 15172(* Limit component bounds. *) 15173(* ------------------------------------------------------------------------- *) 15174 15175val LIM_COMPONENT_UBOUND = store_thm ("LIM_COMPONENT_UBOUND", 15176 ``!net:('a)net f (l:real) b k. 15177 ~(trivial_limit net) /\ (f --> l) net /\ 15178 eventually (\x. f x <= b) net 15179 ==> l <= b``, 15180 REPEAT STRIP_TAC THEN MP_TAC(ISPECL 15181 [``net:('a)net``, ``f:'a->real``, ``{y:real | y <= b}``, ``l:real``] 15182 LIM_IN_CLOSED_SET) THEN 15183 ASM_SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_LE, GSPECIFICATION]); 15184 15185val LIM_COMPONENT_LBOUND = store_thm ("LIM_COMPONENT_LBOUND", 15186 ``!net:('a)net f (l:real) b. 15187 ~(trivial_limit net) /\ (f --> l) net /\ 15188 eventually (\x. b <= (f x)) net 15189 ==> b <= l``, 15190 REPEAT STRIP_TAC THEN MP_TAC(ISPECL 15191 [``net:('a)net``, ``f:'a->real``, ``{y:real | b <= y}``, ``l:real``] 15192 LIM_IN_CLOSED_SET) THEN 15193 ASM_SIMP_TAC std_ss [REWRITE_RULE[real_ge] CLOSED_HALFSPACE_COMPONENT_GE, 15194 GSPECIFICATION]); 15195 15196val LIM_COMPONENT_EQ = store_thm ("LIM_COMPONENT_EQ", 15197 ``!net f:'a->real i l b. 15198 (f --> l) net /\ 15199 ~(trivial_limit net) /\ eventually (\x. f(x) = b) net 15200 ==> (l = b)``, 15201 SIMP_TAC std_ss [GSYM REAL_LE_ANTISYM, EVENTUALLY_AND] THEN 15202 METIS_TAC [LIM_COMPONENT_UBOUND, LIM_COMPONENT_LBOUND]); 15203 15204val LIM_COMPONENT_LE = store_thm ("LIM_COMPONENT_LE", 15205 ``!net:('a)net f:'a->real g:'a->real l m. 15206 ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\ 15207 eventually (\x. (f x) <= (g x)) net 15208 ==> (l <= m)``, 15209 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN 15210 SIMP_TAC std_ss [LIM_COMPONENT_LBOUND] THEN 15211 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 15212 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> b /\ a ==> c ==> d`] THEN 15213 DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN REPEAT STRIP_TAC THEN 15214 MATCH_MP_TAC LIM_COMPONENT_LBOUND THEN EXISTS_TAC ``net:'a net`` THEN 15215 EXISTS_TAC ``(\(x :'a). (g :'a -> real) x - (f :'a -> real) x)`` THEN 15216 METIS_TAC []); 15217 15218val LIM_DROP_LE = store_thm ("LIM_DROP_LE", 15219 ``!net:('a)net f g l m. 15220 ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\ 15221 eventually (\x. f x <= g x) net 15222 ==> l <= m``, 15223 REPEAT STRIP_TAC THEN 15224 MATCH_MP_TAC(ISPEC ``net:('a)net`` LIM_COMPONENT_LE) THEN 15225 MAP_EVERY EXISTS_TAC [``f:'a->real``, ``g:'a->real``] THEN 15226 ASM_REWRITE_TAC[LESS_EQ_REFL]); 15227 15228val LIM_DROP_UBOUND = store_thm ("LIM_DROP_UBOUND", 15229 ``!net f:'a->real l b. 15230 (f --> l) net /\ 15231 ~(trivial_limit net) /\ eventually (\x. f x <= b) net 15232 ==> l <= b``, 15233 REPEAT STRIP_TAC THEN 15234 MATCH_MP_TAC LIM_COMPONENT_UBOUND THEN 15235 REWRITE_TAC[LESS_EQ_REFL] THEN METIS_TAC[]); 15236 15237val LIM_DROP_LBOUND = store_thm ("LIM_DROP_LBOUND", 15238 ``!net f:'a->real l b. 15239 (f --> l) net /\ 15240 ~(trivial_limit net) /\ eventually (\x. b <= f x) net 15241 ==> b <= l``, 15242 REPEAT STRIP_TAC THEN 15243 MATCH_MP_TAC LIM_COMPONENT_LBOUND THEN 15244 REWRITE_TAC[LESS_EQ_REFL] THEN METIS_TAC[]); 15245 15246(* ------------------------------------------------------------------------- *) 15247(* Also extending closed bounds to closures. *) 15248(* ------------------------------------------------------------------------- *) 15249 15250val IMAGE_CLOSURE_SUBSET = store_thm ("IMAGE_CLOSURE_SUBSET", 15251 ``!f (s:real->bool) (t:real->bool). 15252 f continuous_on closure s /\ closed t /\ IMAGE f s SUBSET t 15253 ==> IMAGE f (closure s) SUBSET t``, 15254 REPEAT STRIP_TAC THEN 15255 SUBGOAL_THEN ``closure s SUBSET {x | (f:real->real) x IN t}`` MP_TAC 15256 THENL [MATCH_MP_TAC SUBSET_TRANS, SET_TAC []] THEN 15257 EXISTS_TAC ``{x | x IN closure s /\ (f:real->real) x IN t}`` THEN 15258 CONJ_TAC THENL 15259 [MATCH_MP_TAC CLOSURE_MINIMAL, SET_TAC[]] THEN 15260 ASM_SIMP_TAC std_ss [CONTINUOUS_CLOSED_PREIMAGE, CLOSED_CLOSURE] THEN 15261 MP_TAC (ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[]); 15262 15263val CLOSURE_IMAGE_CLOSURE = store_thm ("CLOSURE_IMAGE_CLOSURE", 15264 ``!f:real->real s. 15265 f continuous_on closure s 15266 ==> (closure(IMAGE f (closure s)) = closure(IMAGE f s))``, 15267 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 15268 SIMP_TAC std_ss [SUBSET_CLOSURE, IMAGE_SUBSET, CLOSURE_SUBSET] THEN 15269 SIMP_TAC std_ss [CLOSURE_MINIMAL_EQ, CLOSED_CLOSURE] THEN 15270 MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN 15271 ASM_REWRITE_TAC[CLOSED_CLOSURE, CLOSURE_SUBSET]); 15272 15273val CLOSURE_IMAGE_BOUNDED = store_thm ("CLOSURE_IMAGE_BOUNDED", 15274 ``!f:real->real s. 15275 f continuous_on closure s /\ bounded s 15276 ==> (closure(IMAGE f s) = IMAGE f (closure s))``, 15277 REPEAT STRIP_TAC THEN 15278 MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC ``closure(IMAGE (f:real->real) (closure s))`` THEN 15279 CONJ_TAC THENL [ASM_MESON_TAC[CLOSURE_IMAGE_CLOSURE], ALL_TAC] THEN 15280 MATCH_MP_TAC CLOSURE_CLOSED THEN MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 15281 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN 15282 ASM_REWRITE_TAC[COMPACT_CLOSURE]); 15283 15284val CONTINUOUS_ON_CLOSURE_ABS_LE = store_thm ("CONTINUOUS_ON_CLOSURE_ABS_LE", 15285 ``!f:real->real s x b. 15286 f continuous_on (closure s) /\ 15287 (!y. y IN s ==> abs(f y) <= b) /\ 15288 x IN (closure s) 15289 ==> abs(f x) <= b``, 15290 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN 15291 SUBGOAL_THEN ``IMAGE (f:real->real) (closure s) SUBSET cball(0,b)`` 15292 MP_TAC THENL 15293 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET, ASM_SET_TAC []] THEN 15294 ASM_REWRITE_TAC [CLOSED_CBALL] THEN ASM_SET_TAC []); 15295 15296val CONTINUOUS_ON_CLOSURE_COMPONENT_LE = store_thm ("CONTINUOUS_ON_CLOSURE_COMPONENT_LE", 15297 ``!f:real->real s x b. 15298 f continuous_on (closure s) /\ 15299 (!y. y IN s ==> (f y) <= b) /\ 15300 x IN (closure s) 15301 ==> (f x) <= b``, 15302 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN 15303 SUBGOAL_THEN ``IMAGE (f:real->real) (closure s) SUBSET {x | x <= b}`` 15304 MP_TAC THENL 15305 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET, ASM_SET_TAC []] THEN 15306 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE] THEN ASM_SET_TAC[]); 15307 15308val CONTINUOUS_ON_CLOSURE_COMPONENT_GE = store_thm ("CONTINUOUS_ON_CLOSURE_COMPONENT_GE", 15309 ``!f:real->real s x b. 15310 f continuous_on (closure s) /\ 15311 (!y. y IN s ==> b <= (f y)) /\ 15312 x IN (closure s) 15313 ==> b <= (f x)``, 15314 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN 15315 SUBGOAL_THEN ``IMAGE (f:real->real) (closure s) SUBSET {x | x >= b}`` 15316 MP_TAC THENL 15317 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET, ASM_SET_TAC [real_ge]] THEN 15318 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_GE] THEN ASM_SET_TAC[real_ge]); 15319 15320val CONTINUOUS_MAP_CLOSURES = store_thm ("CONTINUOUS_MAP_CLOSURES", 15321 ``!f:real->real. 15322 f continuous_on UNIV <=> 15323 !s. IMAGE f (closure s) SUBSET closure(IMAGE f s)``, 15324 GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL 15325 [GEN_TAC THEN MATCH_MP_TAC(MESON[SUBSET_DEF, CLOSURE_SUBSET] 15326 ``(closure s = t) ==> s SUBSET t``) THEN 15327 MATCH_MP_TAC CLOSURE_IMAGE_CLOSURE THEN 15328 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, SUBSET_UNIV], 15329 REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN 15330 REWRITE_TAC[GSYM CLOSED_IN, SUBTOPOLOGY_UNIV, IN_UNIV] THEN 15331 X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN 15332 FIRST_X_ASSUM(MP_TAC o SPEC ``{x | (f:real->real) x IN t}``) THEN 15333 REWRITE_TAC[GSYM CLOSURE_SUBSET_EQ] THEN 15334 SUBGOAL_THEN 15335 ``closure(IMAGE (f:real->real) {x | f x IN t}) SUBSET t`` 15336 MP_TAC THENL 15337 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SET_TAC[], SET_TAC[]]]); 15338 15339(* ------------------------------------------------------------------------- *) 15340(* Limits relative to a union. *) 15341(* ------------------------------------------------------------------------- *) 15342 15343val LIM_WITHIN_UNION = store_thm ("LIM_WITHIN_UNION", 15344 ``(f --> l) (at x within (s UNION t)) <=> 15345 (f --> l) (at x within s) /\ (f --> l) (at x within t)``, 15346 SIMP_TAC std_ss [LIM_WITHIN, IN_UNION, GSYM FORALL_AND_THM] THEN 15347 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN 15348 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN 15349 EQ_TAC THENL [MESON_TAC[], ALL_TAC] THEN DISCH_THEN 15350 (CONJUNCTS_THEN2 (X_CHOOSE_TAC ``d:real``) (X_CHOOSE_TAC ``k:real``)) THEN 15351 EXISTS_TAC ``min d k:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 15352 ASM_MESON_TAC[]); 15353 15354val CONTINUOUS_ON_UNION = store_thm ("CONTINUOUS_ON_UNION", 15355 ``!f s t. closed s /\ closed t /\ f continuous_on s /\ f continuous_on t 15356 ==> f continuous_on (s UNION t)``, 15357 REWRITE_TAC[CONTINUOUS_ON, CLOSED_LIMPT, IN_UNION, LIM_WITHIN_UNION] THEN 15358 MESON_TAC[LIM, TRIVIAL_LIMIT_WITHIN]); 15359 15360val CONTINUOUS_ON_CASES = store_thm ("CONTINUOUS_ON_CASES", 15361 ``!P f g:real->real s t. 15362 closed s /\ closed t /\ f continuous_on s /\ g continuous_on t /\ 15363 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x)) 15364 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)``, 15365 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION THEN 15366 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL 15367 [EXISTS_TAC ``f:real->real``, EXISTS_TAC ``g:real->real``] THEN 15368 METIS_TAC[]); 15369 15370val CONTINUOUS_ON_UNION_LOCAL = store_thm ("CONTINUOUS_ON_UNION_LOCAL", 15371 ``!f:real->real s. 15372 closed_in (subtopology euclidean (s UNION t)) s /\ 15373 closed_in (subtopology euclidean (s UNION t)) t /\ 15374 f continuous_on s /\ f continuous_on t 15375 ==> f continuous_on (s UNION t)``, 15376 REWRITE_TAC[CONTINUOUS_ON, CLOSED_IN_LIMPT, IN_UNION, LIM_WITHIN_UNION] THEN 15377 MESON_TAC[LIM, TRIVIAL_LIMIT_WITHIN]); 15378 15379val CONTINUOUS_ON_CASES_LOCAL = store_thm ("CONTINUOUS_ON_CASES_LOCAL", 15380 ``!P f g:real->real s t. 15381 closed_in (subtopology euclidean (s UNION t)) s /\ 15382 closed_in (subtopology euclidean (s UNION t)) t /\ 15383 f continuous_on s /\ g continuous_on t /\ 15384 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x)) 15385 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)``, 15386 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL THEN 15387 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL 15388 [EXISTS_TAC ``f:real->real``, EXISTS_TAC ``g:real->real``] THEN 15389 METIS_TAC[]); 15390 15391val CONTINUOUS_ON_CASES_LE = store_thm ("CONTINUOUS_ON_CASES_LE", 15392 ``!f g:real->real h s a. 15393 f continuous_on {t | t IN s /\ h t <= a} /\ 15394 g continuous_on {t | t IN s /\ a <= h t} /\ 15395 (h) continuous_on s /\ 15396 (!t. t IN s /\ (h t = a) ==> (f t = g t)) 15397 ==> (\t. if h t <= a then f(t) else g(t)) continuous_on s``, 15398 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC 15399 ``{t | t IN s /\ (h:real->real) t <= a} UNION 15400 {t | t IN s /\ a <= h t}`` THEN 15401 CONJ_TAC THENL 15402 [ALL_TAC, SIMP_TAC std_ss [SUBSET_DEF, IN_UNION, GSPECIFICATION, REAL_LE_TOTAL]] THEN 15403 ONCE_REWRITE_TAC [METIS [] ``h t <= a <=> (\t:real. h t <= a:real) t``] THEN 15404 MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN ASM_SIMP_TAC std_ss [] THEN 15405 SIMP_TAC std_ss [GSPECIFICATION, GSYM CONJ_ASSOC, REAL_LE_ANTISYM] THEN 15406 REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL 15407 [ALL_TAC, METIS_TAC[]] THEN 15408 CONJ_TAC THENL 15409 [SUBGOAL_THEN 15410 ``{t | t IN s /\ (h:real->real) t <= a} = 15411 {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\ 15412 (h) t IN {x | x <= a}}`` 15413 (fn th => GEN_REWR_TAC RAND_CONV [th]) 15414 THENL 15415 [SIMP_TAC std_ss [o_THM, GSPECIFICATION, EXTENSION, IN_UNION] THEN 15416 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC std_ss [], 15417 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN 15418 ASM_SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_LE, ETA_AX] THEN 15419 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 15420 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[]], 15421 SUBGOAL_THEN 15422 ``{t | t IN s /\ a <= (h:real->real) t} = 15423 {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\ 15424 (h) t IN {x | x >= a}}`` 15425 (fn th => GEN_REWR_TAC RAND_CONV [th]) 15426 THENL 15427 [SIMP_TAC std_ss [o_THM, GSPECIFICATION, EXTENSION, IN_UNION] THEN 15428 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC std_ss [real_ge] THEN 15429 ASM_REAL_ARITH_TAC, 15430 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN 15431 ASM_SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_GE, ETA_AX] THEN 15432 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 15433 CONTINUOUS_ON_SUBSET)) THEN 15434 SET_TAC[]]]); 15435 15436val CONTINUOUS_ON_CASES_1 = store_thm ("CONTINUOUS_ON_CASES_1", 15437 ``!f g:real->real s a. 15438 f continuous_on {t | t IN s /\ t <= a} /\ 15439 g continuous_on {t | t IN s /\ a <= t} /\ 15440 (a IN s ==> (f(a) = g(a))) 15441 ==> (\t. if t <= a then f(t) else g(t)) continuous_on s``, 15442 REPEAT STRIP_TAC THEN 15443 ONCE_REWRITE_TAC [METIS [] ``t <= a <=> (\t. t) t <= a:real``] THEN 15444 MATCH_MP_TAC CONTINUOUS_ON_CASES_LE THEN 15445 ASM_SIMP_TAC std_ss [o_DEF, CONTINUOUS_ON_ID] THEN 15446 METIS_TAC[]); 15447 15448val EXTENSION_FROM_CLOPEN = store_thm ("EXTENSION_FROM_CLOPEN", 15449 ``!f:real->real s t u. 15450 open_in (subtopology euclidean s) t /\ 15451 closed_in (subtopology euclidean s) t /\ 15452 f continuous_on t /\ IMAGE f t SUBSET u /\ ((u = {}) ==> (s = {})) 15453 ==> ?g. g continuous_on s /\ IMAGE g s SUBSET u /\ 15454 !x. x IN t ==> (g x = f x)``, 15455 REPEAT GEN_TAC THEN ASM_CASES_TAC ``u:real->bool = {}`` THEN 15456 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_EMPTY, IMAGE_EMPTY, IMAGE_INSERT, SUBSET_EMPTY, 15457 IMAGE_EQ_EMPTY, NOT_IN_EMPTY] THEN 15458 STRIP_TAC THEN UNDISCH_TAC ``u <> {}:real->bool`` THEN DISCH_TAC THEN 15459 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 15460 DISCH_THEN(X_CHOOSE_TAC ``a:real``) THEN 15461 EXISTS_TAC ``\x. if x IN t then (f:real->real) x else a`` THEN 15462 SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE] THEN 15463 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 15464 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 15465 SUBGOAL_THEN ``s:real->bool = t UNION (s DIFF t)`` SUBST1_TAC THENL 15466 [ASM_SET_TAC[], 15467 ONCE_REWRITE_TAC [METIS [] ``(\x. if x IN t then f x else a) = 15468 (\x. if (\x. x IN t) x then f x else (\x. a) x)``] THEN 15469 MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL] THEN 15470 ASM_SIMP_TAC std_ss [SET_RULE ``t SUBSET s ==> (t UNION (s DIFF t) = s)``] THEN 15471 REWRITE_TAC[CONTINUOUS_ON_CONST, IN_DIFF] THEN 15472 CONJ_TAC THENL [MATCH_MP_TAC CLOSED_IN_DIFF, MESON_TAC[]] THEN 15473 ASM_REWRITE_TAC[CLOSED_IN_REFL]); 15474 15475(* ------------------------------------------------------------------------- *) 15476(* Some more convenient intermediate-value theorem formulations. *) 15477(* ------------------------------------------------------------------------- *) 15478 15479val CONNECTED_IVT_HYPERPLANE = store_thm ("CONNECTED_IVT_HYPERPLANE", 15480 ``!s x y:real a b. 15481 connected s /\ 15482 x IN s /\ y IN s /\ a * x <= b /\ b <= a * y 15483 ==> ?z. z IN s /\ (a * z = b)``, 15484 REPEAT STRIP_TAC THEN 15485 UNDISCH_TAC ``connected s`` THEN DISCH_TAC THEN 15486 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [connected]) THEN 15487 SIMP_TAC std_ss [NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o SPECL 15488 [``{x:real | a * x < b}``, ``{x:real | a * x > b}``]) THEN 15489 SIMP_TAC std_ss [OPEN_HALFSPACE_LT, OPEN_HALFSPACE_GT] THEN 15490 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN SIMP_TAC std_ss [] THEN STRIP_TAC THEN 15491 SIMP_TAC real_ss [EXTENSION, GSPECIFICATION, IN_INTER, NOT_IN_EMPTY, SUBSET_DEF, 15492 IN_UNION, REAL_LT_LE, real_gt] THEN 15493 METIS_TAC[REAL_LE_TOTAL, REAL_LE_ANTISYM]); 15494 15495val CONNECTED_IVT_COMPONENT = store_thm ("CONNECTED_IVT_COMPONENT", 15496 ``!s x y:real a. 15497 connected s /\ x IN s /\ y IN s /\ x <= a /\ a <= y 15498 ==> ?z. z IN s /\ (z = a)``, 15499 REPEAT STRIP_TAC THEN MP_TAC(ISPECL 15500 [``s:real->bool``, ``x:real``, ``y:real``, ``1:real``, 15501 ``a:real``] CONNECTED_IVT_HYPERPLANE) THEN 15502 ASM_SIMP_TAC std_ss [REAL_MUL_LID]); 15503 15504(* ------------------------------------------------------------------------- *) 15505(* Rather trivial observation that we can map any connected set on segment. *) 15506(* ------------------------------------------------------------------------- *) 15507 15508val MAPPING_CONNECTED_ONTO_SEGMENT = store_thm ("MAPPING_CONNECTED_ONTO_SEGMENT", 15509 ``!s:real->bool a b:real. 15510 connected s /\ ~(?a. s SUBSET {a}) 15511 ==> ?f. f continuous_on s /\ (IMAGE f s = segment[a,b])``, 15512 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE 15513 ``~(?a. s SUBSET {a}) ==> ?a b. a IN s /\ b IN s /\ ~(a = b)``)) THEN 15514 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 15515 MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN STRIP_TAC THEN EXISTS_TAC 15516 ``\x:real. a + dist(u,x) / (dist(u,x) + dist(v,x)) * (b - a:real)`` THEN 15517 CONJ_TAC THEN SIMP_TAC std_ss [] THENL 15518 [ONCE_REWRITE_TAC [METIS [] 15519 ``(\x. a + dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) = 15520 (\x. (\x. a) x + (\x. dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) x)``] THEN 15521 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN 15522 ONCE_REWRITE_TAC [METIS [] 15523 ``(\x. dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) = 15524 (\x. (\x. dist (u,x) / (dist (u,x) + dist (v,x))) x * (\x. (b - a)) x)``] THEN 15525 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN SIMP_TAC std_ss [o_DEF, CONTINUOUS_ON_CONST], 15526 15527 REWRITE_TAC[segment, REAL_ARITH 15528 ``(&1 - u) * a + u * b:real = a + u * (b - a)``] THEN 15529 ONCE_REWRITE_TAC [METIS [] 15530 ``(\x. a + dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) = 15531 (\x. a + (\x. dist (u,x) / (dist (u,x) + dist (v,x))) x * (b - a))``] THEN 15532 ONCE_REWRITE_TAC [METIS [] ``(0 <= u /\ u <= 1:real) <=> (\u. 0 <= u /\ u <= 1) u``] THEN 15533 MATCH_MP_TAC(SET_RULE 15534 ``(IMAGE f s = {x | P x}) 15535 ==> (IMAGE (\x. a + f x * b) s = {a + u * b:real | P u})``) THEN 15536 SIMP_TAC std_ss [GSYM SUBSET_ANTISYM_EQ, SUBSET_DEF, FORALL_IN_IMAGE] THEN 15537 ASM_SIMP_TAC real_ss [dist, GSPECIFICATION, REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ, 15538 REAL_ARITH ``~(u:real = v) ==> &0 < abs(u - x) + abs(v - x)``] THEN 15539 CONJ_TAC THENL [REAL_ARITH_TAC, REWRITE_TAC[IN_IMAGE]] THEN 15540 X_GEN_TAC ``t:real`` THEN STRIP_TAC THEN 15541 MP_TAC(ISPECL 15542 [``IMAGE (\x:real. dist(u,x) / (dist(u,x) + dist(v,x))) s``, 15543 ``0:real``, ``1:real``, ``t:real``] 15544 CONNECTED_IVT_COMPONENT) THEN 15545 ASM_SIMP_TAC arith_ss [] THEN 15546 SIMP_TAC std_ss [EXISTS_IN_IMAGE] THEN 15547 KNOW_TAC ``connected 15548 (IMAGE 15549 (\(x :real). 15550 (dist ((u :real),x) :real) / 15551 ((dist (u,x) :real) + (dist ((v :real),x) :real))) 15552 (s :real -> bool)) /\ 15553 (0 :real) IN 15554 IMAGE 15555 (\(x :real). 15556 (dist (u,x) :real) / ((dist (u,x) :real) + (dist (v,x) :real))) 15557 s /\ 15558 (1 :real) IN 15559 IMAGE 15560 (\(x :real). 15561 (dist (u,x) :real) / ((dist (u,x) :real) + (dist (v,x) :real))) 15562 s`` THENL 15563 [REWRITE_TAC[IN_IMAGE], DISCH_TAC THEN ASM_REWRITE_TAC [IN_IMAGE] THEN 15564 BETA_TAC THEN MESON_TAC[dist]] THEN 15565 REPEAT CONJ_TAC THENL 15566 [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[], 15567 EXISTS_TAC ``u:real`` THEN ASM_REWRITE_TAC[DIST_REFL, real_div, dist] THEN 15568 BETA_TAC THEN REAL_ARITH_TAC, 15569 EXISTS_TAC ``v:real`` THEN ASM_REWRITE_TAC[DIST_REFL] THEN 15570 ASM_SIMP_TAC std_ss [REAL_DIV_REFL, DIST_EQ_0, REAL_ADD_RID] THEN 15571 RULE_ASSUM_TAC (ONCE_REWRITE_RULE 15572 [REAL_ARITH ``(u <> v) = (abs (u - v) <> 0:real)``]) THEN 15573 ASM_SIMP_TAC real_ss [REAL_DIV_REFL]]] THEN 15574 REWRITE_TAC[real_div] THENL 15575 [ONCE_REWRITE_TAC [METIS [] ``(\x. dist (u,x) * inv (dist (u,x) + dist (v,x))) = 15576 (\x. (\x. dist (u,x)) x * (\x. inv (dist (u,x) + dist (v,x))) x)``] THEN 15577 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN 15578 REWRITE_TAC[CONTINUOUS_ON_DIST] THEN 15579 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (dist (u,x) + dist (v,x))) = 15580 (\x. inv ((\x. (dist (u,x) + dist (v,x))) x))``] THEN 15581 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN 15582 ASM_SIMP_TAC std_ss [dist, REAL_ARITH 15583 ``~(u:real = v) ==> ~(abs(u - x) + abs(v - x) = &0)``] THEN 15584 ONCE_REWRITE_TAC [METIS [] ``(\x:real. abs (u - x) + abs (v - x)) = 15585 (\x. (\x. abs (u - x)) x + (\x. abs (v - x)) x)``] THEN 15586 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN 15587 SIMP_TAC std_ss [GSYM dist, REWRITE_RULE[o_DEF] CONTINUOUS_ON_DIST], 15588 ONCE_REWRITE_TAC [METIS [] ``(\x. dist (u,x) * inv (dist (u,x) + dist (v,x))) = 15589 (\x. (\x. dist (u,x)) x * (\x. inv (dist (u,x) + dist (v,x))) x)``] THEN 15590 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN 15591 REWRITE_TAC[CONTINUOUS_ON_DIST] THEN 15592 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (dist (u,x) + dist (v,x))) = 15593 (\x. inv ((\x. (dist (u,x) + dist (v,x))) x))``] THEN 15594 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN 15595 ASM_SIMP_TAC std_ss [dist, REAL_ARITH 15596 ``~(u:real = v) ==> ~(abs(u - x) + abs(v - x) = &0)``] THEN 15597 ONCE_REWRITE_TAC [METIS [] ``(\x:real. abs (u - x) + abs (v - x)) = 15598 (\x. (\x. abs (u - x)) x + (\x. abs (v - x)) x)``] THEN 15599 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN 15600 SIMP_TAC std_ss [GSYM dist, REWRITE_RULE[o_DEF] CONTINUOUS_ON_DIST], 15601 ALL_TAC] THEN 15602 FULL_SIMP_TAC std_ss [GSYM dist, DIST_REFL, REAL_ADD_RID] THEN 15603 REWRITE_TAC [GSYM real_div] THEN METIS_TAC [REAL_DIV_REFL]); 15604 15605(* ------------------------------------------------------------------------- *) 15606(* Also more convenient formulations of monotone convergence. *) 15607(* ------------------------------------------------------------------------- *) 15608 15609val BOUNDED_INCREASING_CONVERGENT = store_thm ("BOUNDED_INCREASING_CONVERGENT", 15610 ``!s:num->real. 15611 bounded {s n | n IN univ(:num)} /\ (!n. (s n) <= (s(SUC n))) 15612 ==> ?l. (s --> l) sequentially``, 15613 GEN_TAC THEN 15614 SIMP_TAC std_ss [bounded_def, GSPECIFICATION, LIM_SEQUENTIALLY, dist, 15615 IN_UNIV] THEN 15616 DISCH_TAC THEN MATCH_MP_TAC CONVERGENT_BOUNDED_MONOTONE THEN 15617 SIMP_TAC std_ss [LEFT_EXISTS_AND_THM] THEN 15618 CONJ_TAC THENL [METIS_TAC[], ALL_TAC] THEN DISJ1_TAC THEN 15619 ONCE_REWRITE_TAC [METIS [] ``!m n. ((s:num->real) m <= s n) = (\m n. s m <= s n) m n``] THEN 15620 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN 15621 METIS_TAC [REAL_LE_TRANS, REAL_LE_REFL]); 15622 15623val BOUNDED_DECREASING_CONVERGENT = store_thm ("BOUNDED_DECREASING_CONVERGENT", 15624 ``!s:num->real. 15625 bounded {s n | n IN univ(:num)} /\ (!n. (s(SUC n)) <= (s(n))) 15626 ==> ?l. (s --> l) sequentially``, 15627 GEN_TAC THEN SIMP_TAC std_ss [bounded_def, FORALL_IN_GSPEC] THEN 15628 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 15629 MP_TAC(ISPEC ``\n. -((s:num->real) n)`` BOUNDED_INCREASING_CONVERGENT) THEN 15630 ASM_SIMP_TAC std_ss [bounded_def, FORALL_IN_GSPEC, ABS_NEG, REAL_LE_NEG2] THEN 15631 GEN_REWR_TAC (LAND_CONV o BINDER_CONV) [GSYM LIM_NEG_EQ] THEN 15632 SIMP_TAC std_ss [REAL_NEG_NEG, ETA_AX] THEN METIS_TAC[]); 15633 15634(* ------------------------------------------------------------------------- *) 15635(* Basic homeomorphism definitions. *) 15636(* ------------------------------------------------------------------------- *) 15637 15638val homeomorphism = new_definition ("homeomorphism", 15639 ``homeomorphism (s,t) (f,g) <=> 15640 (!x. x IN s ==> (g(f(x)) = x)) /\ (IMAGE f s = t) /\ f continuous_on s /\ 15641 (!y. y IN t ==> (f(g(y)) = y)) /\ (IMAGE g t = s) /\ g continuous_on t``); 15642 15643val _ = set_fixity "homeomorphic" (Infix(NONASSOC, 450)); 15644 15645val homeomorphic = new_definition ("homeomorphic", 15646 ``s homeomorphic t <=> ?f g. homeomorphism (s,t) (f,g)``); 15647 15648val HOMEOMORPHISM = store_thm ("HOMEOMORPHISM", 15649 ``!s:real->bool t:real->bool f g. 15650 homeomorphism (s,t) (f,g) <=> 15651 f continuous_on s /\ IMAGE f s SUBSET t /\ 15652 g continuous_on t /\ IMAGE g t SUBSET s /\ 15653 (!x. x IN s ==> (g (f x) = x)) /\ 15654 (!y. y IN t ==> (f (g y) = y))``, 15655 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN 15656 EQ_TAC THEN SIMP_TAC std_ss [] THEN SET_TAC[]); 15657 15658val HOMEOMORPHISM_OF_SUBSETS = store_thm ("HOMEOMORPHISM_OF_SUBSETS", 15659 ``!f g s t s' t'. 15660 homeomorphism (s,t) (f,g) /\ s' SUBSET s /\ t' SUBSET t /\ (IMAGE f s' = t') 15661 ==> homeomorphism (s',t') (f,g)``, 15662 REWRITE_TAC[homeomorphism] THEN 15663 REPEAT STRIP_TAC THEN 15664 TRY(MATCH_MP_TAC CONTINUOUS_ON_SUBSET) THEN ASM_SET_TAC[]); 15665 15666val HOMEOMORPHISM_ID = store_thm ("HOMEOMORPHISM_ID", 15667 ``!s:real->bool. homeomorphism (s,s) ((\x. x),(\x. x))``, 15668 SIMP_TAC std_ss [homeomorphism, IMAGE_ID, CONTINUOUS_ON_ID]); 15669 15670val HOMEOMORPHIC_REFL = store_thm ("HOMEOMORPHIC_REFL", 15671 ``!s:real->bool. s homeomorphic s``, 15672 REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_ID]); 15673 15674val HOMEOMORPHISM_SYM = store_thm ("HOMEOMORPHISM_SYM", 15675 ``!f:real->real g s t. 15676 homeomorphism (s,t) (f,g) <=> homeomorphism (t,s) (g,f)``, 15677 REWRITE_TAC[homeomorphism] THEN MESON_TAC[]); 15678 15679val HOMEOMORPHIC_SYM = store_thm ("HOMEOMORPHIC_SYM", 15680 ``!s t. s homeomorphic t <=> t homeomorphic s``, 15681 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic, homeomorphism] THEN 15682 ONCE_REWRITE_TAC [METIS [] 15683 ``((!x. x IN t ==> (g (f x) = x)) /\ (IMAGE f t = s) /\ 15684 f continuous_on t /\ (!y. y IN s ==> (f (g y) = y)) /\ 15685 (IMAGE g s = t) /\ g continuous_on s) = 15686 (\f g. (!x. x IN t ==> (g (f x) = x)) /\ (IMAGE f t = s) /\ 15687 f continuous_on t /\ (!y. y IN s ==> (f (g y) = y)) /\ 15688 (IMAGE g s = t) /\ g continuous_on s) f g``] THEN 15689 GEN_REWR_TAC RAND_CONV [SWAP_EXISTS_THM] THEN 15690 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN SIMP_TAC std_ss [] THEN 15691 TAUT_TAC); 15692 15693val HOMEOMORPHISM_COMPOSE = store_thm ("HOMEOMORPHISM_COMPOSE", 15694 ``!f:real->real g h:real->real k s t u. 15695 homeomorphism (s,t) (f,g) /\ homeomorphism (t,u) (h,k) 15696 ==> homeomorphism (s,u) (h o f,g o k)``, 15697 SIMP_TAC std_ss [homeomorphism, CONTINUOUS_ON_COMPOSE, IMAGE_COMPOSE, o_THM] THEN 15698 SET_TAC[]); 15699 15700val HOMEOMORPHIC_TRANS = store_thm ("HOMEOMORPHIC_TRANS", 15701 ``!s:real->bool t:real->bool u:real->bool. 15702 s homeomorphic t /\ t homeomorphic u ==> s homeomorphic u``, 15703 REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_COMPOSE]); 15704 15705val HOMEOMORPHIC_IMP_CARD_EQ = store_thm ("HOMEOMORPHIC_IMP_CARD_EQ", 15706 ``!s:real->bool t:real->bool. s homeomorphic t ==> s =_c t``, 15707 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic, homeomorphism, eq_c] THEN 15708 STRIP_TAC THEN EXISTS_TAC ``f:real->real`` THEN ASM_SET_TAC []); 15709 15710val HOMEOMORPHIC_FINITENESS = store_thm ("HOMEOMORPHIC_FINITENESS", 15711 ``!s:real->bool t:real->bool. 15712 s homeomorphic t ==> (FINITE s <=> FINITE t)``, 15713 REPEAT GEN_TAC THEN 15714 DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN 15715 DISCH_THEN(ACCEPT_TAC o MATCH_MP CARD_FINITE_CONG)); 15716 15717val HOMEOMORPHIC_EMPTY = store_thm ("HOMEOMORPHIC_EMPTY", 15718 ``(!s. (s:real->bool) homeomorphic ({}:real->bool) <=> (s = {})) /\ 15719 (!s. ({}:real->bool) homeomorphic (s:real->bool) <=> (s = {}))``, 15720 REWRITE_TAC[homeomorphic, homeomorphism, IMAGE_EMPTY, IMAGE_INSERT, IMAGE_EQ_EMPTY] THEN 15721 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 15722 ASM_SIMP_TAC std_ss [continuous_on, NOT_IN_EMPTY]); 15723 15724val HOMEOMORPHIC_MINIMAL = store_thm ("HOMEOMORPHIC_MINIMAL", 15725 ``!s t. s homeomorphic t <=> 15726 ?f g. (!x. x IN s ==> f(x) IN t /\ (g(f(x)) = x)) /\ 15727 (!y. y IN t ==> g(y) IN s /\ (f(g(y)) = y)) /\ 15728 f continuous_on s /\ g continuous_on t``, 15729 REWRITE_TAC[homeomorphic, homeomorphism, EXTENSION, IN_IMAGE] THEN 15730 REPEAT GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN MESON_TAC[]); 15731 15732val HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF = store_thm ("HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF", 15733 ``!f:real->real s. 15734 linear f /\ (!x y. (f x = f y) ==> (x = y)) 15735 ==> (IMAGE f s) homeomorphic s``, 15736 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 15737 FIRST_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_LEFT_INVERSE]) THEN 15738 STRIP_TAC THEN EXISTS_TAC ``g:real->real`` THEN 15739 EXISTS_TAC ``f:real->real`` THEN 15740 ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON, FORALL_IN_IMAGE, FUN_IN_IMAGE] THEN 15741 ASM_SIMP_TAC std_ss [continuous_on, CONJ_EQ_IMP, FORALL_IN_IMAGE] THEN 15742 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 15743 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 15744 MP_TAC(ISPEC ``f:real->real`` LINEAR_INJECTIVE_BOUNDED_BELOW_POS) THEN 15745 ASM_REWRITE_TAC[] THEN 15746 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 15747 EXISTS_TAC ``e * B:real`` THEN ASM_SIMP_TAC real_ss [REAL_LT_MUL] THEN 15748 X_GEN_TAC ``y:real`` THEN ASM_SIMP_TAC std_ss [dist, GSYM LINEAR_SUB] THEN 15749 DISCH_TAC THEN ASM_SIMP_TAC real_ss [GSYM REAL_LT_LDIV_EQ] THEN 15750 MATCH_MP_TAC(REAL_ARITH ``a <= b ==> b < x ==> a < x:real``) THEN 15751 ASM_SIMP_TAC real_ss [REAL_LE_RDIV_EQ]); 15752 15753val HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ = store_thm ("HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ", 15754 ``!f:real->real s t. 15755 linear f /\ (!x y. (f x = f y) ==> (x = y)) 15756 ==> ((IMAGE f s) homeomorphic t <=> s homeomorphic t)``, 15757 REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o SPEC ``s:real->bool`` o 15758 MATCH_MP HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF) THEN 15759 EQ_TAC THENL 15760 [FIRST_X_ASSUM(MP_TAC o ONCE_REWRITE_RULE [HOMEOMORPHIC_SYM]), 15761 POP_ASSUM MP_TAC] THEN 15762 METIS_TAC[AND_IMP_INTRO, HOMEOMORPHIC_TRANS]); 15763 15764val HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ = store_thm ("HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ", 15765 ``!f:real->real s t. 15766 linear f /\ (!x y. (f x = f y) ==> (x = y)) 15767 ==> (s homeomorphic (IMAGE f t) <=> s homeomorphic t)``, 15768 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN 15769 REWRITE_TAC[HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ]); 15770 15771val HOMEOMORPHIC_TRANSLATION_SELF = store_thm ("HOMEOMORPHIC_TRANSLATION_SELF", 15772 ``!a:real s. (IMAGE (\x. a + x) s) homeomorphic s``, 15773 REPEAT GEN_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 15774 EXISTS_TAC ``\x:real. x - a`` THEN 15775 EXISTS_TAC ``\x:real. a + x`` THEN 15776 SIMP_TAC std_ss [FORALL_IN_IMAGE, CONTINUOUS_ON_SUB, CONTINUOUS_ON_ID, 15777 CONTINUOUS_ON_CONST, CONTINUOUS_ON_ADD, REAL_ADD_SUB] THEN 15778 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]); 15779 15780val HOMEOMORPHIC_TRANSLATION_LEFT_EQ = store_thm ("HOMEOMORPHIC_TRANSLATION_LEFT_EQ", 15781 ``!a:real s t. 15782 (IMAGE (\x. a + x) s) homeomorphic t <=> s homeomorphic t``, 15783 METIS_TAC[HOMEOMORPHIC_TRANSLATION_SELF, 15784 HOMEOMORPHIC_SYM, HOMEOMORPHIC_TRANS]); 15785 15786val HOMEOMORPHIC_TRANSLATION_RIGHT_EQ = store_thm ("HOMEOMORPHIC_TRANSLATION_RIGHT_EQ", 15787 ``!a:real s t. 15788 s homeomorphic (IMAGE (\x. a + x) t) <=> s homeomorphic t``, 15789 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN 15790 REWRITE_TAC[HOMEOMORPHIC_TRANSLATION_LEFT_EQ]); 15791 15792val HOMEOMORPHISM_IMP_QUOTIENT_MAP = store_thm ("HOMEOMORPHISM_IMP_QUOTIENT_MAP", 15793 ``!f:real->real g s t. 15794 homeomorphism (s,t) (f,g) 15795 ==> !u. u SUBSET t 15796 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 15797 open_in (subtopology euclidean t) u)``, 15798 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN 15799 STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN 15800 EXISTS_TAC ``g:real->real`` THEN ASM_REWRITE_TAC[SUBSET_REFL]); 15801 15802val HOMEOMORPHIC_SCALING_LEFT = store_thm ("HOMEOMORPHIC_SCALING_LEFT", 15803 ``!c. &0 < c 15804 ==> (!s t. (IMAGE (\x. c * x) s) homeomorphic t <=> s homeomorphic t)``, 15805 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN 15806 MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ THEN 15807 ASM_SIMP_TAC std_ss [REAL_EQ_LMUL, REAL_LT_IMP_NE, LINEAR_SCALING]); 15808 15809val HOMEOMORPHIC_SCALING_RIGHT = store_thm ("HOMEOMORPHIC_SCALING_RIGHT", 15810 ``!c. &0 < c 15811 ==> (!s t. s homeomorphic (IMAGE (\x. c * x) t) <=> s homeomorphic t)``, 15812 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN 15813 MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ THEN 15814 ASM_SIMP_TAC std_ss [REAL_EQ_LMUL, REAL_LT_IMP_NE, LINEAR_SCALING]); 15815 15816val HOMEOMORPHIC_FINITE = store_thm ("HOMEOMORPHIC_FINITE", 15817 ``!s:real->bool t:real->bool. 15818 FINITE s /\ FINITE t ==> (s homeomorphic t <=> (CARD s = CARD t))``, 15819 REPEAT STRIP_TAC THEN EQ_TAC THENL 15820 [DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN 15821 ASM_SIMP_TAC std_ss [CARD_EQ_CARD], 15822 STRIP_TAC THEN REWRITE_TAC[homeomorphic, HOMEOMORPHISM] THEN 15823 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] 15824 CARD_EQ_BIJECTIONS) THEN 15825 ASM_REWRITE_TAC[] THEN 15826 DISCH_THEN (X_CHOOSE_TAC ``f:real->real``) THEN POP_ASSUM MP_TAC THEN 15827 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN 15828 MAP_EVERY EXISTS_TAC [``f:real->real``,``g:real->real``] THEN 15829 POP_ASSUM MP_TAC THEN 15830 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_FINITE] THEN ASM_SET_TAC[]]); 15831 15832val HOMEOMORPHIC_FINITE_STRONG = store_thm ("HOMEOMORPHIC_FINITE_STRONG", 15833 ``!s:real->bool t:real->bool. 15834 FINITE s \/ FINITE t 15835 ==> (s homeomorphic t <=> FINITE s /\ FINITE t /\ (CARD s = CARD t))``, 15836 REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN 15837 SIMP_TAC std_ss [HOMEOMORPHIC_FINITE] THEN DISCH_TAC THEN 15838 FIRST_ASSUM(MP_TAC o MATCH_MP CARD_FINITE_CONG o MATCH_MP 15839 HOMEOMORPHIC_IMP_CARD_EQ) THEN 15840 FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN 15841 ASM_MESON_TAC[HOMEOMORPHIC_FINITE]); 15842 15843val HOMEOMORPHIC_SING = store_thm ("HOMEOMORPHIC_SING", 15844 ``!a:real b:real. {a} homeomorphic {b}``, 15845 SIMP_TAC std_ss [HOMEOMORPHIC_FINITE, FINITE_SING, CARD_SING]); 15846 15847val LIFT_TO_QUOTIENT_SPACE_UNIQUE = store_thm ("LIFT_TO_QUOTIENT_SPACE_UNIQUE", 15848 ``!f:real->real g:real->real s t u. 15849 (IMAGE f s = t) /\ 15850 (IMAGE g s = u) /\ 15851 (!v. v SUBSET t 15852 ==> (open_in (subtopology euclidean s) 15853 {x | x IN s /\ f x IN v} <=> 15854 open_in (subtopology euclidean t) v)) /\ 15855 (!v. v SUBSET u 15856 ==> (open_in (subtopology euclidean s) 15857 {x | x IN s /\ g x IN v} <=> 15858 open_in (subtopology euclidean u) v)) /\ 15859 (!x y. x IN s /\ y IN s ==> ((f x = f y) <=> (g x = g y))) 15860 ==> t homeomorphic u``, 15861 REPEAT STRIP_TAC THEN 15862 MP_TAC(ISPECL 15863 [``f:real->real``, ``g:real->real``, ``s:real->bool``, 15864 ``t:real->bool``, ``u:real->bool``] LIFT_TO_QUOTIENT_SPACE) THEN 15865 MP_TAC(ISPECL 15866 [``g:real->real``, ``f:real->real``, ``s:real->bool``, 15867 ``u:real->bool``, ``t:real->bool``] LIFT_TO_QUOTIENT_SPACE) THEN 15868 ASM_REWRITE_TAC[] THEN 15869 MP_TAC(ISPECL [``f:real->real``, ``s:real->bool``, ``t:real->bool``] 15870 CONTINUOUS_ON_OPEN_GEN) THEN 15871 ASM_SIMP_TAC std_ss [SUBSET_REFL] THEN DISCH_THEN SUBST1_TAC THEN 15872 KNOW_TAC ``(!(u :real -> bool). 15873 open_in (subtopology euclidean (t :real -> bool)) u ==> 15874 open_in (subtopology euclidean (s :real -> bool)) 15875 {x | x IN s /\ (f :real -> real) x IN u})`` THENL 15876 [METIS_TAC[OPEN_IN_IMP_SUBSET], 15877 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 15878 DISCH_THEN(X_CHOOSE_THEN ``h:real->real`` STRIP_ASSUME_TAC)] THEN 15879 MP_TAC(ISPECL [``g:real->real``, ``s:real->bool``, ``u:real->bool``] 15880 CONTINUOUS_ON_OPEN_GEN) THEN 15881 ASM_SIMP_TAC std_ss [SUBSET_REFL] THEN DISCH_THEN SUBST1_TAC THEN 15882 KNOW_TAC ``(!(u' :real -> bool). 15883 open_in (subtopology euclidean (u :real -> bool)) u' ==> 15884 open_in (subtopology euclidean (s :real -> bool)) 15885 {x | x IN s /\ (g :real -> real) x IN u'}) /\ 15886 (!(x :real) (y :real). 15887 x IN s /\ y IN s /\ ((f :real -> real) x = f y) ==> (g x = g y))`` THENL 15888 [METIS_TAC[OPEN_IN_IMP_SUBSET], 15889 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 15890 DISCH_THEN(X_CHOOSE_THEN ``k:real->real`` STRIP_ASSUME_TAC)] THEN 15891 REWRITE_TAC[homeomorphic, homeomorphism] THEN 15892 MAP_EVERY EXISTS_TAC 15893 [``k:real->real``, ``h:real->real``] THEN 15894 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]); 15895 15896(* ------------------------------------------------------------------------- *) 15897(* Inverse function property for open/closed maps. *) 15898(* ------------------------------------------------------------------------- *) 15899 15900val CONTINUOUS_ON_INVERSE_OPEN_MAP = store_thm ("CONTINUOUS_ON_INVERSE_OPEN_MAP", 15901 ``!f:real->real g s t. 15902 f continuous_on s /\ (IMAGE f s = t) /\ (!x. x IN s ==> (g(f x) = x)) /\ 15903 (!u. open_in (subtopology euclidean s) u 15904 ==> open_in (subtopology euclidean t) (IMAGE f u)) 15905 ==> g continuous_on t``, 15906 REPEAT STRIP_TAC THEN 15907 MP_TAC(ISPECL [``g:real->real``, ``t:real->bool``, ``s:real->bool``] 15908 CONTINUOUS_ON_OPEN_GEN) THEN 15909 KNOW_TAC ``IMAGE (g :real -> real) (t :real -> bool) SUBSET (s :real -> bool)`` THENL 15910 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 15911 DISCH_THEN SUBST1_TAC] THEN 15912 X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 15913 FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN ASM_REWRITE_TAC[] THEN 15914 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 15915 FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [open_in]) THEN 15916 ASM_SET_TAC[]); 15917 15918val CONTINUOUS_ON_INVERSE_CLOSED_MAP = store_thm ("CONTINUOUS_ON_INVERSE_CLOSED_MAP", 15919 ``!f:real->real g s t. 15920 f continuous_on s /\ (IMAGE f s = t) /\ (!x. x IN s ==> (g(f x) = x)) /\ 15921 (!u. closed_in (subtopology euclidean s) u 15922 ==> closed_in (subtopology euclidean t) (IMAGE f u)) 15923 ==> g continuous_on t``, 15924 REPEAT STRIP_TAC THEN 15925 MP_TAC(ISPECL [``g:real->real``, ``t:real->bool``, ``s:real->bool``] 15926 CONTINUOUS_ON_CLOSED_GEN) THEN 15927 KNOW_TAC ``IMAGE (g :real -> real) (t :real -> bool) SUBSET (s :real -> bool)`` THENL 15928 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 15929 DISCH_THEN SUBST1_TAC] THEN 15930 X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 15931 FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN ASM_REWRITE_TAC[] THEN 15932 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 15933 FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [closed_in]) THEN 15934 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM_SET_TAC[]); 15935 15936val HOMEOMORPHISM_INJECTIVE_OPEN_MAP = store_thm ("HOMEOMORPHISM_INJECTIVE_OPEN_MAP", 15937 ``!f:real->real s t. 15938 f continuous_on s /\ (IMAGE f s = t) /\ 15939 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) /\ 15940 (!u. open_in (subtopology euclidean s) u 15941 ==> open_in (subtopology euclidean t) (IMAGE f u)) 15942 ==> ?g. homeomorphism (s,t) (f,g)``, 15943 REPEAT STRIP_TAC THEN 15944 UNDISCH_TAC ``!(x :real) (y :real). 15945 x IN (s :real -> bool) /\ y IN s /\ 15946 ((f :real -> real) x = f y) ==> 15947 (x = y)`` THEN DISCH_TAC THEN 15948 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_ON_LEFT_INVERSE]) THEN 15949 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN 15950 ASM_SIMP_TAC std_ss [homeomorphism] THEN 15951 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 15952 MATCH_MP_TAC CONTINUOUS_ON_INVERSE_OPEN_MAP THEN ASM_MESON_TAC[]); 15953 15954val HOMEOMORPHISM_INJECTIVE_CLOSED_MAP = store_thm ("HOMEOMORPHISM_INJECTIVE_CLOSED_MAP", 15955 ``!f:real->real s t. 15956 f continuous_on s /\ (IMAGE f s = t) /\ 15957 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) /\ 15958 (!u. closed_in (subtopology euclidean s) u 15959 ==> closed_in (subtopology euclidean t) (IMAGE f u)) 15960 ==> ?g. homeomorphism (s,t) (f,g)``, 15961 REPEAT STRIP_TAC THEN 15962 UNDISCH_TAC ``!(x :real) (y :real). 15963 x IN (s :real -> bool) /\ y IN s /\ 15964 ((f :real -> real) x = f y) ==> 15965 (x = y)`` THEN DISCH_TAC THEN 15966 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_ON_LEFT_INVERSE]) THEN 15967 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN 15968 ASM_SIMP_TAC std_ss [homeomorphism] THEN 15969 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 15970 MATCH_MP_TAC CONTINUOUS_ON_INVERSE_CLOSED_MAP THEN ASM_MESON_TAC[]); 15971 15972val HOMEOMORPHISM_IMP_OPEN_MAP = store_thm ("HOMEOMORPHISM_IMP_OPEN_MAP", 15973 ``!f:real->real g s t u. 15974 homeomorphism (s,t) (f,g) /\ open_in (subtopology euclidean s) u 15975 ==> open_in (subtopology euclidean t) (IMAGE f u)``, 15976 REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN 15977 SUBGOAL_THEN ``IMAGE (f:real->real) u = 15978 {y | y IN t /\ g(y) IN u}`` 15979 SUBST1_TAC THENL 15980 [FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [open_in]) THEN 15981 ASM_SET_TAC[], 15982 MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]]); 15983 15984val HOMEOMORPHISM_IMP_CLOSED_MAP = store_thm ("HOMEOMORPHISM_IMP_CLOSED_MAP", 15985 ``!f:real->real g s t u. 15986 homeomorphism (s,t) (f,g) /\ closed_in (subtopology euclidean s) u 15987 ==> closed_in (subtopology euclidean t) (IMAGE f u)``, 15988 REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN 15989 SUBGOAL_THEN ``IMAGE (f:real->real) u = 15990 {y | y IN t /\ g(y) IN u}`` 15991 SUBST1_TAC THENL 15992 [FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [closed_in]) THEN 15993 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM_SET_TAC[], 15994 MATCH_MP_TAC CONTINUOUS_ON_IMP_CLOSED_IN THEN ASM_REWRITE_TAC[]]); 15995 15996val HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ = store_thm ("HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ", 15997 ``!f:real->real s t. 15998 f continuous_on s /\ (IMAGE f s = t) /\ 15999 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 16000 ==> ((?g. homeomorphism (s,t) (f,g)) <=> 16001 !u. open_in (subtopology euclidean s) u 16002 ==> open_in (subtopology euclidean t) (IMAGE f u))``, 16003 REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 16004 [MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN ASM_MESON_TAC[], 16005 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN 16006 ASM_REWRITE_TAC[]]); 16007 16008val HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ = store_thm ("HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ", 16009 ``!f:real->real s t. 16010 f continuous_on s /\ (IMAGE f s = t) /\ 16011 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 16012 ==> ((?g. homeomorphism (s,t) (f,g)) <=> 16013 !u. closed_in (subtopology euclidean s) u 16014 ==> closed_in (subtopology euclidean t) (IMAGE f u))``, 16015 REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 16016 [MATCH_MP_TAC HOMEOMORPHISM_IMP_CLOSED_MAP THEN ASM_MESON_TAC[], 16017 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP THEN 16018 ASM_REWRITE_TAC[]]); 16019 16020val INJECTIVE_MAP_OPEN_IFF_CLOSED = store_thm ("INJECTIVE_MAP_OPEN_IFF_CLOSED", 16021 ``!f:real->real s t. 16022 f continuous_on s /\ (IMAGE f s = t) /\ 16023 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 16024 ==> ((!u. open_in (subtopology euclidean s) u 16025 ==> open_in (subtopology euclidean t) (IMAGE f u)) <=> 16026 (!u. closed_in (subtopology euclidean s) u 16027 ==> closed_in (subtopology euclidean t) (IMAGE f u)))``, 16028 REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN 16029 EXISTS_TAC ``?g:real->real. homeomorphism (s,t) (f,g)`` THEN 16030 CONJ_TAC THENL 16031 [CONV_TAC SYM_CONV THEN MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ, 16032 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ] THEN 16033 ASM_REWRITE_TAC[]); 16034 16035(* ------------------------------------------------------------------------- *) 16036(* Relatively weak hypotheses if the domain of the function is compact. *) 16037(* ------------------------------------------------------------------------- *) 16038 16039val CONTINUOUS_IMP_CLOSED_MAP = store_thm ("CONTINUOUS_IMP_CLOSED_MAP", 16040 ``!f:real->real s t. 16041 f continuous_on s /\ (IMAGE f s = t) /\ compact s 16042 ==> !u. closed_in (subtopology euclidean s) u 16043 ==> closed_in (subtopology euclidean t) (IMAGE f u)``, 16044 SIMP_TAC std_ss [CLOSED_IN_CLOSED_EQ, COMPACT_IMP_CLOSED] THEN 16045 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_SUBSET THEN 16046 ASM_SIMP_TAC std_ss [IMAGE_SUBSET] THEN 16047 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 16048 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 16049 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_IN_CLOSED_TRANS, 16050 BOUNDED_SUBSET, CONTINUOUS_ON_SUBSET]); 16051 16052val CONTINUOUS_IMP_QUOTIENT_MAP = store_thm ("CONTINUOUS_IMP_QUOTIENT_MAP", 16053 ``!f:real->real s t. 16054 f continuous_on s /\ (IMAGE f s = t) /\ compact s 16055 ==> !u. u SUBSET t 16056 ==> (open_in (subtopology euclidean s) 16057 {x | x IN s /\ f x IN u} <=> 16058 open_in (subtopology euclidean t) u)``, 16059 REPEAT GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN 16060 MATCH_MP_TAC CLOSED_MAP_IMP_QUOTIENT_MAP THEN 16061 ASM_REWRITE_TAC[] THEN 16062 MATCH_MP_TAC CONTINUOUS_IMP_CLOSED_MAP THEN 16063 ASM_REWRITE_TAC[]); 16064 16065val CONTINUOUS_ON_INVERSE = store_thm ("CONTINUOUS_ON_INVERSE", 16066 ``!f:real->real g s. 16067 f continuous_on s /\ compact s /\ (!x. x IN s ==> (g(f(x)) = x)) 16068 ==> g continuous_on (IMAGE f s)``, 16069 REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN 16070 SUBGOAL_THEN ``IMAGE g (IMAGE (f:real->real) s) = s`` SUBST1_TAC THENL 16071 [REWRITE_TAC[EXTENSION, IN_IMAGE] THEN ASM_MESON_TAC[], ALL_TAC] THEN 16072 X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN 16073 REWRITE_TAC[CLOSED_IN_CLOSED] THEN 16074 EXISTS_TAC ``IMAGE (f:real->real) t`` THEN CONJ_TAC THENL 16075 [MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 16076 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN 16077 FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN 16078 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 16079 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_IN_CLOSED_TRANS, 16080 BOUNDED_SUBSET, CONTINUOUS_ON_SUBSET], 16081 SIMP_TAC std_ss [EXTENSION, IN_INTER, GSPECIFICATION, IN_IMAGE] THEN 16082 ASM_MESON_TAC[CLOSED_IN_SUBSET, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, SUBSET_DEF]]); 16083 16084val HOMEOMORPHISM_COMPACT = store_thm ("HOMEOMORPHISM_COMPACT", 16085 ``!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\ 16086 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 16087 ==> ?g. homeomorphism(s,t) (f,g)``, 16088 REWRITE_TAC[INJECTIVE_ON_LEFT_INVERSE] THEN REPEAT GEN_TAC THEN 16089 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 16090 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN 16091 ASM_SIMP_TAC std_ss [EXTENSION, homeomorphism] THEN 16092 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN 16093 ASM_MESON_TAC[CONTINUOUS_ON_INVERSE, IN_IMAGE]); 16094 16095val HOMEOMORPHIC_COMPACT = store_thm ("HOMEOMORPHIC_COMPACT", 16096 ``!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\ 16097 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 16098 ==> s homeomorphic t``, 16099 REWRITE_TAC[homeomorphic] THEN METIS_TAC[HOMEOMORPHISM_COMPACT]); 16100 16101(* ------------------------------------------------------------------------- *) 16102(* Lemmas about composition of homeomorphisms. *) 16103(* ------------------------------------------------------------------------- *) 16104 16105val HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE = store_thm ("HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE", 16106 ``!f:real->real g:real->real s t u. 16107 f continuous_on s /\ (IMAGE f s = t) /\ 16108 g continuous_on t /\ IMAGE g t SUBSET u /\ 16109 (?h. homeomorphism (s,u) (g o f,h)) 16110 ==> (?f'. homeomorphism (s,t) (f,f')) /\ 16111 (?g'. homeomorphism (t,u) (g,g'))``, 16112 REPEAT GEN_TAC THEN STRIP_TAC THEN 16113 RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism, o_THM]) THEN 16114 MATCH_MP_TAC(TAUT `q /\ (q ==> p) ==> p /\ q`) THEN CONJ_TAC THENL 16115 [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN 16116 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 16117 MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_SURJECTIVE THEN 16118 MAP_EVERY EXISTS_TAC [``f:real->real``, ``s:real->bool``] THEN 16119 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN 16120 MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN 16121 MAP_EVERY EXISTS_TAC [``h:real->real``, ``s:real->bool``] THEN 16122 ASM_SIMP_TAC std_ss [homeomorphism, o_THM], 16123 REWRITE_TAC[homeomorphism, o_THM] THEN 16124 DISCH_THEN(X_CHOOSE_THEN ``g':real->real`` STRIP_ASSUME_TAC) THEN 16125 EXISTS_TAC ``((h:real->real) o (g:real->real))`` THEN 16126 ASM_SIMP_TAC std_ss [o_THM, IMAGE_COMPOSE] THEN 16127 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 16128 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN 16129 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]); 16130 16131val HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE = store_thm ("HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE", 16132 ``!f:real->real g:real->real s t u. 16133 f continuous_on s /\ IMAGE f s SUBSET t /\ 16134 g continuous_on t /\ IMAGE g t SUBSET u /\ 16135 (!x y. x IN t /\ y IN t /\ (g x = g y) ==> (x = y)) /\ 16136 (?h. homeomorphism (s,u) (g o f,h)) 16137 ==> (?f'. homeomorphism (s,t) (f,f')) /\ 16138 (?g'. homeomorphism (t,u) (g,g'))``, 16139 REPEAT GEN_TAC THEN STRIP_TAC THEN 16140 RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism, o_THM]) THEN 16141 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL 16142 [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN 16143 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 16144 MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_INJECTIVE THEN 16145 MAP_EVERY EXISTS_TAC [``g:real->real``, ``u:real->bool``] THEN 16146 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN 16147 MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN 16148 MAP_EVERY EXISTS_TAC [``h:real->real``, ``s:real->bool``] THEN 16149 ASM_REWRITE_TAC[homeomorphism, o_THM], 16150 REWRITE_TAC[homeomorphism, o_THM] THEN 16151 DISCH_THEN(X_CHOOSE_THEN ``f':real->real`` STRIP_ASSUME_TAC) THEN 16152 EXISTS_TAC ``(f:real->real) o (h:real->real)`` THEN 16153 ASM_SIMP_TAC std_ss [o_THM, IMAGE_COMPOSE] THEN 16154 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 16155 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN 16156 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]); 16157 16158(* ------------------------------------------------------------------------- *) 16159(* Preservation of topological properties. *) 16160(* ------------------------------------------------------------------------- *) 16161 16162val HOMEOMORPHIC_COMPACTNESS = store_thm ("HOMEOMORPHIC_COMPACTNESS", 16163 ``!s t. s homeomorphic t ==> (compact s <=> compact t)``, 16164 REWRITE_TAC[homeomorphic, homeomorphism] THEN 16165 MESON_TAC[COMPACT_CONTINUOUS_IMAGE]); 16166 16167val HOMEOMORPHIC_CONNECTEDNESS = store_thm ("HOMEOMORPHIC_CONNECTEDNESS", 16168 ``!s t. s homeomorphic t ==> (connected s <=> connected t)``, 16169 REWRITE_TAC[homeomorphic, homeomorphism] THEN 16170 MESON_TAC[CONNECTED_CONTINUOUS_IMAGE]); 16171 16172(* ------------------------------------------------------------------------- *) 16173(* Results on translation, scaling etc. *) 16174(* ------------------------------------------------------------------------- *) 16175 16176val HOMEOMORPHIC_SCALING = store_thm ("HOMEOMORPHIC_SCALING", 16177 ``!s:real->bool c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. c * x) s)``, 16178 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 16179 MAP_EVERY EXISTS_TAC [``\x:real. c * x``, ``\x:real. inv(c) * x``] THEN 16180 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CMUL, CONTINUOUS_ON_ID, FORALL_IN_IMAGE] THEN 16181 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_RINV] THEN 16182 SIMP_TAC std_ss [REAL_MUL_LID, IN_IMAGE, REAL_MUL_LID] THEN MESON_TAC[]); 16183 16184val HOMEOMORPHIC_TRANSLATION = store_thm ("HOMEOMORPHIC_TRANSLATION", 16185 ``!s a:real. s homeomorphic (IMAGE (\x. a + x) s)``, 16186 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 16187 MAP_EVERY EXISTS_TAC [``\x:real. a + x``, ``\x:real. -a + x``] THEN 16188 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID] THEN 16189 SIMP_TAC std_ss [REAL_ADD_ASSOC, REAL_ADD_LINV, REAL_ADD_RINV, 16190 FORALL_IN_IMAGE, REAL_ADD_LID] THEN 16191 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]); 16192 16193val HOMEOMORPHIC_AFFINITY = store_thm ("HOMEOMORPHIC_AFFINITY", 16194 ``!s a:real c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. a + c * x) s)``, 16195 REPEAT STRIP_TAC THEN 16196 MATCH_MP_TAC HOMEOMORPHIC_TRANS THEN 16197 EXISTS_TAC ``IMAGE (\x:real. c * x) s`` THEN 16198 ASM_SIMP_TAC std_ss [HOMEOMORPHIC_SCALING] THEN 16199 SUBGOAL_THEN ``(\x:real. a + c * x) = (\x. a + x) o (\x. c * x)`` 16200 SUBST1_TAC THENL [REWRITE_TAC[o_DEF], ALL_TAC] THEN 16201 SIMP_TAC std_ss [IMAGE_COMPOSE, HOMEOMORPHIC_TRANSLATION]); 16202 16203val HOMEOMORPHIC_BALLS_CBALL_SPHERE = store_thm ("HOMEOMORPHIC_BALLS_CBALL_SPHERE", 16204 ``(!a:real b:real d e. 16205 &0 < d /\ &0 < e ==> ball(a,d) homeomorphic ball(b,e)) /\ 16206 (!a:real b:real d e. 16207 &0 < d /\ &0 < e ==> cball(a,d) homeomorphic cball(b,e)) /\ 16208 (!a:real b:real d e. 16209 &0 < d /\ &0 < e ==> sphere(a,d) homeomorphic sphere(b,e))``, 16210 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 16211 EXISTS_TAC ``\x:real. b + (e / d) * (x - a)`` THEN 16212 EXISTS_TAC ``\x:real. a + (d / e) * (x - b)`` THEN 16213 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_SUB, CONTINUOUS_ON_CMUL, 16214 CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID, IN_BALL, IN_CBALL, IN_SPHERE] THEN 16215 REWRITE_TAC[dist, REAL_ARITH ``a - (a + b) = -b:real``, ABS_NEG] THEN 16216 REWRITE_TAC[real_div, REAL_ARITH 16217 ``a + d * ((b + e * (x - a)) - b) = (&1 - d * e) * a + (d * e) * x:real``] THEN 16218 ONCE_REWRITE_TAC[REAL_ARITH 16219 ``(e * d') * (d * e') = (d * d') * (e * e':real)``] THEN 16220 ASM_SIMP_TAC std_ss [REAL_MUL_RINV, REAL_LT_IMP_NE, REAL_MUL_LID, REAL_SUB_REFL] THEN 16221 REWRITE_TAC[ABS_MUL, REAL_MUL_LZERO, REAL_MUL_LID, REAL_ADD_LID] THEN 16222 ASM_SIMP_TAC std_ss [ABS_MUL, ABS_INV, REAL_ARITH 16223 ``&0 < x ==> (abs x = x:real)``, REAL_LT_IMP_NE] THEN 16224 GEN_REWR_TAC(BINOP_CONV o BINDER_CONV o funpow 2 RAND_CONV) 16225 [GSYM REAL_MUL_RID] THEN 16226 ONCE_REWRITE_TAC[REAL_ARITH ``(a * b) * c = (a * c) * b:real``] THEN 16227 ASM_SIMP_TAC std_ss [REAL_LE_LMUL, GSYM real_div, REAL_LE_LDIV_EQ, REAL_MUL_LID, 16228 GSYM REAL_MUL_ASSOC, REAL_LT_LMUL, REAL_LT_LDIV_EQ, ABS_SUB] THEN 16229 ASM_SIMP_TAC std_ss [REAL_DIV_REFL, REAL_LT_IMP_NE, REAL_MUL_RID]); 16230 16231val HOMEOMORPHIC_BALLS = store_thm ("HOMEOMORPHIC_BALLS", 16232 ``(!a:real b:real d e. 16233 &0 < d /\ &0 < e ==> ball(a,d) homeomorphic ball(b,e))``, 16234 REWRITE_TAC [HOMEOMORPHIC_BALLS_CBALL_SPHERE]); 16235 16236val HOMEOMORPHIC_CBALL = store_thm ("HOMEOMORPHIC_CBALL", 16237 ``(!a:real b:real d e. 16238 &0 < d /\ &0 < e ==> cball(a,d) homeomorphic cball(b,e))``, 16239 REWRITE_TAC [HOMEOMORPHIC_BALLS_CBALL_SPHERE]); 16240 16241val HOMEOMORPHIC_SPHERE = store_thm ("HOMEOMORPHIC_SPHERE", 16242 ``(!a:real b:real d e. 16243 &0 < d /\ &0 < e ==> sphere(a,d) homeomorphic sphere(b,e))``, 16244 REWRITE_TAC [HOMEOMORPHIC_BALLS_CBALL_SPHERE]); 16245 16246(* ------------------------------------------------------------------------- *) 16247(* Homeomorphism of one-point compactifications. *) 16248(* ------------------------------------------------------------------------- *) 16249 16250val HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS = store_thm ("HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS", 16251 ``!s:real->bool t:real->bool a b. 16252 compact s /\ compact t /\ a IN s /\ b IN t /\ 16253 (s DELETE a) homeomorphic (t DELETE b) 16254 ==> s homeomorphic t``, 16255 REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN 16256 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [homeomorphic]) THEN 16257 SIMP_TAC std_ss [HOMEOMORPHISM, LEFT_IMP_EXISTS_THM] THEN 16258 MAP_EVERY X_GEN_TAC [``f:real->real``, ``g:real->real``] THEN 16259 STRIP_TAC THEN 16260 EXISTS_TAC ``\x. if x = a then b else (f:real->real) x`` THEN 16261 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 16262 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 16263 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 16264 ASM_CASES_TAC ``x:real = a`` THEN ASM_REWRITE_TAC[] THENL 16265 [REWRITE_TAC[continuous_within] THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 16266 MP_TAC(ISPECL [``b:real``, ``e:real``] CENTRE_IN_BALL) THEN 16267 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 16268 SUBGOAL_THEN 16269 ``closed_in (subtopology euclidean s) 16270 { x | x IN (s DELETE a) /\ 16271 (f:real->real)(x) IN t DIFF ball(b,e)}`` 16272 MP_TAC THENL 16273 [MATCH_MP_TAC CLOSED_SUBSET THEN CONJ_TAC THENL [SET_TAC[], ALL_TAC] THEN 16274 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN SUBGOAL_THEN 16275 ``{x | x IN s DELETE a /\ f x IN t DIFF ball(b,e)} = 16276 IMAGE (g:real->real) (t DIFF ball (b,e))`` 16277 SUBST1_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 16278 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN 16279 ASM_SIMP_TAC std_ss [COMPACT_DIFF, OPEN_BALL] THEN 16280 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 16281 CONTINUOUS_ON_SUBSET)) THEN ASM_SET_TAC[], 16282 REWRITE_TAC[closed_in, open_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 16283 DISCH_THEN(MP_TAC o SPEC ``a:real`` o last o CONJUNCTS) THEN 16284 ASM_SIMP_TAC std_ss [GSPECIFICATION, IN_DIFF, IN_DELETE] THEN 16285 SIMP_TAC std_ss [CONJ_EQ_IMP, DE_MORGAN_THM] THEN 16286 STRIP_TAC THEN EXISTS_TAC ``e':real`` THEN 16287 ASM_REWRITE_TAC[] THEN GEN_TAC THEN COND_CASES_TAC THEN 16288 ASM_REWRITE_TAC[DIST_REFL] THEN 16289 GEN_REWR_TAC (RAND_CONV o RAND_CONV o LAND_CONV) [DIST_SYM] THEN 16290 RULE_ASSUM_TAC(REWRITE_RULE[IN_BALL]) THEN ASM_SET_TAC[]], 16291 UNDISCH_TAC ``(f:real->real) continuous_on (s DELETE a)`` THEN 16292 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 16293 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[IN_DELETE] THEN 16294 REWRITE_TAC[continuous_within] THEN 16295 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN 16296 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[IN_DELETE] THEN 16297 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 16298 EXISTS_TAC ``min d (dist(a:real,x))`` THEN 16299 ASM_SIMP_TAC std_ss [REAL_LT_MIN, GSYM DIST_NZ] THEN 16300 METIS_TAC[REAL_LT_REFL]]); 16301 16302(* ------------------------------------------------------------------------- *) 16303(* Homeomorphisms between open intervals in real and then in real. *) 16304(* Could prove similar things for closed intervals, but they drop out of *) 16305(* later stuff in "convex.ml" even more easily. *) 16306(* ------------------------------------------------------------------------- *) 16307 16308val HOMEOMORPHIC_OPEN_INTERVALS = store_thm ("HOMEOMORPHIC_OPEN_INTERVALS", 16309 ``!a b c d. 16310 a < b /\ c < d 16311 ==> interval(a,b) homeomorphic interval(c,d)``, 16312 SUBGOAL_THEN 16313 ``!a b. a < b 16314 ==> interval(0:real,1) homeomorphic interval(a,b)`` 16315 ASSUME_TAC THENL 16316 [REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 16317 EXISTS_TAC ``(\x. a + x * (b - a)):real->real`` THEN 16318 EXISTS_TAC ``(\x. inv(b - a) * (x - a)):real->real`` THEN 16319 ASM_SIMP_TAC std_ss [IN_INTERVAL] THEN 16320 REWRITE_TAC[METIS [REAL_MUL_SYM, GSYM real_div] ``inv b * a:real = a / b``] THEN 16321 ASM_SIMP_TAC std_ss [REAL_LT_LDIV_EQ, REAL_LT_RDIV_EQ, REAL_SUB_LT, 16322 REAL_LT_ADDR, REAL_EQ_LDIV_EQ, REAL_DIV_RMUL, REAL_LT_IMP_NE, 16323 REAL_LT_MUL, REAL_MUL_LZERO, REAL_ADD_SUB, REAL_LT_RMUL, 16324 REAL_ARITH ``a + x < b <=> x < &1 * (b - a:real)``] THEN 16325 REPEAT CONJ_TAC THENL 16326 [REAL_ARITH_TAC, 16327 ONCE_REWRITE_TAC [METIS [] ``(\x. a + x * (b - a)) = 16328 (\x. (\x. a) x + (\x. x * (b - a)) x:real)``] THEN 16329 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN 16330 ONCE_REWRITE_TAC [METIS [] ``(\x. x * (b - a)) = 16331 (\x. (\x. x) x * (\x. (b - a)) x:real)``] THEN 16332 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN 16333 REWRITE_TAC[o_DEF, CONTINUOUS_ON_ID, CONTINUOUS_ON_CONST], 16334 ONCE_REWRITE_TAC [METIS [real_div, REAL_MUL_SYM] ``(\x. (x - a) / (b - a)) = 16335 (\x. inv(b - a) * (\x. (x - a)) x:real)``] THEN 16336 MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN 16337 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID]], 16338 REPEAT STRIP_TAC THEN 16339 FIRST_ASSUM(MP_TAC o SPECL [``a:real``, ``b:real``]) THEN 16340 FIRST_X_ASSUM(MP_TAC o SPECL [``c:real``, ``d:real``]) THEN 16341 ASM_REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN 16342 GEN_REWR_TAC (LAND_CONV o LAND_CONV) [HOMEOMORPHIC_SYM] THEN 16343 REWRITE_TAC[HOMEOMORPHIC_TRANS]]); 16344 16345val HOMEOMORPHIC_OPEN_INTERVAL_UNIV = store_thm ("HOMEOMORPHIC_OPEN_INTERVAL_UNIV", 16346 ``!a b. a < b ==> interval(a,b) homeomorphic univ(:real)``, 16347 REPEAT STRIP_TAC THEN 16348 MP_TAC(SPECL [``a:real``, ``b:real``, ``-1:real``, ``1:real``] 16349 HOMEOMORPHIC_OPEN_INTERVALS) THEN 16350 ASM_REWRITE_TAC[] THEN REWRITE_TAC [REAL_ARITH ``-1 < 1:real``] THEN 16351 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMEOMORPHIC_TRANS) THEN 16352 POP_ASSUM_LIST(K ALL_TAC) THEN 16353 REWRITE_TAC[HOMEOMORPHIC_MINIMAL, IN_UNIV] THEN 16354 EXISTS_TAC ``\x:real. inv(&1 - abs x) * x`` THEN 16355 EXISTS_TAC ``\y:real. if &0 <= y then inv(&1 + y) * y 16356 else inv(&1 - y) * y`` THEN 16357 SIMP_TAC std_ss [] THEN REPEAT CONJ_TAC THENL 16358 [X_GEN_TAC ``x:real`` THEN REWRITE_TAC[IN_INTERVAL] THEN 16359 SIMP_TAC std_ss [REAL_LE_MUL, REAL_LT_INV_EQ, REAL_LE_MUL, REAL_ARITH 16360 ``-a < x /\ x < a ==> &0 < a - abs x:real``] THEN 16361 SIMP_TAC std_ss [abs, REAL_MUL_ASSOC] THEN 16362 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN 16363 GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN 16364 AP_THM_TAC THEN AP_TERM_TAC THEN COND_CASES_TAC THEN 16365 (Cases_on `x = 0:real` THENL 16366 [ASM_REWRITE_TAC [REAL_INV1, REAL_NEG_0, REAL_SUB_RZERO, 16367 REAL_ADD_RID, REAL_MUL_RZERO] THEN REAL_ARITH_TAC, ALL_TAC]) THEN 16368 (KNOW_TAC ``!y. y <> 0:real ==> ((1 + inv y * x) = (y + x) / y:real) /\ 16369 ((1 - inv y * x) = (y - x) / y:real)`` THENL 16370 [ASM_SIMP_TAC real_ss [real_div, REAL_ADD_RDISTRIB, REAL_MUL_RINV, REAL_SUB_RDISTRIB] THEN 16371 REAL_ARITH_TAC, STRIP_TAC] THEN 16372 KNOW_TAC ``(1 - x) <> 0 /\ (1 - -x) <> 0:real`` THENL 16373 [METIS_TAC [REAL_ARITH ``x < 1 ==> 1 - x <> 0:real``, 16374 REAL_ARITH ``-1 < x ==> 1 - -x <> 0:real``], 16375 STRIP_TAC] THEN ASM_SIMP_TAC real_ss []) THENL 16376 [METIS_TAC [REAL_INV_1OVER, REAL_MUL_RINV, REAL_INV_INV], 16377 FULL_SIMP_TAC real_ss [REAL_LT_IMP_LE] THEN 16378 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_MUL_SYM]) THEN 16379 FULL_SIMP_TAC real_ss [GSYM real_div, REAL_LE_RDIV_EQ, 16380 REAL_ARITH ``(-1 < x) = (0 < 1 + x:real)``], 16381 FULL_SIMP_TAC real_ss [REAL_LT_IMP_LE, REAL_NOT_LE] THEN 16382 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_MUL_SYM]) THEN 16383 FULL_SIMP_TAC real_ss [GSYM real_div, REAL_LT_LDIV_EQ, 16384 REAL_ARITH ``(x < 1) = (0 < 1 - x:real)``] THEN 16385 METIS_TAC [REAL_ARITH ``~(x < 0 /\ 0 <= x:real)``], 16386 FULL_SIMP_TAC real_ss [] THEN 16387 METIS_TAC [REAL_INV_1OVER, REAL_MUL_RINV, REAL_INV_INV]], 16388 X_GEN_TAC ``y:real`` THEN COND_CASES_TAC THEN 16389 ASM_SIMP_TAC real_ss [IN_INTERVAL, REAL_BOUNDS_LT] THEN 16390 ASM_SIMP_TAC real_ss [ABS_MUL, ABS_INV, REAL_ARITH 16391 ``(0 <= y ==> 1 + y <> 0:real) /\ (~(0 <= y) ==> 1 - y <> 0:real)``] THEN 16392 REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div)] THEN 16393 ASM_SIMP_TAC real_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``&0 <= x ==> &0 < abs(&1 + x:real)``, 16394 REAL_ARITH ``~(&0 <= x) ==> &0 < abs(&1 - x:real)``] THEN 16395 (CONJ_TAC THENL [ASM_REAL_ARITH_TAC, ALL_TAC]) THEN 16396 REWRITE_TAC [real_div] THEN 16397 ONCE_REWRITE_TAC [REAL_ARITH ``a * b * c = c * b * a:real``] THEN 16398 REWRITE_TAC[REAL_MUL_ASSOC] THEN REWRITE_TAC[ABS_MUL] THEN 16399 ASM_REWRITE_TAC[abs, REAL_LE_INV_EQ] THEN 16400 ASM_SIMP_TAC real_ss [REAL_ARITH ``&0 <= x ==> &0 <= &1 + x:real``, 16401 REAL_ARITH ``~(&0 <= x) ==> &0 <= &1 - x:real``] THEN 16402 GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN 16403 AP_THM_TAC THEN AP_TERM_TAC THEN 16404 (KNOW_TAC ``!x. x <> 0:real ==> ((1 + y * inv x) = (x + y) / x:real) /\ 16405 ((1 - y * inv x) = (x - y) / x:real)`` THENL 16406 [ASM_SIMP_TAC real_ss [real_div, REAL_ADD_RDISTRIB, REAL_MUL_RINV, REAL_SUB_RDISTRIB], 16407 STRIP_TAC]) THENL 16408 [KNOW_TAC ``(1 + y) <> 0:real`` THENL 16409 [METIS_TAC [REAL_ARITH ``(0 <= x) ==> 1 + x <> 0:real``], 16410 STRIP_TAC] THEN ASM_SIMP_TAC real_ss [], 16411 KNOW_TAC ``(1 - y) <> 0:real`` THENL 16412 [METIS_TAC [REAL_ARITH ``~(0 <= x) ==> 1 - x <> 0:real``], 16413 STRIP_TAC] THEN ASM_SIMP_TAC real_ss []] THEN 16414 METIS_TAC [REAL_INV_1OVER, REAL_MUL_RINV, REAL_INV_INV], 16415 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 16416 X_GEN_TAC ``x:real`` THEN 16417 REWRITE_TAC[IN_INTERVAL] THEN DISCH_TAC THEN 16418 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (1 - abs x) * x) = 16419 (\x. (\x. inv (1 - abs x)) x * (\x. x) x:real)``] THEN 16420 MATCH_MP_TAC CONTINUOUS_MUL THEN 16421 REWRITE_TAC[CONTINUOUS_AT_ID] THEN 16422 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (1 - abs x)) = 16423 (\x. inv ((\x. 1 - abs x) x:real))``] THEN 16424 ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN 16425 SIMP_TAC real_ss [NETLIMIT_AT, o_DEF] THEN 16426 CONJ_TAC THENL 16427 [ONCE_REWRITE_TAC [METIS [] 16428 ``(\x. 1 - abs x) = (\x. (\x. 1) x - (\x. abs x) x:real)``] THEN 16429 MATCH_MP_TAC CONTINUOUS_SUB THEN 16430 SIMP_TAC std_ss [CONTINUOUS_CONST] THEN 16431 ONCE_REWRITE_TAC [METIS [] ``(\x. abs x) = (\x. abs ((\x. x) x:real))``] THEN 16432 METIS_TAC [REWRITE_RULE[o_DEF] CONTINUOUS_AT_ABS], ASM_REAL_ARITH_TAC], 16433 SUBGOAL_THEN ``univ(:real) = {x | x >= &0} UNION {x | x <= &0}`` 16434 SUBST1_TAC THENL 16435 [SIMP_TAC std_ss [EXTENSION, IN_UNION, IN_UNION, GSPECIFICATION, IN_UNIV] THEN 16436 REAL_ARITH_TAC, 16437 ONCE_REWRITE_TAC [METIS [] 16438 ``(\y. if 0 <= y then inv (1 + y) * y else inv (1 - y) * y) = 16439 (\y. if (\y. 0 <= y) y then (\y. inv (1 + y) * y) y 16440 else (\y. inv (1 - y) * y) y:real)``] THEN 16441 MATCH_MP_TAC CONTINUOUS_ON_CASES THEN 16442 SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_LE, CLOSED_HALFSPACE_COMPONENT_GE, 16443 GSPECIFICATION] THEN 16444 REWRITE_TAC[REAL_NOT_LE, real_ge, REAL_LET_ANTISYM] THEN 16445 SIMP_TAC std_ss [REAL_LE_ANTISYM, REAL_SUB_RZERO, REAL_ADD_RID] THEN 16446 CONJ_TAC THENL 16447 [MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 16448 X_GEN_TAC ``y:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, real_ge] THEN 16449 DISCH_TAC THEN ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 + y) * y) = 16450 (\y. (\y. inv (1 + y)) y * (\y. y) y:real)``] THEN 16451 MATCH_MP_TAC CONTINUOUS_MUL THEN 16452 REWRITE_TAC[CONTINUOUS_AT_ID] THEN 16453 ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 + y)) = (\y. inv ((\y. (1 + y)) y:real))``] THEN 16454 ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN 16455 SIMP_TAC std_ss [NETLIMIT_AT, o_DEF] THEN 16456 ASM_SIMP_TAC std_ss [CONTINUOUS_ADD, CONTINUOUS_AT_ID, CONTINUOUS_SUB, 16457 CONTINUOUS_CONST] THEN 16458 ASM_REAL_ARITH_TAC, ALL_TAC] THEN CONJ_TAC THENL 16459 [MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 16460 X_GEN_TAC ``y:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, real_ge] THEN 16461 DISCH_TAC THEN ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 - y) * y) = 16462 (\y. (\y. inv (1 - y)) y * (\y. y) y:real)``] THEN 16463 MATCH_MP_TAC CONTINUOUS_MUL THEN 16464 REWRITE_TAC[CONTINUOUS_AT_ID] THEN 16465 ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 - y)) = (\y. inv ((\y. (1 - y)) y:real))``] THEN 16466 ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN 16467 SIMP_TAC std_ss [NETLIMIT_AT, o_DEF] THEN 16468 ASM_SIMP_TAC std_ss [CONTINUOUS_ADD, CONTINUOUS_AT_ID, CONTINUOUS_SUB, 16469 CONTINUOUS_CONST] THEN 16470 ASM_REAL_ARITH_TAC, 16471 REPEAT STRIP_TAC THENL [METIS_TAC [REAL_ARITH ``~(0 <= x /\ x < 0:real)``], 16472 ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC]]]]); 16473 16474(* ------------------------------------------------------------------------- *) 16475(* Cardinality of the reals. This is done in a rather laborious way to avoid *) 16476(* any dependence on the theories of analysis. *) 16477(* ------------------------------------------------------------------------- *) 16478 16479Triviality lemma: 16480 !s m n. sum (s INTER (m..n)) (\i. inv(&3 pow i)) < &3 / &2 / &3 pow m 16481Proof 16482 REPEAT GEN_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 16483 EXISTS_TAC ``sum (m..n) (\i. inv(&3 pow i))`` THEN CONJ_TAC THENL 16484 [ (* goal 1 (of 2) *) 16485 MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN 16486 SIMP_TAC std_ss [FINITE_NUMSEG, INTER_SUBSET, REAL_LE_INV_EQ, 16487 POW_POS, REAL_POS], 16488 (* goal 2 (of 2) *) 16489 completeInduct_on `n - m:num` THEN GEN_TAC THEN GEN_TAC THEN 16490 DISCH_TAC THEN FULL_SIMP_TAC std_ss [] THEN POP_ASSUM K_TAC THEN 16491 KNOW_TAC ``(!m'. m' < n - m ==> 16492 !n m''. (m' = n - m'') ==> 16493 sum (m'' .. n) (\i. inv (3 pow i)) < 3 / 2 / 3 pow m'') ==> 16494 (!n' m''. (n' - m'' < n - m) ==> 16495 sum (m'' .. n') (\i. inv (3 pow i)) < 3 / 2 / 3 pow m'')`` THENL 16496 [ METIS_TAC [], ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN DISCH_TAC ] THEN 16497 ASM_CASES_TAC ``m:num <= n`` THENL 16498 [ (* goal 2.1 (of 2) *) 16499 ASM_SIMP_TAC std_ss [SUM_CLAUSES_LEFT] THEN ASM_CASES_TAC ``m + 1 <= n:num`` THENL 16500 [ (* goal 2.1.1 (of 2) *) 16501 FIRST_X_ASSUM (MP_TAC o SPECL [``n:num``, ``SUC m``]) THEN 16502 KNOW_TAC ``n - SUC m < n - m`` THENL 16503 [ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 16504 ASM_SIMP_TAC arith_ss [ADD1, REAL_POW_ADD]] THEN 16505 MATCH_MP_TAC (REAL_ARITH 16506 ``a + j:real <= k ==> x < j ==> a + x < k:real``) THEN 16507 KNOW_TAC ``3 pow m <> 0:real`` THENL 16508 [MATCH_MP_TAC POW_NZ THEN REAL_ARITH_TAC, DISCH_TAC] THEN 16509 ASM_SIMP_TAC real_ss [real_div, REAL_INV_MUL, POW_1] THEN 16510 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 16511 GEN_REWR_TAC (LAND_CONV o LAND_CONV) [GSYM REAL_MUL_RID] THEN 16512 REWRITE_TAC [GSYM REAL_ADD_LDISTRIB, GSYM REAL_MUL_ASSOC] THEN 16513 MATCH_MP_TAC REAL_LE_LMUL_IMP THEN CONJ_TAC THENL 16514 [REWRITE_TAC [REAL_LE_INV_EQ] THEN MATCH_MP_TAC POW_POS THEN 16515 REAL_ARITH_TAC, ALL_TAC] THEN REWRITE_TAC [GSYM real_div] THEN 16516 SIMP_TAC real_ss [REAL_LE_RDIV_EQ, REAL_ADD_RDISTRIB, real_div] THEN 16517 REWRITE_TAC [REAL_MUL_ASSOC] THEN SIMP_TAC real_ss [REAL_MUL_LINV], 16518 ALL_TAC], ALL_TAC] THEN 16519 RULE_ASSUM_TAC (REWRITE_RULE[NOT_LESS_EQUAL, GSYM NUMSEG_EMPTY]) THEN 16520 ASM_REWRITE_TAC [SUM_CLAUSES, REAL_ADD_RID] THEN 16521 (KNOW_TAC ``0:real < 3 pow m`` THENL 16522 [MATCH_MP_TAC REAL_POW_LT THEN REAL_ARITH_TAC, DISCH_TAC] THEN 16523 ASM_SIMP_TAC real_ss [REAL_LT_RDIV_EQ, REAL_MUL_LINV, REAL_LT_IMP_NE])] 16524QED 16525 16526Theorem CARD_EQ_REAL: univ(:real) =_c univ(:num->bool) 16527Proof 16528 REWRITE_TAC [GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL 16529 [ (* goal 1 (of 2) *) 16530 KNOW_TAC ``univ(:real) <=_c (univ(:num) *_c univ(:num->bool)) /\ 16531 (univ(:num) *_c univ(:num->bool)) <=_c univ(:num -> bool)`` THENL 16532 [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN 16533 CONJ_TAC THENL 16534 [ALL_TAC, 16535 MATCH_MP_TAC CARD_MUL2_ABSORB_LE THEN REWRITE_TAC[INFINITE_CARD_LE] THEN 16536 SIMP_TAC std_ss [CANTOR_THM_UNIV, CARD_LT_IMP_LE, CARD_LE_REFL]] THEN 16537 `univ(:real) <=_c (univ(:num) *_c {x:real | &0 <= x}) /\ 16538 univ(:num) *_c {x:real | &0 <= x} <=_c univ(:num) *_c univ(:num -> bool)` 16539 suffices_by METIS_TAC[CARD_LE_TRANS] THEN 16540 CONJ_TAC THENL 16541 [SIMP_TAC std_ss [LE_C, mul_c, EXISTS_PROD, IN_ELIM_PAIR_THM, IN_UNIV] THEN 16542 EXISTS_TAC ``\(n,x:real). -(&1) pow n * x`` THEN X_GEN_TAC ``x:real`` THEN 16543 `?p_2. (p_2 IN {x | 0r <= x} /\ ((\ (n,x). -1 pow n * x) (0,p_2) = x)) \/ 16544 (p_2 IN {x | 0r <= x} /\ ((\ (n,x). -1 pow n * x) (1,p_2) = x))` 16545 suffices_by METIS_TAC[OR_EXISTS_THM] THEN EXISTS_TAC ``abs x:real`` THEN 16546 SIMP_TAC std_ss [GSPECIFICATION, pow, POW_1] THEN REAL_ARITH_TAC, 16547 ALL_TAC] THEN 16548 MATCH_MP_TAC CARD_LE_MUL THEN SIMP_TAC std_ss [CARD_LE_REFL] THEN 16549 MP_TAC(ISPECL [``univ(:num)``, ``univ(:num)``] CARD_MUL_ABSORB_LE) THEN 16550 SIMP_TAC std_ss [CARD_LE_REFL, num_INFINITE] THEN 16551 SIMP_TAC std_ss [le_c, mul_c, IN_UNIV, FORALL_PROD, IN_ELIM_PAIR_THM] THEN 16552 REWRITE_TAC [GSYM PAIR_EQ] THEN 16553 SIMP_TAC std_ss [GSYM FORALL_PROD, INJECTIVE_LEFT_INVERSE] THEN 16554 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] 16555 16556 THEN 16557 MAP_EVERY X_GEN_TAC [``Pair:num#num->num``, ``Unpair:num->num#num``] THEN 16558 DISCH_TAC THEN 16559 EXISTS_TAC ``\x:real n:num. &(FST(Unpair n)) * x <= &(SND(Unpair n))`` THEN 16560 SIMP_TAC std_ss [] THEN 16561 HO_MATCH_MP_TAC REAL_WLOG_LT THEN 16562 SIMP_TAC std_ss [GSPECIFICATION, FUN_EQ_THM] THEN 16563 CONJ_TAC THENL [SIMP_TAC std_ss [EQ_SYM_EQ, CONJ_ACI], ALL_TAC] THEN 16564 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN REPEAT STRIP_TAC THEN 16565 FIRST_X_ASSUM(MP_TAC o GENL [``p:num``, ``q:num``] o 16566 SPEC ``(Pair:num#num->num) (p,q)``) THEN 16567 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN 16568 MP_TAC(SPEC ``y - x:real`` REAL_ARCH) THEN 16569 ASM_SIMP_TAC std_ss [REAL_SUB_LT, NOT_FORALL_THM] THEN 16570 DISCH_THEN(MP_TAC o SPEC ``&2:real``) THEN 16571 DISCH_THEN (X_CHOOSE_TAC ``p:num``) THEN EXISTS_TAC ``p:num`` THEN 16572 MP_TAC(ISPEC ``&p * x:real`` REAL_BIGNUM) THEN 16573 ONCE_REWRITE_TAC [METIS [] ``(?n. &p * x < &n:real) = (?n. (\n. &p * x < &n) n)``] THEN 16574 DISCH_THEN (MP_TAC o MATCH_MP WOP) THEN SIMP_TAC std_ss [] THEN 16575 DISCH_THEN (X_CHOOSE_TAC ``n:num``) THEN EXISTS_TAC ``n:num`` THEN 16576 POP_ASSUM MP_TAC THEN SPEC_TAC (``n:num``,``n:num``) THEN 16577 KNOW_TAC ``!n. (\n. &p * x < &n:real /\ (!m. m < n ==> ~(&p * x < &m)) ==> 16578 ~(&p * x <= &n <=> &p * y <= &n:real)) n`` THENL 16579 [ALL_TAC, METIS_TAC []] THEN MATCH_MP_TAC INDUCTION THEN 16580 16581 ASM_SIMP_TAC std_ss [REAL_LE_MUL, REAL_POS, 16582 REAL_ARITH ``x:real < &0 <=> ~(&0 <= x)``] 16583 16584 THEN 16585 X_GEN_TAC ``q:num`` THEN REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN 16586 DISCH_THEN(K ALL_TAC) THEN STRIP_TAC THEN 16587 FIRST_X_ASSUM(MP_TAC o SPEC ``q:num``) THEN 16588 SIMP_TAC arith_ss [LT] THEN POP_ASSUM MP_TAC THEN 16589 POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN 16590 POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC, 16591 16592 (* goal 2 (of 2) *) 16593 REWRITE_TAC[le_c, IN_UNIV] THEN 16594 EXISTS_TAC ``\s:num->bool. sup { sum (s INTER ((0:num)..n)) (\i. inv(&3 pow i)) | 16595 n IN univ(:num) }`` THEN 16596 MAP_EVERY X_GEN_TAC [``x:num->bool``, ``y:num->bool``] THEN 16597 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 16598 SIMP_TAC std_ss [EXTENSION, NOT_FORALL_THM] THEN 16599 ONCE_REWRITE_TAC [METIS [] ``(?x':num. x' IN x <=/=> x' IN y) = 16600 (?x'. (\x'. x' IN x <=/=> x' IN y) x')``] THEN 16601 DISCH_THEN (MP_TAC o MATCH_MP WOP) THEN SIMP_TAC std_ss [] THEN 16602 MAP_EVERY (fn w => SPEC_TAC(w,w)) [``y:num->bool``, ``x:num->bool``] THEN 16603 KNOW_TAC ``!x y. 16604 (?n. ~(n IN x <=> n IN y) /\ (\x y n. !m. m < n ==> (m IN x <=> m IN y)) x y n) ==> 16605 (\x y. sup {sum (x INTER (0 .. n)) (\i. inv (3 pow i)) | n IN univ(:num)} <> 16606 sup {sum (y INTER (0 .. n)) (\i. inv (3 pow i)) | n IN univ(:num)}) x y`` THENL 16607 [ALL_TAC, METIS_TAC []] THEN 16608 MATCH_MP_TAC(MESON[] 16609 ``((!P Q n. R P Q n <=> R Q P n) /\ (!P Q. SS P Q <=> SS Q P)) /\ 16610 (!P Q. (?n. n IN P /\ ~(n IN Q) /\ R P Q n) ==> SS P Q) 16611 ==> !P Q. (?n:num. ~(n IN P <=> n IN Q) /\ R P Q n) ==> SS P Q``) THEN 16612 SIMP_TAC std_ss [] THEN CONJ_TAC THENL 16613 [ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN METIS_TAC [], SIMP_TAC std_ss []] THEN 16614 MAP_EVERY X_GEN_TAC [``x:num->bool``, ``y:num->bool``] THEN 16615 DISCH_THEN(X_CHOOSE_THEN ``n:num`` STRIP_ASSUME_TAC) THEN 16616 MATCH_MP_TAC(REAL_ARITH ``!z:real. y < z /\ z <= x ==> ~(x = y)``) THEN 16617 16618 EXISTS_TAC ``sum (x INTER ((0:num)..n)) (\i. inv(&3 pow i))`` THEN CONJ_TAC THENL 16619 [ (* goal 2.1 (of 2) *) 16620 MATCH_MP_TAC REAL_LET_TRANS THEN 16621 EXISTS_TAC 16622 ``sum (y INTER ((0:num)..n)) (\i. inv(&3 pow i)) + 16623 &3 / &2 / &3 pow (SUC n)`` THEN 16624 16625 CONJ_TAC THENL 16626 [MATCH_MP_TAC REAL_SUP_LE' THEN 16627 CONJ_TAC THENL [SET_TAC[], SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV]] THEN 16628 X_GEN_TAC ``p:num`` THEN ASM_CASES_TAC ``n:num <= p`` THENL 16629 [MATCH_MP_TAC(REAL_ARITH 16630 ``!d. (s:real = t + d) /\ d <= e ==> s <= t + e``) THEN 16631 EXISTS_TAC ``sum(y INTER (n+(1:num)..p)) (\i. inv (&3 pow i))`` THEN 16632 CONJ_TAC THENL 16633 [ONCE_REWRITE_TAC[INTER_COMM] THEN 16634 SIMP_TAC std_ss [INTER_DEF, SUM_RESTRICT_SET] THEN 16635 ASM_SIMP_TAC std_ss [SUM_COMBINE_R, ZERO_LESS_EQ], 16636 SIMP_TAC std_ss [ADD1, lemma, REAL_LT_IMP_LE]], 16637 MATCH_MP_TAC(REAL_ARITH ``y:real <= x /\ &0 <= d ==> y <= x + d``) THEN 16638 SIMP_TAC real_ss [REAL_LE_DIV, REAL_POS, POW_POS] THEN 16639 MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN 16640 SIMP_TAC real_ss [REAL_LE_INV_EQ, POW_POS, REAL_POS] THEN 16641 SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN MATCH_MP_TAC 16642 (SET_RULE ``s SUBSET t ==> u INTER s SUBSET u INTER t``) THEN 16643 REWRITE_TAC[SUBSET_NUMSEG] THEN ASM_SIMP_TAC arith_ss []], 16644 ONCE_REWRITE_TAC[INTER_COMM] THEN 16645 SIMP_TAC std_ss [INTER_DEF, SUM_RESTRICT_SET] THEN ASM_CASES_TAC ``n = 0:num`` THENL 16646 [FIRST_X_ASSUM SUBST_ALL_TAC THEN 16647 FULL_SIMP_TAC real_ss [SUM_SING, NUMSEG_SING, pow] THEN 16648 SIMP_TAC real_ss [REAL_LT_LDIV_EQ, REAL_INV1] THEN REAL_ARITH_TAC, 16649 ASM_SIMP_TAC std_ss [SUM_CLAUSES_RIGHT, LE_1, ZERO_LESS_EQ, REAL_ADD_RID] THEN 16650 MATCH_MP_TAC(REAL_ARITH ``(s:real = t) /\ d < e ==> s + d < t + e``) THEN 16651 CONJ_TAC THENL 16652 [MATCH_MP_TAC SUM_EQ_NUMSEG THEN 16653 ASM_SIMP_TAC std_ss [ARITH_PROVE ``~(n = 0:num) /\ m <= n - 1 ==> m < n``], 16654 SIMP_TAC real_ss [pow, real_div, REAL_INV_MUL, REAL_MUL_ASSOC] THEN 16655 KNOW_TAC ``3 pow n <> 0:real`` THENL 16656 [MATCH_MP_TAC POW_NZ THEN REAL_ARITH_TAC, DISCH_TAC] THEN 16657 KNOW_TAC ``0:real < 3 pow n`` THENL 16658 [MATCH_MP_TAC REAL_POW_LT THEN REAL_ARITH_TAC, DISCH_TAC] THEN 16659 ASM_SIMP_TAC real_ss [REAL_INV_MUL, REAL_MUL_ASSOC] THEN 16660 GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN 16661 MATCH_MP_TAC REAL_LT_RMUL_IMP THEN ASM_SIMP_TAC real_ss [REAL_LT_INV_EQ] THEN 16662 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 16663 SIMP_TAC real_ss [REAL_MUL_ASSOC, REAL_MUL_LINV] THEN 16664 SIMP_TAC real_ss [REAL_INV_1OVER, REAL_LT_LDIV_EQ]]]], 16665 MP_TAC(ISPEC ``{ sum (x INTER ((0:num)..n)) (\i. inv(&3 pow i)) | n IN univ(:num) }`` 16666 SUP) THEN SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV] THEN 16667 KNOW_TAC ``{sum (x INTER (0 .. n)) (\i. inv (3 pow i)) | n | T} <> {} /\ 16668 (?b. !n. sum (x INTER (0 .. n)) (\i. inv (3 pow i)) <= b)`` THENL 16669 [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 16670 SIMP_TAC std_ss []] THEN 16671 CONJ_TAC THENL [SET_TAC[], ALL_TAC] THEN 16672 EXISTS_TAC ``&3 / &2 / (&3:real) pow 0`` THEN 16673 SIMP_TAC std_ss [lemma, REAL_LT_IMP_LE]] 16674 ] 16675QED 16676 16677val UNCOUNTABLE_REAL = store_thm ("UNCOUNTABLE_REAL", 16678 ``~COUNTABLE univ(:real)``, 16679 REWRITE_TAC[COUNTABLE, ge_c] THEN 16680 KNOW_TAC ``univ(:num) <_c univ(:num->bool) /\ 16681 univ(:num->bool) <=_c univ(:real)`` THENL 16682 [ALL_TAC, METIS_TAC [CARD_LTE_TRANS]] THEN 16683 REWRITE_TAC[CANTOR_THM_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN 16684 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN REWRITE_TAC[CARD_EQ_REAL]); 16685 16686val CARD_EQ_REAL_IMP_UNCOUNTABLE = store_thm ("CARD_EQ_REAL_IMP_UNCOUNTABLE", 16687 ``!s:real->bool. s =_c univ(:real) ==> ~COUNTABLE s``, 16688 GEN_TAC THEN STRIP_TAC THEN 16689 DISCH_THEN (MP_TAC o SPEC ``univ(:real)`` o MATCH_MP 16690 (SIMP_RULE std_ss [CONJ_EQ_IMP] CARD_EQ_COUNTABLE)) THEN 16691 REWRITE_TAC[UNCOUNTABLE_REAL] THEN ASM_MESON_TAC[CARD_EQ_SYM]); 16692 16693(* ------------------------------------------------------------------------- *) 16694(* Cardinalities of various useful sets. *) 16695(* ------------------------------------------------------------------------- *) 16696 16697val CARD_EQ_EUCLIDEAN = store_thm ("CARD_EQ_EUCLIDEAN", 16698 ``univ(:real) =_c univ(:real)``, 16699 REWRITE_TAC [eq_c, IN_UNIV] THEN EXISTS_TAC ``(\x. x:real)`` THEN 16700 METIS_TAC []); 16701 16702val UNCOUNTABLE_EUCLIDEAN = store_thm ("UNCOUNTABLE_EUCLIDEAN", 16703 ``~COUNTABLE univ(:real)``, 16704 MATCH_MP_TAC CARD_EQ_REAL_IMP_UNCOUNTABLE THEN 16705 REWRITE_TAC[CARD_EQ_EUCLIDEAN]); 16706 16707val CARD_EQ_INTERVAL = store_thm ("CARD_EQ_INTERVAL", 16708 ``(!a b:real. ~(interval(a,b) = {}) ==> (interval[a,b] =_c univ(:real))) /\ 16709 (!a b:real. ~(interval(a,b) = {}) ==> (interval(a,b) =_c univ(:real)))``, 16710 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN 16711 ASM_CASES_TAC ``interval(a:real,b) = {}`` THEN ASM_REWRITE_TAC[] THEN 16712 CONJ_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL 16713 [REWRITE_TAC[CARD_LE_UNIV], 16714 KNOW_TAC ``univ(:real) <=_c interval(a:real,b) /\ 16715 interval(a:real,b) <=_c interval [(a,b)]`` THENL 16716 [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN 16717 SIMP_TAC std_ss [CARD_LE_SUBSET, INTERVAL_OPEN_SUBSET_CLOSED], 16718 REWRITE_TAC[CARD_LE_UNIV], 16719 ALL_TAC] THEN 16720 RULE_ASSUM_TAC (REWRITE_RULE [INTERVAL_NE_EMPTY]) THEN 16721 FIRST_X_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_OPEN_INTERVAL_UNIV) THEN 16722 DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN 16723 MESON_TAC[CARD_EQ_IMP_LE, CARD_EQ_SYM]); 16724 16725val UNCOUNTABLE_INTERVAL = store_thm ("UNCOUNTABLE_INTERVAL", 16726 ``(!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval[a,b])) /\ 16727 (!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval(a,b)))``, 16728 SIMP_TAC std_ss [CARD_EQ_REAL_IMP_UNCOUNTABLE, CARD_EQ_INTERVAL]); 16729 16730val COUNTABLE_OPEN_INTERVAL = store_thm ("COUNTABLE_OPEN_INTERVAL", 16731 ``!a b. COUNTABLE(interval(a,b)) <=> (interval(a,b) = {})``, 16732 MESON_TAC[COUNTABLE_EMPTY, UNCOUNTABLE_INTERVAL]); 16733 16734val CARD_EQ_OPEN = store_thm ("CARD_EQ_OPEN", 16735 ``!s:real->bool. open s /\ ~(s = {}) ==> s =_c univ(:real)``, 16736 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL 16737 [REWRITE_TAC[CARD_LE_UNIV], 16738 UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN 16739 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_INTERVAL]) THEN 16740 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 16741 DISCH_THEN(X_CHOOSE_TAC ``c:real``) THEN 16742 DISCH_THEN(MP_TAC o SPEC ``c:real``) THEN 16743 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 16744 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN 16745 ASM_CASES_TAC ``interval(a:real,b) = {}`` THEN 16746 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN STRIP_TAC THEN 16747 KNOW_TAC ``univ(:real) <=_c interval[a:real,b] /\ 16748 interval[a:real,b] <=_c s:real->bool`` THENL 16749 [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN 16750 ASM_SIMP_TAC std_ss [CARD_LE_SUBSET] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN 16751 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC std_ss [CARD_EQ_INTERVAL]]); 16752 16753val UNCOUNTABLE_OPEN = store_thm ("UNCOUNTABLE_OPEN", 16754 ``!s:real->bool. open s /\ ~(s = {}) ==> ~(COUNTABLE s)``, 16755 SIMP_TAC std_ss [CARD_EQ_OPEN, CARD_EQ_REAL_IMP_UNCOUNTABLE]); 16756 16757val CARD_EQ_BALL = store_thm ("CARD_EQ_BALL", 16758 ``!a:real r. &0 < r ==> ball(a,r) =_c univ(:real)``, 16759 SIMP_TAC std_ss [CARD_EQ_OPEN, OPEN_BALL, BALL_EQ_EMPTY, GSYM REAL_NOT_LT]); 16760 16761val CARD_EQ_CBALL = store_thm ("CARD_EQ_CBALL", 16762 ``!a:real r. &0 < r ==> cball(a,r) =_c univ(:real)``, 16763 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL 16764 [REWRITE_TAC[CARD_LE_UNIV], 16765 KNOW_TAC ``univ(:real) <=_c ball(a:real,r) /\ 16766 ball(a:real,r) <=_c cball (a,r:real)`` THENL 16767 [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN 16768 SIMP_TAC std_ss [CARD_LE_SUBSET, BALL_SUBSET_CBALL] THEN 16769 MATCH_MP_TAC CARD_EQ_IMP_LE THEN 16770 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC std_ss [CARD_EQ_BALL]]); 16771 16772val FINITE_IMP_NOT_OPEN = store_thm ("FINITE_IMP_NOT_OPEN", 16773 ``!s:real->bool. FINITE s /\ ~(s = {}) ==> ~(open s)``, 16774 MESON_TAC[UNCOUNTABLE_OPEN, FINITE_IMP_COUNTABLE]); 16775 16776val OPEN_IMP_INFINITE = store_thm ("OPEN_IMP_INFINITE", 16777 ``!s. open s ==> (s = {}) \/ INFINITE s``, 16778 MESON_TAC[FINITE_IMP_NOT_OPEN]); 16779 16780val EMPTY_INTERIOR_FINITE = store_thm ("EMPTY_INTERIOR_FINITE", 16781 ``!s:real->bool. FINITE s ==> (interior s = {})``, 16782 REPEAT STRIP_TAC THEN MP_TAC(ISPEC ``s:real->bool`` OPEN_INTERIOR) THEN 16783 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 16784 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] FINITE_IMP_NOT_OPEN) THEN 16785 MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``s:real->bool`` THEN 16786 ASM_REWRITE_TAC[INTERIOR_SUBSET]); 16787 16788val FINITE_CBALL = store_thm ("FINITE_CBALL", 16789 ``!a:real r. FINITE(cball(a,r)) <=> r <= &0``, 16790 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``r < &0:real`` THEN 16791 ASM_SIMP_TAC std_ss [CBALL_EMPTY, REAL_LT_IMP_LE, FINITE_EMPTY] THEN 16792 ASM_CASES_TAC ``r = &0:real`` THEN 16793 ASM_REWRITE_TAC[CBALL_TRIVIAL, FINITE_SING, REAL_LE_REFL] THEN 16794 EQ_TAC THENL [ALL_TAC, ASM_REAL_ARITH_TAC] THEN 16795 DISCH_THEN(MP_TAC o MATCH_MP EMPTY_INTERIOR_FINITE) THEN 16796 REWRITE_TAC[INTERIOR_CBALL, BALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC); 16797 16798val FINITE_BALL = store_thm ("FINITE_BALL", 16799 ``!a:real r. FINITE(ball(a,r)) <=> r <= &0``, 16800 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``r <= &0:real`` THEN 16801 ASM_SIMP_TAC std_ss [BALL_EMPTY, REAL_LT_IMP_LE, FINITE_EMPTY] THEN 16802 DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[CONJ_EQ_IMP] 16803 FINITE_IMP_NOT_OPEN)) THEN 16804 REWRITE_TAC[OPEN_BALL, BALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC); 16805 16806(* ------------------------------------------------------------------------- *) 16807(* "Iff" forms of constancy of function from connected set into a set that *) 16808(* is smaller than R, or countable, or finite, or disconnected, or discrete. *) 16809(* ------------------------------------------------------------------------- *) 16810 16811val CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ = store_thm 16812 ("CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ", 16813 ``(!s. connected s <=> 16814 !f:real->real t. 16815 f continuous_on s /\ IMAGE f s SUBSET t /\ 16816 (!y. y IN t ==> (connected_component t y = {y})) 16817 ==> ?a. !x. x IN s ==> (f x = a)) /\ 16818 (!s. connected s <=> 16819 !f:real->real. 16820 f continuous_on s /\ 16821 (!x. x IN s 16822 ==> ?e. &0 < e /\ 16823 !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x)) 16824 ==> ?a. !x. x IN s ==> (f x = a)) /\ 16825 (!s. connected s <=> 16826 !f:real->real. 16827 f continuous_on s /\ FINITE(IMAGE f s) 16828 ==> ?a. !x. x IN s ==> (f x = a))``, 16829 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN X_GEN_TAC ``s:real->bool`` THEN 16830 MATCH_MP_TAC(TAUT 16831 `(s ==> t) /\ (t ==> u) /\ (u ==> v) /\ (v ==> s) 16832 ==> (s <=> t) /\ (s <=> u) /\ (s <=> v)`) THEN 16833 REPEAT CONJ_TAC THENL 16834 [REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 16835 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN 16836 FIRST_X_ASSUM(X_CHOOSE_TAC ``x:real`` o 16837 REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 16838 EXISTS_TAC ``(f:real->real) x`` THEN 16839 MATCH_MP_TAC(SET_RULE 16840 ``IMAGE f s SUBSET {a} ==> !y. y IN s ==> (f y = a)``) THEN 16841 FIRST_X_ASSUM(MP_TAC o SPEC ``(f:real->real) x``) THEN 16842 KNOW_TAC ``(f:real->real) x IN t`` THENL 16843 [ASM_SET_TAC [], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 16844 DISCH_THEN(SUBST1_TAC o SYM)] THEN 16845 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN 16846 ASM_SIMP_TAC std_ss [CONNECTED_CONTINUOUS_IMAGE] THEN ASM_SET_TAC [], 16847 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 16848 EXISTS_TAC ``IMAGE (f:real->real) s`` THEN 16849 ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE, SUBSET_REFL] THEN 16850 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 16851 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 16852 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 16853 MATCH_MP_TAC(SET_RULE 16854 ``(!y. y IN s /\ f y IN connected_component (IMAGE f s) a ==> (f y = a)) /\ 16855 connected_component (IMAGE f s) a SUBSET (IMAGE f s) /\ 16856 connected_component (IMAGE f s) a a 16857 ==> (connected_component (IMAGE f s) a = {a})``) THEN 16858 SIMP_TAC std_ss [CONNECTED_COMPONENT_SUBSET, CONNECTED_COMPONENT_REFL_EQ] THEN 16859 ASM_SIMP_TAC std_ss [FUN_IN_IMAGE] THEN X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 16860 MP_TAC(ISPEC ``connected_component (IMAGE (f:real->real) s) (f x)`` 16861 CONNECTED_CLOSED) THEN 16862 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN 16863 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 16864 ASM_REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC 16865 [``cball((f:real->real) x,e / &2)``, 16866 ``univ(:real) DIFF ball((f:real->real) x,e)``] THEN 16867 SIMP_TAC std_ss [GSYM OPEN_CLOSED, OPEN_BALL, CLOSED_CBALL] THEN 16868 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REPEAT CONJ_TAC THENL 16869 [REWRITE_TAC[SUBSET_DEF, IN_CBALL, IN_UNION, IN_DIFF, IN_BALL, IN_UNIV] THEN 16870 ONCE_REWRITE_TAC [METIS [] 16871 ``(dist (f x,x') <= e / 2 \/ ~(dist (f x,x') < e)) = 16872 (\x'. dist (f x,x') <= e / 2 \/ ~(dist (f x,x') < e)) x'``] THEN 16873 MATCH_MP_TAC(MESON[SUBSET_DEF, CONNECTED_COMPONENT_SUBSET] 16874 ``(!x. x IN s ==> P x) 16875 ==> (!x. x IN connected_component s y ==> P x)``) THEN 16876 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN X_GEN_TAC ``z:real`` THEN 16877 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``z:real``) THEN 16878 ASM_SIMP_TAC real_ss [dist, REAL_LE_RDIV_EQ] THEN ASM_REAL_ARITH_TAC, 16879 MATCH_MP_TAC(SET_RULE 16880 ``(!x. x IN s /\ x IN t ==> F) ==> (s INTER t INTER u = {})``) THEN 16881 REWRITE_TAC[IN_BALL, IN_CBALL, IN_DIFF, IN_UNIV] THEN 16882 UNDISCH_TAC ``&0 < e:real`` THEN 16883 ASM_SIMP_TAC real_ss [dist, REAL_LE_RDIV_EQ] THEN REAL_ARITH_TAC, 16884 EXISTS_TAC ``(f:real->real) x`` THEN 16885 ASM_SIMP_TAC std_ss [CENTRE_IN_CBALL, REAL_HALF, REAL_LT_IMP_LE, IN_INTER] THEN 16886 SIMP_TAC std_ss [SPECIFICATION] THEN 16887 ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_REFL_EQ, FUN_IN_IMAGE], 16888 EXISTS_TAC ``(f:real->real) y`` THEN 16889 ASM_REWRITE_TAC[IN_INTER, IN_DIFF, IN_UNIV, IN_BALL, REAL_NOT_LT] THEN 16890 ASM_SIMP_TAC std_ss [ONCE_REWRITE_RULE[DIST_SYM] dist]], 16891 DISCH_TAC THEN X_GEN_TAC ``f:real->real`` THEN 16892 POP_ASSUM (MP_TAC o SPEC ``f:real->real``) THEN 16893 DISCH_THEN(fn th => STRIP_TAC THEN MATCH_MP_TAC th) THEN 16894 ASM_REWRITE_TAC[] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 16895 ASM_CASES_TAC ``IMAGE (f:real->real) s DELETE (f x) = {}`` THENL 16896 [EXISTS_TAC ``&1:real`` THEN REWRITE_TAC[REAL_LT_01] THEN ASM_SET_TAC [], 16897 ALL_TAC] THEN 16898 EXISTS_TAC 16899 ``inf{abs(z - f x) |z| z IN IMAGE (f:real->real) s DELETE (f x)}`` THEN 16900 SIMP_TAC real_ss [GSYM IMAGE_DEF] THEN 16901 ASM_SIMP_TAC std_ss [REAL_LT_INF_FINITE, REAL_INF_LE_FINITE, FINITE_DELETE, 16902 IMAGE_FINITE, IMAGE_EQ_EMPTY] THEN 16903 SIMP_TAC std_ss [FORALL_IN_IMAGE, EXISTS_IN_IMAGE] THEN 16904 SIMP_TAC real_ss [IN_DELETE, GSYM ABS_NZ, REAL_SUB_0, IN_IMAGE] THEN 16905 MESON_TAC[REAL_LE_REFL], 16906 REWRITE_TAC[CONNECTED_CLOSED_IN_EQ] THEN 16907 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 16908 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 16909 MAP_EVERY X_GEN_TAC [``t:real->bool``, ``u:real->bool``] THEN 16910 STRIP_TAC THEN EXISTS_TAC 16911 ``(\x. if x IN t then 0 else 1:real):real->real`` THEN 16912 SIMP_TAC std_ss [NOT_IMP] THEN REPEAT CONJ_TAC THENL 16913 [EXPAND_TAC "s" THEN 16914 ONCE_REWRITE_TAC [METIS [] ``(\x:real. if x IN t then 0 else 1:real) = 16915 (\x. if (\x. x IN t) x then (\x. 0) x else (\x. 1) x)``] THEN 16916 MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN 16917 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CONST] THEN ASM_SET_TAC [], 16918 MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``{0:real;1:real}`` THEN 16919 REWRITE_TAC[FINITE_INSERT, FINITE_EMPTY] THEN SET_TAC[], 16920 SUBGOAL_THEN ``?a b:real. a IN s /\ a IN t /\ b IN s /\ ~(b IN t)`` 16921 STRIP_ASSUME_TAC THENL 16922 [ASM_SET_TAC [], GEN_TAC] THEN CCONTR_TAC THEN 16923 POP_ASSUM (MP_TAC o SIMP_RULE std_ss []) THEN 16924 DISCH_THEN(fn th => MP_TAC(SPEC ``a:real`` th) THEN 16925 MP_TAC(SPEC ``b:real`` th)) THEN 16926 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]]); 16927 16928val CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ = store_thm 16929 ("CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ", 16930 ``(!s. connected s <=> 16931 !f:real->real t. 16932 f continuous_on s /\ IMAGE f s SUBSET t /\ 16933 (!y. y IN t ==> (connected_component t y = {y})) 16934 ==> ?a. !x. x IN s ==> (f x = a))``, 16935 REWRITE_TAC [CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ]); 16936 16937val CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ = store_thm 16938 ("CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ", 16939 ``(!s. connected s <=> 16940 !f:real->real. 16941 f continuous_on s /\ 16942 (!x. x IN s 16943 ==> ?e. &0 < e /\ 16944 !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x)) 16945 ==> ?a. !x. x IN s ==> (f x = a)) ``, 16946 METIS_TAC [CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ]); 16947 16948val CONTINUOUS_FINITE_RANGE_CONSTANT_EQ = store_thm 16949 ("CONTINUOUS_FINITE_RANGE_CONSTANT_EQ", 16950 ``(!s. connected s <=> 16951 !f:real->real. 16952 f continuous_on s /\ FINITE(IMAGE f s) 16953 ==> ?a. !x. x IN s ==> (f x = a))``, 16954 METIS_TAC [CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ]); 16955 16956val CONTINUOUS_DISCONNECTED_RANGE_CONSTANT = store_thm 16957 ("CONTINUOUS_DISCONNECTED_RANGE_CONSTANT", 16958 ``!f:real->real s. 16959 connected s /\ 16960 f continuous_on s /\ IMAGE f s SUBSET t /\ 16961 (!y. y IN t ==> (connected_component t y = {y})) 16962 ==> ?a. !x. x IN s ==> (f x = a)``, 16963 MESON_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ]); 16964 16965val CONTINUOUS_DISCRETE_RANGE_CONSTANT = store_thm 16966 ("CONTINUOUS_DISCRETE_RANGE_CONSTANT", 16967 ``!f:real->real s. 16968 connected s /\ 16969 f continuous_on s /\ 16970 (!x. x IN s 16971 ==> ?e. &0 < e /\ 16972 !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x)) 16973 ==> ?a. !x. x IN s ==> (f x = a)``, 16974 KNOW_TAC ``!s f:real->real. 16975 connected s /\ 16976 f continuous_on s /\ 16977 (!x. x IN s 16978 ==> ?e. &0 < e /\ 16979 !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x)) 16980 ==> ?a. !x. x IN s ==> (f x = a)`` THENL 16981 [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]] THEN 16982 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM, CONJ_EQ_IMP] THEN 16983 SIMP_TAC std_ss [AND_IMP_INTRO, GSYM CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ]); 16984 16985val CONTINUOUS_FINITE_RANGE_CONSTANT = store_thm 16986 ("CONTINUOUS_FINITE_RANGE_CONSTANT", 16987 ``!f:real->real s. 16988 connected s /\ 16989 f continuous_on s /\ 16990 FINITE(IMAGE f s) 16991 ==> ?a. !x. x IN s ==> (f x = a)``, 16992 MESON_TAC[CONTINUOUS_FINITE_RANGE_CONSTANT_EQ]); 16993 16994(* ------------------------------------------------------------------------- *) 16995(* Homeomorphism of hyperplanes. *) 16996(* ------------------------------------------------------------------------- *) 16997 16998val lemma = prove ( 16999 ``~(a = 0) 17000 ==> {x:real | a * x = b} homeomorphic {x:real | x = &0}``, 17001 REPEAT STRIP_TAC THEN SUBGOAL_THEN ``?c:real. a * c = b`` 17002 STRIP_ASSUME_TAC THENL 17003 [EXISTS_TAC ``inv a * b:real`` THEN 17004 ASM_SIMP_TAC real_ss [REAL_MUL_RINV, REAL_MUL_ASSOC], ALL_TAC] THEN 17005 REWRITE_TAC [homeomorphic, homeomorphism] THEN 17006 EXISTS_TAC ``(\x. 0):real->real`` THEN 17007 EXISTS_TAC ``(\x:real. inv a * b:real)`` THEN 17008 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN 17009 SIMP_TAC std_ss [CONTINUOUS_ON_CONST] THEN 17010 REPEAT STRIP_TAC THENL 17011 [ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN 17012 ASM_CASES_TAC ``0 < a:real`` THENL 17013 [ASM_SIMP_TAC real_ss [REAL_EQ_LDIV_EQ] THEN ASM_REAL_ARITH_TAC, ALL_TAC] THEN 17014 FULL_SIMP_TAC real_ss [REAL_NOT_LT, REAL_LE_LT] THENL [ALL_TAC, METIS_TAC []] THEN 17015 KNOW_TAC ``a < 0 ==> 0 < -a:real`` THENL [REAL_ARITH_TAC, ASM_REWRITE_TAC []] THEN 17016 DISCH_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_EQ_NEG] THEN 17017 REWRITE_TAC [real_div, REAL_ARITH ``-(a * b) = a * -b:real``] THEN 17018 ASM_SIMP_TAC std_ss [REAL_NEG_INV, GSYM real_div] THEN 17019 ASM_SIMP_TAC real_ss [REAL_EQ_LDIV_EQ] THEN ASM_REAL_ARITH_TAC, 17020 METIS_TAC [], 17021 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN 17022 ASM_CASES_TAC ``0 < a:real`` THENL 17023 [ASM_SIMP_TAC real_ss [REAL_EQ_RDIV_EQ] THEN ASM_REAL_ARITH_TAC, ALL_TAC] THEN 17024 FULL_SIMP_TAC real_ss [REAL_NOT_LT, REAL_LE_LT] THENL [ALL_TAC, METIS_TAC []] THEN 17025 KNOW_TAC ``a < 0 ==> 0 < -a:real`` THENL [REAL_ARITH_TAC, ASM_REWRITE_TAC []] THEN 17026 DISCH_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_EQ_NEG] THEN 17027 REWRITE_TAC [real_div, REAL_ARITH ``-(a * b) = a * -b:real``] THEN 17028 ASM_SIMP_TAC std_ss [REAL_NEG_INV, GSYM real_div] THEN 17029 ASM_SIMP_TAC real_ss [REAL_EQ_RDIV_EQ] THEN ASM_REAL_ARITH_TAC]); 17030 17031val HOMEOMORPHIC_HYPERPLANES = store_thm ("HOMEOMORPHIC_HYPERPLANES", 17032 ``!a:real b c:real d. 17033 ~(a = 0) /\ ~(c = 0) 17034 ==> {x | a * x = b} homeomorphic {x | c * x = d}``, 17035 REPEAT STRIP_TAC THEN 17036 MATCH_MP_TAC HOMEOMORPHIC_TRANS THEN EXISTS_TAC ``{x:real | x = &0}`` THEN 17037 ASM_SIMP_TAC std_ss [lemma] THEN ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN 17038 ASM_SIMP_TAC std_ss [lemma]); 17039 17040val HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE = store_thm 17041 ("HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE", 17042 ``!a:real b c. 17043 ~(a = 0) 17044 ==> {x | a * x = b} homeomorphic {x:real | x = c}``, 17045 REPEAT STRIP_TAC THEN 17046 SUBGOAL_THEN ``{x:real | x = c} = {x | 1 * x = c}`` SUBST1_TAC 17047 THENL [ASM_SIMP_TAC real_ss [], MATCH_MP_TAC HOMEOMORPHIC_HYPERPLANES] THEN 17048 ASM_SIMP_TAC real_ss []); 17049 17050val HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE = store_thm 17051 ("HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE", 17052 ``!a:real b c. 17053 ~(a = 0) 17054 ==> {x:real | x = c} homeomorphic {x | a * x = b}``, 17055 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN 17056 SIMP_TAC std_ss [HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE]); 17057 17058(* ------------------------------------------------------------------------- *) 17059(* "Isometry" (up to constant bounds) of injective linear map etc. *) 17060(* ------------------------------------------------------------------------- *) 17061 17062val CAUCHY_ISOMETRIC = store_thm ("CAUCHY_ISOMETRIC", 17063 ``!f s e x. 17064 &0 < e /\ subspace s /\ 17065 linear f /\ (!x. x IN s ==> abs(f x) >= e * abs(x)) /\ 17066 (!n. x(n) IN s) /\ cauchy(f o x) 17067 ==> cauchy x``, 17068 REPEAT GEN_TAC THEN REWRITE_TAC[real_ge] THEN 17069 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 17070 SIMP_TAC std_ss [CAUCHY, dist, o_THM] THEN 17071 FIRST_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN 17072 DISCH_THEN(fn th => X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN MP_TAC th) THEN 17073 DISCH_THEN(MP_TAC o SPEC ``d * e:real``) THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL] THEN 17074 METIS_TAC[REAL_LE_RDIV_EQ, REAL_MUL_SYM, REAL_LET_TRANS, SUBSPACE_SUB, 17075 REAL_LT_LDIV_EQ]); 17076 17077val COMPLETE_ISOMETRIC_IMAGE = store_thm ("COMPLETE_ISOMETRIC_IMAGE", 17078 ``!f:real->real s e. 17079 &0 < e /\ subspace s /\ 17080 linear f /\ (!x. x IN s ==> abs(f x) >= e * abs(x)) /\ 17081 complete s 17082 ==> complete(IMAGE f s)``, 17083 REPEAT GEN_TAC THEN SIMP_TAC std_ss [complete, EXISTS_IN_IMAGE] THEN 17084 STRIP_TAC THEN X_GEN_TAC ``g:num->real`` THEN 17085 SIMP_TAC std_ss [IN_IMAGE, SKOLEM_THM, FORALL_AND_THM] THEN 17086 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 17087 DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` MP_TAC) THEN 17088 ONCE_REWRITE_TAC [METIS [] ``(!n. g n = f (x n)) = (!n. g n = (\n. f (x n)) n)``] THEN 17089 GEN_REWR_TAC (LAND_CONV o LAND_CONV) [GSYM FUN_EQ_THM] THEN 17090 REWRITE_TAC[GSYM o_DEF] THEN 17091 DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN 17092 FIRST_X_ASSUM(MP_TAC o SPEC ``x:num->real``) THEN 17093 ASM_MESON_TAC[CAUCHY_ISOMETRIC, LINEAR_CONTINUOUS_AT, 17094 CONTINUOUS_AT_SEQUENTIALLY]); 17095 17096val INJECTIVE_IMP_ISOMETRIC = store_thm ("INJECTIVE_IMP_ISOMETRIC", 17097 ``!f:real->real s. 17098 closed s /\ subspace s /\ 17099 linear f /\ (!x. x IN s /\ (f x = 0) ==> (x = 0)) 17100 ==> ?e. &0 < e /\ !x. x IN s ==> abs(f x) >= e * abs(x)``, 17101 REPEAT STRIP_TAC THEN 17102 ASM_CASES_TAC ``s SUBSET {0 :real}`` THENL 17103 [EXISTS_TAC ``&1:real`` THEN REWRITE_TAC[REAL_LT_01, REAL_MUL_LID, real_ge] THEN 17104 ASM_MESON_TAC[SUBSET_DEF, IN_SING, ABS_0, LINEAR_0, REAL_LE_REFL], 17105 ALL_TAC] THEN 17106 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 17107 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, IN_SING] THEN 17108 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 17109 MP_TAC(ISPECL 17110 [``{(f:real->real) x | x IN s /\ (abs(x) = abs(a:real))}``, 17111 ``0:real``] DISTANCE_ATTAINS_INF) THEN 17112 KNOW_TAC ``closed {(f:real->real) x | x IN s /\ (abs x = abs a)} /\ 17113 {f x | x IN s /\ (abs x = abs a)} <> {}`` THENL 17114 [SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, GSPECIFICATION] THEN 17115 CONJ_TAC THENL [ALL_TAC, METIS_TAC[]] THEN 17116 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 17117 SUBST1_TAC(SET_RULE 17118 ``{f x | x IN s /\ (abs(x) = abs(a:real))} = 17119 IMAGE (f:real->real) (s INTER {x | abs x = abs a})``) THEN 17120 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN 17121 ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON] THEN 17122 MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN 17123 SUBGOAL_THEN 17124 ``{x:real | abs x = abs(a:real)} = frontier(cball(0,abs a))`` 17125 SUBST1_TAC THENL 17126 [ASM_SIMP_TAC real_ss [FRONTIER_CBALL, GSYM ABS_NZ, dist, REAL_SUB_LZERO, 17127 ABS_NEG, sphere], 17128 ASM_SIMP_TAC std_ss [COMPACT_FRONTIER, COMPACT_CBALL]], 17129 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 17130 ONCE_REWRITE_TAC [METIS [] ``{(f:real->real) x | x IN s /\ (abs x = abs a)} = 17131 {f x | (\x. x IN s /\ (abs x = abs a)) x}``] THEN 17132 ONCE_REWRITE_TAC[SET_RULE ``{f x | P x} = IMAGE f {x | P x}``] THEN 17133 SIMP_TAC std_ss [FORALL_IN_IMAGE, EXISTS_IN_IMAGE] THEN 17134 DISCH_THEN(X_CHOOSE_THEN ``b:real`` MP_TAC) THEN 17135 SIMP_TAC std_ss [GSPECIFICATION, dist, REAL_SUB_LZERO, ABS_NEG] THEN 17136 STRIP_TAC THEN SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_APPROACHABLE] THEN 17137 EXISTS_TAC ``abs((f:real->real) b) / abs(b)`` THEN CONJ_TAC THENL 17138 [ASM_MESON_TAC[REAL_LT_DIV, GSYM ABS_NZ, ABS_ZERO], ALL_TAC] THEN 17139 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 17140 ASM_CASES_TAC ``x:real = 0`` THENL 17141 [FIRST_ASSUM(fn th => ASM_REWRITE_TAC[MATCH_MP LINEAR_0 th]) THEN 17142 REWRITE_TAC[ABS_0, REAL_MUL_RZERO, real_ge, REAL_LE_REFL], 17143 ALL_TAC] THEN 17144 FIRST_X_ASSUM(MP_TAC o SPEC ``(abs(a:real) / abs(x)) * x:real``) THEN 17145 KNOW_TAC ``abs a / abs x * x IN s /\ (abs (abs a / abs x * x) = abs a:real)`` THENL 17146 [KNOW_TAC ``(abs x <> 0:real) /\ (abs a <> 0:real)`` THENL 17147 [UNDISCH_TAC ``a <> 0:real`` THEN POP_ASSUM MP_TAC THEN 17148 REAL_ARITH_TAC, STRIP_TAC] THEN 17149 ASM_SIMP_TAC real_ss [ABS_MUL, ABS_DIV, ABS_ABS] THEN 17150 FULL_SIMP_TAC std_ss [subspace] THEN 17151 ASM_SIMP_TAC real_ss [REAL_DIV_RMUL, ABS_ZERO], 17152 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 17153 UNDISCH_TAC ``linear f`` THEN DISCH_TAC THEN 17154 FIRST_ASSUM(fn th => SIMP_TAC std_ss [MATCH_MP LINEAR_CMUL th]) THEN 17155 KNOW_TAC ``(abs x <> 0:real) /\ (abs a <> 0:real)`` THENL 17156 [UNDISCH_TAC ``a <> 0:real`` THEN UNDISCH_TAC ``x <> 0:real`` THEN 17157 REAL_ARITH_TAC, STRIP_TAC] THEN 17158 ASM_SIMP_TAC real_ss [ABS_MUL, ABS_DIV, ABS_ABS, real_ge] THEN 17159 ASM_SIMP_TAC real_ss [GSYM REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ, GSYM ABS_NZ] THEN 17160 SIMP_TAC std_ss [real_div, REAL_MUL_ASSOC] THEN REAL_ARITH_TAC); 17161 17162val CLOSED_INJECTIVE_IMAGE_SUBSPACE = store_thm ("CLOSED_INJECTIVE_IMAGE_SUBSPACE", 17163 ``!f s. subspace s /\ 17164 linear f /\ 17165 (!x. x IN s /\ (f(x) = 0) ==> (x = 0)) /\ 17166 closed s 17167 ==> closed(IMAGE f s)``, 17168 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED] THEN 17169 MATCH_MP_TAC COMPLETE_ISOMETRIC_IMAGE THEN 17170 ASM_SIMP_TAC std_ss [COMPLETE_EQ_CLOSED] THEN 17171 MATCH_MP_TAC INJECTIVE_IMP_ISOMETRIC THEN 17172 ASM_REWRITE_TAC[]); 17173 17174(* ------------------------------------------------------------------------- *) 17175(* Relating linear images to open/closed/interior/closure. *) 17176(* ------------------------------------------------------------------------- *) 17177 17178val OPEN_SURJECTIVE_LINEAR_IMAGE = store_thm ("OPEN_SURJECTIVE_LINEAR_IMAGE", 17179 ``!f:real->real. 17180 linear f /\ (!y. ?x. f x = y) 17181 ==> !s. open s ==> open(IMAGE f s)``, 17182 GEN_TAC THEN STRIP_TAC THEN 17183 SIMP_TAC std_ss [open_def, FORALL_IN_IMAGE] THEN 17184 FIRST_ASSUM(MP_TAC o GEN ``k:num`` o SPEC ``if (1 = k:num) then &1 else &0:real``) THEN 17185 SIMP_TAC std_ss [SKOLEM_THM] THEN 17186 DISCH_THEN(X_CHOOSE_THEN ``b:num->real`` STRIP_ASSUME_TAC) THEN 17187 SUBGOAL_THEN ``bounded(IMAGE (b:num->real) ((1:num)..(1:num)))`` MP_TAC THENL 17188 [SIMP_TAC std_ss [FINITE_IMP_BOUNDED, IMAGE_FINITE, FINITE_NUMSEG], ALL_TAC] THEN 17189 SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE, IN_NUMSEG] THEN 17190 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 17191 X_GEN_TAC ``s:real->bool`` THEN DISCH_TAC THEN 17192 X_GEN_TAC ``x:real`` THEN POP_ASSUM (MP_TAC o SPEC ``x:real``) THEN 17193 ASM_CASES_TAC ``(x:real) IN s`` THEN 17194 ASM_REWRITE_TAC[] THEN 17195 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 17196 EXISTS_TAC ``e / B / &(1):real`` THEN 17197 ASM_SIMP_TAC real_ss [REAL_LT_DIV, REAL_LT, LE_1] THEN 17198 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN 17199 ABBREV_TAC ``u = y - (f:real->real) x`` THEN 17200 EXISTS_TAC ``x + sum(1 .. 1) (\i. (u:real) * b i):real`` THEN 17201 ASM_SIMP_TAC std_ss [LINEAR_ADD, LINEAR_SUM, FINITE_NUMSEG, o_DEF, 17202 LINEAR_CMUL] THEN 17203 CONJ_TAC THENL [EXPAND_TAC "u" THEN SIMP_TAC std_ss [NUMSEG_SING, SUM_SING] THEN 17204 REAL_ARITH_TAC, ALL_TAC] THEN 17205 FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC [dist] THEN 17206 REWRITE_TAC[REAL_ARITH ``abs(x + y - x) = abs y:real``] THEN 17207 MATCH_MP_TAC REAL_LET_TRANS THEN 17208 EXISTS_TAC ``(dist(y,(f:real->real) x) * &(1)) * B:real`` THEN 17209 ASM_SIMP_TAC real_ss [GSYM REAL_LT_RDIV_EQ, REAL_LT, LE_1] THEN 17210 MATCH_MP_TAC SUM_ABS_TRIANGLE THEN REWRITE_TAC[FINITE_NUMSEG] THEN 17211 EXPAND_TAC "u" THEN SIMP_TAC std_ss [NUMSEG_SING, SUM_SING] THEN 17212 REWRITE_TAC [ABS_MUL] THEN 17213 UNDISCH_TAC ``!x. 1 <= x /\ x <= 1 ==> abs ((b:num->real) x) <= B`` THEN 17214 DISCH_THEN (MP_TAC o SPEC ``1:num``) THEN ASM_SIMP_TAC real_ss [dist] THEN 17215 DISCH_TAC THEN MATCH_MP_TAC REAL_LE_LMUL_IMP THEN 17216 ASM_SIMP_TAC std_ss [ABS_POS]); 17217 17218val OPEN_BIJECTIVE_LINEAR_IMAGE_EQ = store_thm ("OPEN_BIJECTIVE_LINEAR_IMAGE_EQ", 17219 ``!f:real->real s. 17220 linear f /\ (!x y. (f x = f y) ==> (x = y)) /\ (!y. ?x. f x = y) 17221 ==> (open(IMAGE f s) <=> open s)``, 17222 REPEAT STRIP_TAC THEN EQ_TAC THENL 17223 [DISCH_TAC, ASM_MESON_TAC[OPEN_SURJECTIVE_LINEAR_IMAGE]] THEN 17224 SUBGOAL_THEN ``s = {x | (f:real->real) x IN IMAGE f s}`` 17225 SUBST1_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN 17226 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN 17227 ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_AT]); 17228 17229val CLOSED_INJECTIVE_LINEAR_IMAGE = store_thm ("CLOSED_INJECTIVE_LINEAR_IMAGE", 17230 ``!f:real->real. 17231 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17232 ==> !s. closed s ==> closed(IMAGE f s)``, 17233 REPEAT STRIP_TAC THEN 17234 MP_TAC(ISPEC ``f:real->real`` LINEAR_INJECTIVE_LEFT_INVERSE) THEN 17235 ASM_REWRITE_TAC[] THEN 17236 DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN 17237 MATCH_MP_TAC CLOSED_IN_CLOSED_TRANS THEN 17238 EXISTS_TAC ``IMAGE (f:real->real) univ(:real)`` THEN 17239 CONJ_TAC THENL 17240 [MP_TAC(ISPECL [``g:real->real``, ``IMAGE (f:real->real) univ(:real)``, 17241 ``IMAGE (g:real->real) (IMAGE (f:real->real) s)``] 17242 CONTINUOUS_CLOSED_IN_PREIMAGE) THEN 17243 ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON] THEN 17244 KNOW_TAC ``closed (IMAGE (g:real->real) (IMAGE (f:real->real) s))`` THENL 17245 [ASM_REWRITE_TAC[GSYM IMAGE_COMPOSE, IMAGE_ID], 17246 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 17247 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 17248 FIRST_X_ASSUM(MP_TAC o SIMP_RULE std_ss [FUN_EQ_THM]) THEN 17249 SIMP_TAC std_ss [EXTENSION, o_THM, I_THM] THEN SET_TAC[], 17250 MATCH_MP_TAC CLOSED_INJECTIVE_IMAGE_SUBSPACE THEN 17251 ASM_REWRITE_TAC[IN_UNIV, SUBSPACE_UNIV, CLOSED_UNIV] THEN 17252 X_GEN_TAC ``x:real`` THEN 17253 DISCH_THEN(MP_TAC o AP_TERM ``g:real->real``) THEN 17254 RULE_ASSUM_TAC(SIMP_RULE std_ss [FUN_EQ_THM, I_THM, o_THM]) THEN 17255 ASM_MESON_TAC[LINEAR_0]]); 17256 17257val CLOSED_INJECTIVE_LINEAR_IMAGE_EQ = store_thm ("CLOSED_INJECTIVE_LINEAR_IMAGE_EQ", 17258 ``!f:real->real s. 17259 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17260 ==> (closed(IMAGE f s) <=> closed s)``, 17261 REPEAT STRIP_TAC THEN EQ_TAC THENL 17262 [DISCH_TAC, ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE]] THEN 17263 SUBGOAL_THEN ``s = {x | (f:real->real) x IN IMAGE f s}`` 17264 SUBST1_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN 17265 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN 17266 ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_AT]); 17267 17268val CLOSURE_LINEAR_IMAGE_SUBSET = store_thm ("CLOSURE_LINEAR_IMAGE_SUBSET", 17269 ``!f:real->real s. 17270 linear f ==> IMAGE f (closure s) SUBSET closure(IMAGE f s)``, 17271 REPEAT STRIP_TAC THEN 17272 MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN 17273 ASM_SIMP_TAC std_ss [CLOSED_CLOSURE, CLOSURE_SUBSET, LINEAR_CONTINUOUS_ON]); 17274 17275val CLOSURE_INJECTIVE_LINEAR_IMAGE = store_thm ("CLOSURE_INJECTIVE_LINEAR_IMAGE", 17276 ``!f:real->real s. 17277 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17278 ==> (closure(IMAGE f s) = IMAGE f (closure s))``, 17279 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 17280 ASM_SIMP_TAC std_ss [CLOSURE_LINEAR_IMAGE_SUBSET] THEN 17281 MATCH_MP_TAC CLOSURE_MINIMAL THEN 17282 SIMP_TAC std_ss [CLOSURE_SUBSET, IMAGE_SUBSET] THEN 17283 ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE, CLOSED_CLOSURE]); 17284 17285val CLOSURE_BOUNDED_LINEAR_IMAGE = store_thm ("CLOSURE_BOUNDED_LINEAR_IMAGE", 17286 ``!f:real->real s. 17287 linear f /\ bounded s 17288 ==> (closure(IMAGE f s) = IMAGE f (closure s))``, 17289 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 17290 ASM_SIMP_TAC std_ss [CLOSURE_LINEAR_IMAGE_SUBSET] THEN 17291 MATCH_MP_TAC CLOSURE_MINIMAL THEN 17292 SIMP_TAC std_ss [CLOSURE_SUBSET, IMAGE_SUBSET] THEN 17293 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 17294 MATCH_MP_TAC COMPACT_LINEAR_IMAGE THEN 17295 ASM_REWRITE_TAC[COMPACT_CLOSURE]); 17296 17297val LINEAR_INTERIOR_IMAGE_SUBSET = store_thm ("LINEAR_INTERIOR_IMAGE_SUBSET", 17298 ``!f:real->real s. 17299 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17300 ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)``, 17301 MESON_TAC[INTERIOR_IMAGE_SUBSET, LINEAR_CONTINUOUS_AT]); 17302 17303val LINEAR_IMAGE_SUBSET_INTERIOR = store_thm ("LINEAR_IMAGE_SUBSET_INTERIOR", 17304 ``!f:real->real s. 17305 linear f /\ (!y. ?x. f x = y) 17306 ==> IMAGE f (interior s) SUBSET interior(IMAGE f s)``, 17307 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_MAXIMAL THEN 17308 ASM_SIMP_TAC std_ss [OPEN_SURJECTIVE_LINEAR_IMAGE, OPEN_INTERIOR, 17309 IMAGE_SUBSET, INTERIOR_SUBSET]); 17310 17311val INTERIOR_BIJECTIVE_LINEAR_IMAGE = store_thm ("INTERIOR_BIJECTIVE_LINEAR_IMAGE", 17312 ``!f:real->real s. 17313 linear f /\ (!x y. (f x = f y) ==> (x = y)) /\ (!y. ?x. f x = y) 17314 ==> (interior(IMAGE f s) = IMAGE f (interior s))``, 17315 ONCE_REWRITE_TAC [GSYM SURJECTIVE_IMAGE] THEN REPEAT STRIP_TAC THEN 17316 REWRITE_TAC [interior] THEN 17317 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN 17318 GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 17319 [FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN 17320 STRIP_TAC THEN UNDISCH_TAC ``(t:real->bool) SUBSET IMAGE (f:real->real) s`` THEN 17321 DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SIMP_RULE std_ss [SUBSET_DEF, IN_IMAGE]) THEN 17322 DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN 17323 EXISTS_TAC ``x':real`` THEN ASM_REWRITE_TAC [] THEN EXISTS_TAC ``s':real->bool`` THEN 17324 REPEAT CONJ_TAC THENL 17325 [UNDISCH_TAC ``open t`` THEN MATCH_MP_TAC EQ_IMPLIES THEN 17326 EXPAND_TAC "t" THEN MATCH_MP_TAC OPEN_BIJECTIVE_LINEAR_IMAGE_EQ THEN 17327 METIS_TAC [SURJECTIVE_IMAGE], 17328 UNDISCH_TAC ``IMAGE (f:real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN 17329 DISCH_THEN (MP_TAC o SPEC ``(f:real->real) x'``) THEN SIMP_TAC std_ss [IN_IMAGE] THEN 17330 METIS_TAC [], 17331 REWRITE_TAC [SUBSET_DEF] THEN X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 17332 UNDISCH_TAC ``IMAGE (f:real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN 17333 DISCH_THEN (MP_TAC o SPEC ``(f:real->real) y``) THEN REWRITE_TAC [IN_IMAGE] THEN 17334 KNOW_TAC ``(?x. (f y = (f:real->real) x) /\ x IN s')`` THENL 17335 [METIS_TAC [], ALL_TAC] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 17336 DISCH_TAC THEN UNDISCH_TAC ``t SUBSET IMAGE (f:real->real) s`` THEN 17337 REWRITE_TAC [SUBSET_DEF] THEN DISCH_THEN (MP_TAC o SPEC ``(f:real->real) y``) THEN 17338 ASM_REWRITE_TAC [] THEN REWRITE_TAC [IN_IMAGE] THEN STRIP_TAC THEN 17339 METIS_TAC []], ALL_TAC] THEN 17340 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [GSPECIFICATION] THEN 17341 STRIP_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN 17342 STRIP_TAC THEN EXISTS_TAC ``IMAGE (f:real->real) t`` THEN 17343 REPEAT CONJ_TAC THENL 17344 [UNDISCH_TAC ``open t`` THEN MATCH_MP_TAC OPEN_SURJECTIVE_LINEAR_IMAGE THEN 17345 METIS_TAC [SURJECTIVE_IMAGE], 17346 REWRITE_TAC [IN_IMAGE] THEN EXISTS_TAC ``x':real`` THEN 17347 ASM_REWRITE_TAC [], 17348 MATCH_MP_TAC IMAGE_SUBSET THEN ASM_REWRITE_TAC []]); 17349 17350(* ------------------------------------------------------------------------- *) 17351(* Corollaries, reformulations and special cases for M = N. *) 17352(* ------------------------------------------------------------------------- *) 17353 17354val IN_INTERIOR_LINEAR_IMAGE = store_thm ("IN_INTERIOR_LINEAR_IMAGE", 17355 ``!f:real->real g s x. 17356 linear f /\ linear g /\ (f o g = I) /\ x IN interior s 17357 ==> (f x) IN interior (IMAGE f s)``, 17358 SIMP_TAC std_ss [FUN_EQ_THM, o_THM, I_THM] THEN REPEAT STRIP_TAC THEN 17359 MP_TAC(ISPECL [``f:real->real``, ``s:real->bool``] 17360 LINEAR_IMAGE_SUBSET_INTERIOR) THEN 17361 ASM_SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE] THEN 17362 ASM_MESON_TAC[]); 17363 17364val LINEAR_OPEN_MAPPING = store_thm ("LINEAR_OPEN_MAPPING", 17365 ``!f:real->real g. 17366 linear f /\ linear g /\ (f o g = I) 17367 ==> !s. open s ==> open(IMAGE f s)``, 17368 REPEAT GEN_TAC THEN SIMP_TAC std_ss [FUN_EQ_THM, o_THM, I_THM] THEN DISCH_TAC THEN 17369 MATCH_MP_TAC OPEN_SURJECTIVE_LINEAR_IMAGE THEN 17370 ASM_MESON_TAC[]); 17371 17372val INTERIOR_INJECTIVE_LINEAR_IMAGE = store_thm ("INTERIOR_INJECTIVE_LINEAR_IMAGE", 17373 ``!f:real->real s. 17374 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17375 ==> (interior(IMAGE f s) = IMAGE f (interior s))``, 17376 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_BIJECTIVE_LINEAR_IMAGE THEN 17377 METIS_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE]); 17378 17379val COMPLETE_INJECTIVE_LINEAR_IMAGE = store_thm ("COMPLETE_INJECTIVE_LINEAR_IMAGE", 17380 ``!f:real->real. 17381 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17382 ==> !s. complete s ==> complete(IMAGE f s)``, 17383 REWRITE_TAC[COMPLETE_EQ_CLOSED, CLOSED_INJECTIVE_LINEAR_IMAGE]); 17384 17385val COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ = store_thm ("COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ", 17386 ``!f:real->real s. 17387 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17388 ==> (complete(IMAGE f s) <=> complete s)``, 17389 REWRITE_TAC[COMPLETE_EQ_CLOSED, CLOSED_INJECTIVE_LINEAR_IMAGE_EQ]); 17390 17391val LIMPT_INJECTIVE_LINEAR_IMAGE_EQ = store_thm ("LIMPT_INJECTIVE_LINEAR_IMAGE_EQ", 17392 ``!f:real->real s. 17393 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17394 ==> ((f x) limit_point_of (IMAGE f s) <=> x limit_point_of s)``, 17395 SIMP_TAC std_ss [LIMPT_APPROACHABLE, EXISTS_IN_IMAGE] THEN 17396 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN 17397 DISCH_TAC THENL 17398 [MP_TAC(ISPEC ``f:real->real`` LINEAR_INJECTIVE_BOUNDED_BELOW_POS), 17399 MP_TAC(ISPEC ``f:real->real`` LINEAR_BOUNDED_POS)] THEN 17400 ASM_REWRITE_TAC [] THEN 17401 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THENL 17402 [UNDISCH_TAC ``!(e :real). 17403 (0 :real) < e ==> 17404 ?(x' :real). 17405 x' IN (s :real -> bool) /\ 17406 (f :real -> real) x' <> f (x :real) /\ 17407 (dist (f x',f x) :real) < e`` THEN 17408 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e * B:real``), 17409 UNDISCH_TAC ``!(e :real). 17410 (0 :real) < e ==> 17411 ?(x' :real). 17412 x' IN (s :real -> bool) /\ x' <> (x :real) /\ 17413 (dist (x',x) :real) < e`` THEN DISCH_TAC THEN 17414 FIRST_X_ASSUM(MP_TAC o SPEC ``e / B:real``)] THEN 17415 ASM_SIMP_TAC real_ss [REAL_LT_DIV, REAL_LT_MUL, dist, GSYM LINEAR_SUB] THEN 17416 DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN 17417 POP_ASSUM MP_TAC THEN 17418 REPEAT(MATCH_MP_TAC MONO_AND THEN 17419 CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC]) THEN 17420 ASM_SIMP_TAC real_ss [GSYM REAL_LT_LDIV_EQ, REAL_LT_RDIV_EQ] THEN 17421 MATCH_MP_TAC(REAL_ARITH ``a <= b ==> b < x ==> a < x:real``) THEN 17422 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC real_ss [REAL_LE_RDIV_EQ]); 17423 17424(* ------------------------------------------------------------------------- *) 17425(* Even more special cases. *) 17426(* ------------------------------------------------------------------------- *) 17427 17428val INTERIOR_NEGATIONS = store_thm ("INTERIOR_NEGATIONS", 17429 ``!s. interior(IMAGE (\x. -x) s) = IMAGE (\x. -x) (interior s)``, 17430 GEN_TAC THEN MATCH_MP_TAC INTERIOR_INJECTIVE_LINEAR_IMAGE THEN 17431 SIMP_TAC std_ss [linear] THEN REPEAT CONJ_TAC THEN REAL_ARITH_TAC); 17432 17433val SYMMETRIC_INTERIOR = store_thm ("SYMMETRIC_INTERIOR", 17434 ``!s:real->bool. 17435 (!x. x IN s ==> -x IN s) 17436 ==> !x. x IN interior s ==> (-x) IN interior s``, 17437 REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN 17438 DISCH_THEN(MP_TAC o MATCH_MP(ISPEC ``(\x. -x):real->real`` FUN_IN_IMAGE)) THEN 17439 SIMP_TAC std_ss [GSYM INTERIOR_NEGATIONS] THEN 17440 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN AP_TERM_TAC THEN 17441 SIMP_TAC std_ss [EXTENSION, IN_IMAGE] THEN METIS_TAC[REAL_NEG_NEG]); 17442 17443val CLOSURE_NEGATIONS = store_thm ("CLOSURE_NEGATIONS", 17444 ``!s. closure(IMAGE (\x. -x) s) = IMAGE (\x. -x) (closure s)``, 17445 GEN_TAC THEN MATCH_MP_TAC CLOSURE_INJECTIVE_LINEAR_IMAGE THEN 17446 SIMP_TAC std_ss [linear] THEN REPEAT CONJ_TAC THEN REAL_ARITH_TAC); 17447 17448val SYMMETRIC_CLOSURE = store_thm ("SYMMETRIC_CLOSURE", 17449 ``!s:real->bool. 17450 (!x. x IN s ==> -x IN s) 17451 ==> !x. x IN closure s ==> (-x) IN closure s``, 17452 REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN 17453 DISCH_THEN(MP_TAC o MATCH_MP(ISPEC ``(\x. -x):real->real`` FUN_IN_IMAGE)) THEN 17454 SIMP_TAC std_ss [GSYM CLOSURE_NEGATIONS] THEN 17455 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN AP_TERM_TAC THEN 17456 SIMP_TAC std_ss [EXTENSION, IN_IMAGE] THEN ASM_MESON_TAC[REAL_NEG_NEG]); 17457 17458(* ------------------------------------------------------------------------- *) 17459(* Some properties of a canonical subspace. *) 17460(* ------------------------------------------------------------------------- *) 17461 17462val SUBSPACE_SUBSTANDARD = store_thm ("SUBSPACE_SUBSTANDARD", 17463 ``subspace {x:real | (x = &0)}``, 17464 SIMP_TAC std_ss [subspace, GSPECIFICATION, REAL_MUL_RZERO, REAL_ADD_LID]); 17465 17466val CLOSED_SUBSTANDARD = store_thm ("CLOSED_SUBSTANDARD", 17467 ``closed {x:real | x = &0}``, 17468 REWRITE_TAC [GSPEC_EQ, CLOSED_SING]); 17469 17470val DIM_SUBSTANDARD = store_thm ("DIM_SUBSTANDARD", 17471 ``dim {x:real | x = &0} = 0``, 17472 REWRITE_TAC [dim, GSPEC_EQ] THEN MATCH_MP_TAC SELECT_UNIQUE THEN 17473 RW_TAC std_ss [] THEN EQ_TAC THENL 17474 [ONCE_REWRITE_TAC [MONO_NOT_EQ] THEN RW_TAC std_ss [] THEN 17475 ASM_CASES_TAC ``~(b SUBSET {0:real})`` THEN 17476 ASM_REWRITE_TAC [] THEN FULL_SIMP_TAC std_ss [SET_RULE 17477 ``b SUBSET {0:real} <=> (b = {}) \/ (b = {0})``] THENL 17478 [DISJ2_TAC THEN DISJ2_TAC THEN SIMP_TAC std_ss [HAS_SIZE] THEN 17479 DISJ2_TAC THEN REWRITE_TAC [CARD_EMPTY] THEN METIS_TAC [], 17480 REWRITE_TAC [INDEPENDENT_SING]], ALL_TAC] THEN 17481 DISCH_TAC THEN EXISTS_TAC ``{}:real->bool`` THEN 17482 ASM_SIMP_TAC std_ss [SPAN_EMPTY, SUBSET_REFL, EMPTY_SUBSET, INDEPENDENT_EMPTY] THEN 17483 ASM_REWRITE_TAC [HAS_SIZE_0]); 17484 17485(* ------------------------------------------------------------------------- *) 17486(* Affine transformations of intervals. *) 17487(* ------------------------------------------------------------------------- *) 17488 17489val AFFINITY_INVERSES = store_thm ("AFFINITY_INVERSES", 17490 ``!m c. ~(m = &0:real) 17491 ==> ((\x. m * x + c) o (\x. inv(m) * x + (-(inv(m) * c))) = (\x. x)) /\ 17492 ((\x. inv(m) * x + (-(inv(m) * c))) o (\x. m * x + c) = (\x. x))``, 17493 SIMP_TAC std_ss [FUN_EQ_THM, o_THM] THEN 17494 SIMP_TAC std_ss [REAL_ADD_LDISTRIB, REAL_MUL_RNEG] THEN 17495 SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_RINV] THEN 17496 REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 17497 17498val REAL_AFFINITY_LE = store_thm ("REAL_AFFINITY_LE", 17499 ``!m c x y. &0:real < m ==> ((m * x + c <= y) <=> (x <= inv(m) * y + -(c / m)))``, 17500 REWRITE_TAC[REAL_ARITH ``(m * x + c <= y:real) <=> (x * m <= y - c)``] THEN 17501 SIMP_TAC std_ss [GSYM REAL_LE_RDIV_EQ] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 17502 REWRITE_TAC [real_div, GSYM real_sub, REAL_SUB_RDISTRIB]); 17503 17504val REAL_LE_AFFINITY = store_thm ("REAL_LE_AFFINITY", 17505 ``!m c x y. &0:real < m ==> ((y <= m * x + c) <=> (inv(m) * y + -(c / m) <= x))``, 17506 REWRITE_TAC[REAL_ARITH ``(y <= m * x + c:real) <=> (y - c <= x * m)``] THEN 17507 SIMP_TAC std_ss [GSYM REAL_LE_LDIV_EQ] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 17508 REWRITE_TAC [real_div, GSYM real_sub, REAL_SUB_RDISTRIB]); 17509 17510val REAL_AFFINITY_LT = store_thm ("REAL_AFFINITY_LT", 17511 ``!m c x y. &0:real < m ==> (m * x + c < y <=> x < inv(m) * y + -(c / m))``, 17512 SIMP_TAC std_ss [REAL_LE_AFFINITY, GSYM REAL_NOT_LE]); 17513 17514val REAL_LT_AFFINITY = store_thm ("REAL_LT_AFFINITY", 17515 ``!m c x y. &0:real < m ==> (y < m * x + c <=> inv(m) * y + -(c / m) < x)``, 17516 SIMP_TAC std_ss [REAL_AFFINITY_LE, GSYM REAL_NOT_LE]); 17517 17518val REAL_AFFINITY_EQ = store_thm ("REAL_AFFINITY_EQ", 17519 ``!m c x y. ~(m = &0:real) ==> ((m * x + c = y) <=> (x = inv(m) * y + -(c / m)))``, 17520 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 17521 REWRITE_TAC [real_div, GSYM real_sub, GSYM REAL_SUB_RDISTRIB] THEN 17522 REWRITE_TAC [GSYM REAL_EQ_SUB_LADD, GSYM real_div] THEN 17523 REPEAT STRIP_TAC THEN EQ_TAC THENL 17524 [GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN 17525 ASM_SIMP_TAC arith_ss [real_div, GSYM REAL_MUL_ASSOC, REAL_MUL_RINV, 17526 REAL_MUL_RID], DISCH_TAC THEN METIS_TAC [REAL_DIV_RMUL]]); 17527 17528val REAL_EQ_AFFINITY = store_thm ("REAL_EQ_AFFINITY", 17529 ``!m c x y. ~(m = &0:real) ==> ((y = m * x + c) <=> (inv(m) * y + -(c / m) = x))``, 17530 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 17531 REWRITE_TAC [real_div, GSYM real_sub, GSYM REAL_SUB_RDISTRIB] THEN 17532 REPEAT STRIP_TAC THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN 17533 REWRITE_TAC [GSYM REAL_EQ_SUB_LADD, GSYM real_div] THEN EQ_TAC THENL 17534 [GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN 17535 ASM_SIMP_TAC arith_ss [real_div, GSYM REAL_MUL_ASSOC, REAL_MUL_RINV, 17536 REAL_MUL_RID], DISCH_TAC THEN METIS_TAC [REAL_DIV_RMUL]]); 17537 17538val IMAGE_AFFINITY_INTERVAL = store_thm ("IMAGE_AFFINITY_INTERVAL", 17539 ``!a b:real m c. 17540 IMAGE (\x. m * x + c) (interval[a,b]) = 17541 if interval[a,b] = {} then {} 17542 else if &0 <= m then interval[m * a + c,m * b + c] 17543 else interval[m * b + c,m * a + c]``, 17544 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[IMAGE_EMPTY, IMAGE_INSERT] THEN 17545 ASM_CASES_TAC ``m = &0:real`` THEN ASM_REWRITE_TAC[REAL_LE_LT] THENL 17546 [ASM_REWRITE_TAC[REAL_MUL_LZERO, REAL_ADD_LID, COND_ID] THEN 17547 REWRITE_TAC[INTERVAL_SING] THEN ASM_SET_TAC[], 17548 ALL_TAC] THEN 17549 FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH 17550 ``~(x = &0:real) ==> &0 < x \/ &0 < -x``)) THEN 17551 ASM_SIMP_TAC std_ss [EXTENSION, IN_IMAGE, REAL_ARITH ``&0 < -x ==> ~(&0 < x:real)``] THENL 17552 [ALL_TAC, 17553 ONCE_REWRITE_TAC[REAL_ARITH ``(x = m * y + c:real) <=> (c = (-m) * y + x)``]] THEN 17554 (ASM_SIMP_TAC std_ss [REAL_EQ_AFFINITY, REAL_LT_IMP_NE, UNWIND_THM1] THEN 17555 SIMP_TAC std_ss [IN_INTERVAL] THEN 17556 POP_ASSUM(MP_TAC o ONCE_REWRITE_RULE [GSYM REAL_LT_INV_EQ]) THEN 17557 SIMP_TAC std_ss [REAL_AFFINITY_LE, REAL_LE_AFFINITY, real_div] THEN 17558 DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[REAL_INV_INV] THEN 17559 REWRITE_TAC[REAL_MUL_LNEG, REAL_NEGNEG] THEN 17560 KNOW_TAC ``-m <> 0:real`` THENL [ASM_REAL_ARITH_TAC, DISCH_TAC] THEN 17561 ASM_SIMP_TAC std_ss [METIS [REAL_MUL_RID, GSYM REAL_MUL_ASSOC, REAL_MUL_RINV, 17562 REAL_ARITH ``b * inv a * a = b * a * inv a:real``] 17563 ``m <> 0:real ==> (x * inv m * m = x)``] THEN 17564 GEN_TAC THEN ONCE_REWRITE_TAC [REAL_ADD_SYM] THEN REWRITE_TAC [GSYM real_sub] THEN 17565 REAL_ARITH_TAC)); 17566 17567(* ------------------------------------------------------------------------- *) 17568(* Infinite sums of vectors. Allow general starting point (and more). *) 17569(* ------------------------------------------------------------------------- *) 17570 17571val _ = hide "sums"; 17572val _ = hide "summable"; 17573 17574val _ = set_fixity "sums" (Infix(NONASSOC, 450)); 17575 17576Definition sums : (* cf. seqTheory.sums *) 17577 (f sums l) s = ((\n. sum (s INTER ((0:num)..n)) f) --> l) sequentially 17578End 17579 17580Definition infsum : (* cf. seqTheory.suminf *) 17581 infsum s f = @l. (f sums l) s 17582End 17583val _ = overload_on ("suminf", ``infsum``); 17584 17585Definition summable : (* cf. seqTheory.summable *) 17586 summable s f = ?l. (f sums l) s 17587End 17588 17589(* connections to related concepts in seqTheory *) 17590Theorem sums_univ : 17591 !(f :num -> real) (l :real). (f sums l) univ(:num) <=> seq$sums f l 17592Proof 17593 RW_TAC std_ss [seqTheory.sums, sums, dist, INTER_UNIV, SEQ, LIM_SEQUENTIALLY] 17594 >> EQ_TAC >> rpt STRIP_TAC 17595 >| [ (* goal 1 (of 2) *) 17596 Q.PAT_X_ASSUM `!e. 0 < e ==> P` (MP_TAC o (Q.SPEC `e`)) \\ 17597 RW_TAC std_ss [] \\ 17598 Q.EXISTS_TAC `SUC N` >> rpt STRIP_TAC \\ 17599 Cases_on `n` >- fs [] \\ 17600 REWRITE_TAC [GSYM sum_real] \\ 17601 FIRST_X_ASSUM MATCH_MP_TAC >> rw [], 17602 (* goal 2 (of 2) *) 17603 Q.PAT_X_ASSUM `!e. 0 < e ==> P` (MP_TAC o (Q.SPEC `e`)) \\ 17604 RW_TAC std_ss [] \\ 17605 Q.EXISTS_TAC `N` >> rpt STRIP_TAC \\ 17606 REWRITE_TAC [sum_real] \\ 17607 FIRST_X_ASSUM MATCH_MP_TAC >> rw [] ] 17608QED 17609 17610Theorem suminf_univ : 17611 !(f :num -> real). infsum univ(:num) f = seq$suminf f 17612Proof 17613 RW_TAC std_ss [infsum, suminf, sums_univ] 17614QED 17615 17616Theorem summable_univ : 17617 !(f :num -> real). summable univ(:num) f <=> seq$summable f 17618Proof 17619 RW_TAC std_ss [summable, seqTheory.summable, sums_univ] 17620QED 17621 17622val SUMS_SUMMABLE = store_thm ("SUMS_SUMMABLE", 17623 ``!f l s. (f sums l) s ==> summable s f``, 17624 REWRITE_TAC[summable] THEN MESON_TAC[]); 17625 17626val SUMS_INFSUM = store_thm ("SUMS_INFSUM", 17627 ``!f s. (f sums (infsum s f)) s <=> summable s f``, 17628 REWRITE_TAC[infsum, summable] THEN METIS_TAC[]); 17629 17630val SUMS_LIM = store_thm ("SUMS_LIM", 17631 ``!f:num->real s. 17632 (f sums lim sequentially (\n. sum (s INTER ((0:num)..n)) f)) s 17633 <=> summable s f``, 17634 GEN_TAC THEN GEN_TAC THEN EQ_TAC THENL [MESON_TAC[summable], 17635 REWRITE_TAC[summable, sums] THEN STRIP_TAC THEN REWRITE_TAC[lim_def] THEN 17636 METIS_TAC[]]); 17637 17638val FINITE_INTER_NUMSEG = store_thm ("FINITE_INTER_NUMSEG", 17639 ``!s m n. FINITE(s INTER (m..n))``, 17640 MESON_TAC[SUBSET_FINITE_I, FINITE_NUMSEG, INTER_SUBSET]); 17641 17642val SERIES_FROM = store_thm ("SERIES_FROM", 17643 ``!f l k. (f sums l) (from k) = ((\n. sum(k..n) f) --> l) sequentially``, 17644 REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN 17645 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN 17646 AP_THM_TAC THEN AP_TERM_TAC THEN 17647 SIMP_TAC std_ss [EXTENSION, numseg, from_def, GSPECIFICATION, IN_INTER] THEN ARITH_TAC); 17648 17649val SERIES_UNIQUE = store_thm ("SERIES_UNIQUE", 17650 ``!f:num->real l l' s. (f sums l) s /\ (f sums l') s ==> (l = l')``, 17651 REWRITE_TAC[sums] THEN MESON_TAC[TRIVIAL_LIMIT_SEQUENTIALLY, LIM_UNIQUE]); 17652 17653val INFSUM_UNIQUE = store_thm ("INFSUM_UNIQUE", 17654 ``!f:num->real l s. (f sums l) s ==> (infsum s f = l)``, 17655 MESON_TAC[SERIES_UNIQUE, SUMS_INFSUM, summable]); 17656 17657val SERIES_TERMS_TOZERO = store_thm ("SERIES_TERMS_TOZERO", 17658 ``!f l n. (f sums l) (from n) ==> (f --> 0) sequentially``, 17659 REPEAT GEN_TAC THEN SIMP_TAC std_ss [sums, LIM_SEQUENTIALLY, FROM_INTER_NUMSEG] THEN 17660 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 17661 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 17662 ASM_REWRITE_TAC[REAL_HALF] THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THEN 17663 EXISTS_TAC ``N + n + 1:num`` THEN X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN 17664 FIRST_X_ASSUM(fn th => 17665 MP_TAC(SPEC ``m - 1:num`` th) THEN MP_TAC(SPEC ``m:num`` th)) THEN 17666 SUBGOAL_THEN ``0 < m:num /\ n <= m`` (fn th => SIMP_TAC std_ss [SUM_CLAUSES_RIGHT, th]) 17667 THENL [CONJ_TAC THENL 17668 [MATCH_MP_TAC LESS_LESS_EQ_TRANS THEN EXISTS_TAC ``N + n + 1:num`` THEN 17669 ASM_REWRITE_TAC [] THEN ARITH_TAC, 17670 MATCH_MP_TAC LESS_EQ_TRANS THEN EXISTS_TAC ``N + n + 1:num`` THEN 17671 ASM_REWRITE_TAC [] THEN ARITH_TAC], ALL_TAC] THEN 17672 KNOW_TAC ``N <= m:num`` THENL [MATCH_MP_TAC LESS_EQ_TRANS THEN 17673 EXISTS_TAC ``N + n + 1:num`` THEN ASM_REWRITE_TAC [] THEN ARITH_TAC, 17674 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN 17675 KNOW_TAC ``N <= m:num - 1`` THENL [MATCH_MP_TAC LESS_EQ_TRANS THEN 17676 EXISTS_TAC ``N + n:num`` THEN CONJ_TAC THENL [ARITH_TAC, ALL_TAC] THEN 17677 ONCE_REWRITE_TAC [ARITH_PROVE ``(a <= b) = (a + 1 <= b + 1:num)``] THEN 17678 MATCH_MP_TAC LESS_EQ_TRANS THEN EXISTS_TAC ``m:num`` THEN 17679 ASM_REWRITE_TAC [] THEN ARITH_TAC, 17680 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN 17681 REWRITE_TAC [DIST_0] THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN 17682 FULL_SIMP_TAC std_ss [dist] THEN ASM_REAL_ARITH_TAC); 17683 17684val SERIES_FINITE = store_thm ("SERIES_FINITE", 17685 ``!f s. FINITE s ==> (f sums (sum s f)) s``, 17686 REPEAT GEN_TAC THEN SIMP_TAC std_ss [num_FINITE, LEFT_IMP_EXISTS_THM] THEN 17687 X_GEN_TAC ``n:num`` THEN SIMP_TAC std_ss [sums, LIM_SEQUENTIALLY] THEN 17688 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN EXISTS_TAC ``n:num`` THEN 17689 X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN 17690 SUBGOAL_THEN ``s INTER ((0:num)..m) = s`` 17691 (fn th => ASM_REWRITE_TAC[th, DIST_REFL]) THEN 17692 SIMP_TAC std_ss [EXTENSION, IN_INTER, IN_NUMSEG, ZERO_LESS_EQ] THEN 17693 METIS_TAC[LESS_EQ_TRANS]); 17694 17695val SERIES_LINEAR = store_thm ("SERIES_LINEAR", 17696 ``!f h l s. (f sums l) s /\ linear h ==> ((\n. h(f n)) sums h l) s``, 17697 SIMP_TAC std_ss [sums, LIM_LINEAR, FINITE_INTER, FINITE_NUMSEG, 17698 GSYM(REWRITE_RULE[o_DEF] LINEAR_SUM)]); 17699 17700val SERIES_0 = store_thm ("SERIES_0", 17701 ``!s. ((\n. 0) sums (0)) s``, 17702 REWRITE_TAC[sums, SUM_0, LIM_CONST]); 17703 17704val SERIES_ADD = store_thm ("SERIES_ADD", 17705 ``!x x0 y y0 s. 17706 (x sums x0) s /\ (y sums y0) s ==> ((\n. x n + y n) sums (x0 + y0)) s``, 17707 SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_ADD, LIM_ADD]); 17708 17709val SERIES_SUB = store_thm ("SERIES_SUB", 17710 ``!x x0 y y0 s. 17711 (x sums x0) s /\ (y sums y0) s ==> ((\n. x n - y n) sums (x0 - y0)) s``, 17712 SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_SUB, LIM_SUB]); 17713 17714val SERIES_CMUL = store_thm ("SERIES_CMUL", 17715 ``!x x0 c s. (x sums x0) s ==> ((\n. c * x n) sums (c * x0)) s``, 17716 SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_LMUL, LIM_CMUL]); 17717 17718val SERIES_NEG = store_thm ("SERIES_NEG", 17719 ``!x x0 s. (x sums x0) s ==> ((\n. -(x n)) sums (-x0)) s``, 17720 SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_NEG, LIM_NEG]); 17721 17722val SUMS_IFF = store_thm ("SUMS_IFF", 17723 ``!f g k. (!x. x IN k ==> (f x = g x)) ==> ((f sums l) k <=> (g sums l) k)``, 17724 REPEAT STRIP_TAC THEN REWRITE_TAC[sums] THEN 17725 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN 17726 MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC std_ss [IN_INTER]); 17727 17728val SUMS_EQ = store_thm ("SUMS_EQ", 17729 ``!f g k. (!x. x IN k ==> (f x = g x)) /\ (f sums l) k ==> (g sums l) k``, 17730 MESON_TAC[SUMS_IFF]); 17731 17732val SUMS_0 = store_thm ("SUMS_0", 17733 ``!f:num->real s. (!n. n IN s ==> (f n = 0)) ==> (f sums 0) s``, 17734 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMS_EQ THEN 17735 EXISTS_TAC ``\n:num. 0:real`` THEN ASM_SIMP_TAC std_ss [SERIES_0]); 17736 17737val SERIES_FINITE_SUPPORT = store_thm ("SERIES_FINITE_SUPPORT", 17738 ``!f:num->real s k. 17739 FINITE (s INTER k) /\ (!x. x IN k /\ ~(x IN s) ==> (f x = 0)) 17740 ==> (f sums sum (s INTER k) f) k``, 17741 REWRITE_TAC[sums, LIM_SEQUENTIALLY] THEN REPEAT STRIP_TAC THEN 17742 FIRST_ASSUM(MP_TAC o ISPEC ``\x:num. x`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN 17743 REWRITE_TAC[] THEN DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN 17744 EXISTS_TAC ``N:num`` THEN POP_ASSUM MP_TAC THEN 17745 STRIP_TAC THEN X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 17746 SIMP_TAC std_ss [] THEN 17747 SUBGOAL_THEN ``sum (k INTER ((0:num)..n)) (f:num->real) = sum(s INTER k) f`` 17748 (fn th => ASM_SIMP_TAC std_ss [DIST_REFL, th]) THEN 17749 MATCH_MP_TAC SUM_SUPERSET THEN 17750 ASM_SIMP_TAC std_ss [SUBSET_DEF, IN_INTER, IN_NUMSEG, ZERO_LESS_EQ] THEN 17751 METIS_TAC[IN_INTER, LESS_EQ_TRANS]); 17752 17753val SERIES_COMPONENT = store_thm ("SERIES_COMPONENT", 17754 ``!f s l:real. (f sums l) s 17755 ==> ((\i. f(i)) sums l) s``, 17756 METIS_TAC []); 17757 17758val SERIES_DIFFS = store_thm ("SERIES_DIFFS", 17759 ``!f:num->real k. (f --> 0) sequentially 17760 ==> ((\n. f(n) - f(n + 1)) sums f(k)) (from k)``, 17761 REWRITE_TAC[sums, FROM_INTER_NUMSEG, SUM_DIFFS] THEN 17762 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN 17763 EXISTS_TAC ``\n. (f:num->real) k - f(n + 1)`` THEN CONJ_TAC THENL 17764 [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC ``k:num`` THEN 17765 SIMP_TAC std_ss [], 17766 GEN_REWR_TAC LAND_CONV [GSYM REAL_SUB_RZERO] THEN 17767 KNOW_TAC ``((\n. (\n. f k) n - (\n. f (n + 1)) n) 17768 --> ((f:num->real) k - 0)) sequentially`` THENL 17769 [ALL_TAC, SIMP_TAC std_ss []] THEN 17770 MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN 17771 MATCH_MP_TAC SEQ_OFFSET THEN ASM_REWRITE_TAC[]]); 17772 17773val SERIES_TRIVIAL = store_thm ("SERIES_TRIVIAL", 17774 ``!f. (f sums 0) {}``, 17775 SIMP_TAC std_ss [sums, INTER_EMPTY, SUM_CLAUSES, LIM_CONST]); 17776 17777val SERIES_RESTRICT = store_thm ("SERIES_RESTRICT", 17778 ``!f k l:real. 17779 ((\n. if n IN k then f(n) else 0) sums l) univ(:num) <=> 17780 (f sums l) k``, 17781 REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN 17782 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN 17783 REWRITE_TAC[FUN_EQ_THM, INTER_UNIV] THEN GEN_TAC THEN 17784 SIMP_TAC std_ss [] THEN 17785 MATCH_MP_TAC(METIS [] ``(sum s f = sum t f) /\ (sum t f = sum t g) 17786 ==> (sum s f = sum t g)``) THEN 17787 CONJ_TAC THENL 17788 [MATCH_MP_TAC SUM_SUPERSET THEN SET_TAC[], 17789 MATCH_MP_TAC SUM_EQ THEN SIMP_TAC std_ss [IN_INTER]]); 17790 17791val SERIES_SUM = store_thm ("SERIES_SUM", 17792 ``!f l k s. FINITE s /\ s SUBSET k /\ (!x. ~(x IN s) ==> (f x = 0)) /\ 17793 (sum s f = l) ==> (f sums l) k``, 17794 REPEAT STRIP_TAC THEN EXPAND_TAC "l" THEN 17795 SUBGOAL_THEN ``s INTER k = s:num->bool`` ASSUME_TAC THENL 17796 [ASM_SET_TAC [], ASM_MESON_TAC [SERIES_FINITE_SUPPORT]]); 17797 17798val SUMS_REINDEX = store_thm ("SUMS_REINDEX", 17799 ``!k a l:real n. 17800 ((\x. a(x + k)) sums l) (from n) <=> (a sums l) (from(n + k))``, 17801 REPEAT GEN_TAC THEN REWRITE_TAC[sums, FROM_INTER_NUMSEG] THEN 17802 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUM_OFFSET] THEN 17803 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 17804 ASM_MESON_TAC[ARITH_PROVE ``N + k:num <= n ==> (n = (n - k) + k) /\ N <= n - k``, 17805 ARITH_PROVE ``N + k:num <= n ==> N <= n + k``]); 17806 17807val SUMS_REINDEX_GEN = store_thm ("SUMS_REINDEX_GEN", 17808 ``!k a l:real s. 17809 ((\x. a(x + k)) sums l) s <=> (a sums l) (IMAGE (\i. i + k) s)``, 17810 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN 17811 MP_TAC(ISPECL 17812 [``k:num``, 17813 ``\i. if i IN IMAGE (\i. i + k) s then (a:num->real) i else 0``, 17814 ``l:real``, ``0:num``] SUMS_REINDEX) THEN 17815 REWRITE_TAC[FROM_0] THEN 17816 SIMP_TAC std_ss [EQ_ADD_RCANCEL, SET_RULE 17817 ``(!x y:num. (x + k = y + k) <=> (x = y)) 17818 ==> ((x + k) IN IMAGE (\i. i + k) s <=> x IN s)``] THEN 17819 DISCH_THEN SUBST1_TAC THEN 17820 GEN_REWR_TAC LAND_CONV [GSYM SERIES_RESTRICT] THEN 17821 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN 17822 REWRITE_TAC[FUN_EQ_THM, IN_FROM, ADD_CLAUSES] THEN 17823 SUBGOAL_THEN ``!x:num. x IN IMAGE (\i. i + k) s ==> k <= x`` MP_TAC THENL 17824 [SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN ARITH_TAC, SET_TAC[]]); 17825 17826(* ------------------------------------------------------------------------- *) 17827(* Similar combining theorems just for summability. *) 17828(* ------------------------------------------------------------------------- *) 17829 17830val SUMMABLE_LINEAR = store_thm ("SUMMABLE_LINEAR", 17831 ``!f h s. summable s f /\ linear h ==> summable s (\n. h(f n))``, 17832 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_LINEAR]); 17833 17834val SUMMABLE_0 = store_thm ("SUMMABLE_0", 17835 ``!s. summable s (\n. 0)``, 17836 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_0]); 17837 17838val SUMMABLE_ADD = store_thm ("SUMMABLE_ADD", 17839 ``!x y s. summable s x /\ summable s y ==> summable s (\n. x n + y n)``, 17840 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_ADD]); 17841 17842val SUMMABLE_SUB = store_thm ("SUMMABLE_SUB", 17843 ``!x y s. summable s x /\ summable s y ==> summable s (\n. x n - y n)``, 17844 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_SUB]); 17845 17846val SUMMABLE_CMUL = store_thm ("SUMMABLE_CMUL", 17847 ``!s x c. summable s x ==> summable s (\n. c * x n)``, 17848 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_CMUL]); 17849 17850val SUMMABLE_NEG = store_thm ("SUMMABLE_NEG", 17851 ``!x s. summable s x ==> summable s (\n. -(x n))``, 17852 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_NEG]); 17853 17854val SUMMABLE_IFF = store_thm ("SUMMABLE_IFF", 17855 ``!f g k. (!x. x IN k ==> (f x = g x)) ==> (summable k f <=> summable k g)``, 17856 REWRITE_TAC[summable] THEN METIS_TAC[SUMS_IFF]); 17857 17858val SUMMABLE_EQ = store_thm ("SUMMABLE_EQ", 17859 ``!f g k. (!x. x IN k ==> (f x = g x)) /\ summable k f ==> summable k g``, 17860 REWRITE_TAC[summable] THEN METIS_TAC[SUMS_EQ]); 17861 17862val SUMMABLE_COMPONENT = store_thm ("SUMMABLE_COMPONENT", 17863 ``!f:num->real s. 17864 summable s f ==> summable s (\i. f(i))``, 17865 METIS_TAC []); 17866 17867val SERIES_SUBSET = store_thm ("SERIES_SUBSET", 17868 ``!x s t l. 17869 s SUBSET t /\ 17870 ((\i. if i IN s then x i else 0) sums l) t 17871 ==> (x sums l) s``, 17872 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 17873 REWRITE_TAC[sums] THEN MATCH_MP_TAC EQ_IMPLIES THEN 17874 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN 17875 ASM_SIMP_TAC std_ss [GSYM SUM_RESTRICT_SET, FINITE_INTER_NUMSEG] THEN 17876 AP_THM_TAC THEN AP_TERM_TAC THEN POP_ASSUM MP_TAC THEN SET_TAC[]); 17877 17878val SUMMABLE_SUBSET = store_thm ("SUMMABLE_SUBSET", 17879 ``!x s t. 17880 s SUBSET t /\ 17881 summable t (\i. if i IN s then x i else 0) 17882 ==> summable s x``, 17883 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_SUBSET]); 17884 17885val SUMMABLE_TRIVIAL = store_thm ("SUMMABLE_TRIVIAL", 17886 ``!f:num->real. summable {} f``, 17887 GEN_TAC THEN REWRITE_TAC[summable] THEN EXISTS_TAC ``0:real`` THEN 17888 REWRITE_TAC[SERIES_TRIVIAL]); 17889 17890val SUMMABLE_RESTRICT = store_thm ("SUMMABLE_RESTRICT", 17891 ``!f:num->real k. 17892 summable univ(:num) (\n. if n IN k then f(n) else 0) <=> 17893 summable k f``, 17894 SIMP_TAC std_ss [summable, SERIES_RESTRICT]); 17895 17896val SUMS_FINITE_DIFF = store_thm ("SUMS_FINITE_DIFF", 17897 ``!f:num->real t s l. 17898 t SUBSET s /\ FINITE t /\ (f sums l) s 17899 ==> (f sums (l - sum t f)) (s DIFF t)``, 17900 REPEAT GEN_TAC THEN 17901 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 17902 FIRST_ASSUM(MP_TAC o ISPEC ``f:num->real`` o MATCH_MP SERIES_FINITE) THEN 17903 ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN 17904 REWRITE_TAC[AND_IMP_INTRO] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN 17905 DISCH_THEN(MP_TAC o MATCH_MP SERIES_SUB) THEN 17906 MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN 17907 REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``x:num`` THEN REWRITE_TAC[IN_DIFF] THEN 17908 UNDISCH_TAC ``t SUBSET s:num->bool`` THEN DISCH_TAC THEN 17909 FIRST_ASSUM(MP_TAC o SPEC ``x:num`` o REWRITE_RULE [SUBSET_DEF]) THEN 17910 MAP_EVERY ASM_CASES_TAC [``(x:num) IN s``, ``(x:num) IN t``] THEN 17911 ASM_SIMP_TAC arith_ss [] THEN REAL_ARITH_TAC); 17912 17913val SUMS_FINITE_UNION = store_thm ("SUMS_FINITE_UNION", 17914 ``!f:num->real s t l. 17915 FINITE t /\ (f sums l) s 17916 ==> (f sums (l + sum (t DIFF s) f)) (s UNION t)``, 17917 REPEAT GEN_TAC THEN 17918 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 17919 FIRST_ASSUM(MP_TAC o SPEC ``s:num->bool`` o MATCH_MP FINITE_DIFF) THEN 17920 DISCH_THEN(MP_TAC o ISPEC ``f:num->real`` o MATCH_MP SERIES_FINITE) THEN 17921 ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN 17922 REWRITE_TAC[AND_IMP_INTRO] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN 17923 DISCH_THEN(MP_TAC o MATCH_MP SERIES_ADD) THEN 17924 MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN 17925 REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``x:num`` THEN 17926 REWRITE_TAC[IN_DIFF, IN_UNION] THEN 17927 MAP_EVERY ASM_CASES_TAC [``(x:num) IN s``, ``(x:num) IN t``] THEN 17928 ASM_SIMP_TAC arith_ss [] THEN REAL_ARITH_TAC); 17929 17930val SUMS_OFFSET = store_thm ("SUMS_OFFSET", 17931 ``!f l:real m n. 17932 (f sums l) (from m) /\ 0 < n /\ m <= n 17933 ==> (f sums l - sum (m..n - 1) f) (from n)``, 17934 REPEAT STRIP_TAC THEN 17935 SUBGOAL_THEN ``from n = from m DIFF (m..(n-1:num))`` SUBST1_TAC THENL 17936 [SIMP_TAC std_ss [EXTENSION, IN_FROM, IN_DIFF, IN_NUMSEG] THEN 17937 GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN CONJ_TAC THENL 17938 [MATCH_MP_TAC LESS_EQ_TRANS THEN EXISTS_TAC ``n:num`` THEN ASM_REWRITE_TAC [], 17939 REWRITE_TAC [NOT_LESS_EQUAL] THEN DISJ2_TAC THEN 17940 MATCH_MP_TAC LESS_LESS_EQ_TRANS THEN EXISTS_TAC ``n:num`` THEN ASM_REWRITE_TAC [] THEN 17941 MATCH_MP_TAC SUB_LESS THEN CONJ_TAC THENL [ARITH_TAC , ALL_TAC] THEN 17942 REWRITE_TAC [ONE] THEN ASM_REWRITE_TAC [GSYM LESS_EQ]], ARITH_TAC], 17943 MATCH_MP_TAC SUMS_FINITE_DIFF THEN ASM_REWRITE_TAC[FINITE_NUMSEG] THEN 17944 SIMP_TAC std_ss [SUBSET_DEF, IN_FROM, IN_NUMSEG]]); 17945 17946val SUMS_OFFSET_REV = store_thm ("SUMS_OFFSET_REV", 17947 ``!f:num->real l m n. 17948 (f sums l) (from m) /\ 0 < m /\ n <= m 17949 ==> (f sums (l + sum(n..m-1) f)) (from n)``, 17950 REPEAT STRIP_TAC THEN 17951 MP_TAC(ISPECL [``f:num->real``, ``from m``, ``n..m-1``, ``l:real``] 17952 SUMS_FINITE_UNION) THEN 17953 ASM_REWRITE_TAC[FINITE_NUMSEG] THEN MATCH_MP_TAC EQ_IMPLIES THEN 17954 BINOP_TAC THENL [AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC, ALL_TAC] THEN 17955 REWRITE_TAC[EXTENSION, IN_DIFF, IN_UNION, IN_FROM, IN_NUMSEG] THEN 17956 ASM_SIMP_TAC arith_ss []); 17957 17958val SUMMABLE_REINDEX = store_thm ("SUMMABLE_REINDEX", 17959 ``!k a n. summable (from n) (\x. a (x + k)) <=> summable (from(n + k)) a``, 17960 REWRITE_TAC[summable, GSYM SUMS_REINDEX]); 17961 17962val SERIES_DROP_LE = store_thm ("SERIES_DROP_LE", 17963 ``!f g s a b. 17964 (f sums a) s /\ (g sums b) s /\ 17965 (!x. x IN s ==> (f x <= g x)) 17966 ==> a <= b``, 17967 REWRITE_TAC[sums] THEN REPEAT STRIP_TAC THEN 17968 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_DROP_LE) THEN 17969 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY, TRIVIAL_LIMIT_SEQUENTIALLY] THEN 17970 EXISTS_TAC ``\n. sum (s INTER ((0:num)..n)) (f:num->real)`` THEN 17971 EXISTS_TAC ``\n. sum (s INTER ((0:num)..n)) (g:num->real)`` THEN 17972 ASM_REWRITE_TAC[] THEN EXISTS_TAC ``0:num`` THEN REPEAT STRIP_TAC THEN 17973 SIMP_TAC std_ss [] THEN MATCH_MP_TAC SUM_LE THEN 17974 ASM_SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG, IN_INTER, IN_NUMSEG]); 17975 17976val SERIES_DROP_POS = store_thm ("SERIES_DROP_POS", 17977 ``!f s a. 17978 (f sums a) s /\ (!x. x IN s ==> &0 <= f x) 17979 ==> &0 <= a``, 17980 REPEAT STRIP_TAC THEN 17981 MP_TAC(ISPECL [``(\n. 0):num->real``, ``f:num->real``, ``s:num->bool``, 17982 ``0:real``, ``a:real``] SERIES_DROP_LE) THEN 17983 ASM_SIMP_TAC std_ss [SUMS_0]); 17984 17985val SERIES_BOUND = store_thm ("SERIES_BOUND", 17986 ``!f:num->real g s a b. 17987 (f sums a) s /\ (g sums b) s /\ 17988 (!i. i IN s ==> abs(f i) <= g i) 17989 ==> abs (a) <= b``, 17990 REWRITE_TAC[sums] THEN REPEAT STRIP_TAC THEN 17991 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_ABS_UBOUND) THEN 17992 EXISTS_TAC ``\n. sum (s INTER ((0:num)..n)) (f:num->real)`` THEN 17993 ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN 17994 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC ``0:num`` THEN 17995 X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN 17996 SIMP_TAC std_ss [] THEN MATCH_MP_TAC REAL_LE_TRANS THEN 17997 EXISTS_TAC ``sum (s INTER ((0:num)..m)) g`` THEN CONJ_TAC THEN 17998 ASM_SIMP_TAC std_ss [SUM_ABS_LE, IN_INTER, FINITE_NUMSEG, FINITE_INTER] THEN 17999 RULE_ASSUM_TAC(REWRITE_RULE[GSYM sums]) THEN 18000 UNDISCH_TAC ``(g sums b) s`` THEN 18001 GEN_REWR_TAC LAND_CONV [GSYM SERIES_RESTRICT] THEN 18002 REWRITE_TAC[GSYM FROM_0] THEN DISCH_THEN(MP_TAC o SPEC ``m + 1:num`` o MATCH_MP 18003 (ONCE_REWRITE_RULE[CONJ_EQ_IMP] SUMS_OFFSET)) THEN 18004 KNOW_TAC ``0 < m + 1 /\ 0 <= m + 1:num`` THENL 18005 [ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 18006 REWRITE_TAC[ARITH_PROVE ``0 < m + 1:num``, o_DEF, ADD_SUB] THEN 18007 SIMP_TAC std_ss [GSYM SUM_RESTRICT_SET] THEN 18008 SIMP_TAC std_ss [ETA_AX] THEN 18009 DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] SERIES_DROP_POS)) THEN 18010 REWRITE_TAC[ONCE_REWRITE_RULE[INTER_COMM] (GSYM INTER_DEF), 18011 REAL_SUB_LE] THEN 18012 DISCH_THEN MATCH_MP_TAC THEN REPEAT STRIP_TAC THEN SIMP_TAC std_ss [] THEN 18013 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [REAL_LE_REFL] THEN 18014 ASM_MESON_TAC[REAL_ARITH ``abs(x:real) <= y ==> &0 <= y``]); 18015 18016(* ------------------------------------------------------------------------- *) 18017(* Similar combining theorems for infsum. *) 18018(* ------------------------------------------------------------------------- *) 18019 18020val INFSUM_LINEAR = store_thm ("INFSUM_LINEAR", 18021 ``!f h s. summable s f /\ linear h 18022 ==> (infsum s (\n. h(f n)) = h(infsum s f))``, 18023 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN 18024 MATCH_MP_TAC SERIES_LINEAR THEN ASM_REWRITE_TAC[SUMS_INFSUM]); 18025 18026val INFSUM_0 = store_thm ("INFSUM_0", 18027 ``infsum s (\i. 0) = 0``, 18028 MATCH_MP_TAC INFSUM_UNIQUE THEN REWRITE_TAC[SERIES_0]); 18029 18030val INFSUM_ADD = store_thm ("INFSUM_ADD", 18031 ``!x y s. summable s x /\ summable s y 18032 ==> (infsum s (\i. x i + y i) = infsum s x + infsum s y)``, 18033 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN 18034 MATCH_MP_TAC SERIES_ADD THEN ASM_REWRITE_TAC[SUMS_INFSUM]); 18035 18036val INFSUM_SUB = store_thm ("INFSUM_SUB", 18037 ``!x y s. summable s x /\ summable s y 18038 ==> (infsum s (\i. x i - y i) = infsum s x - infsum s y)``, 18039 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN 18040 MATCH_MP_TAC SERIES_SUB THEN ASM_REWRITE_TAC[SUMS_INFSUM]); 18041 18042val INFSUM_CMUL = store_thm ("INFSUM_CMUL", 18043 ``!s x c. summable s x ==> (infsum s (\n. c * x n) = c * infsum s x)``, 18044 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN 18045 MATCH_MP_TAC SERIES_CMUL THEN ASM_REWRITE_TAC[SUMS_INFSUM]); 18046 18047val INFSUM_NEG = store_thm ("INFSUM_NEG", 18048 ``!s x. summable s x ==> (infsum s (\n. -(x n)) = -(infsum s x))``, 18049 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN 18050 MATCH_MP_TAC SERIES_NEG THEN ASM_REWRITE_TAC[SUMS_INFSUM]); 18051 18052val INFSUM_EQ = store_thm ("INFSUM_EQ", 18053 ``!f g k. summable k f /\ summable k g /\ (!x. x IN k ==> (f x = g x)) 18054 ==> (infsum k f = infsum k g)``, 18055 REPEAT STRIP_TAC THEN REWRITE_TAC[infsum] THEN 18056 AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[SUMS_EQ, SUMS_INFSUM]); 18057 18058val INFSUM_RESTRICT = store_thm ("INFSUM_RESTRICT", 18059 ``!k a:num->real. 18060 infsum univ(:num) (\n. if n IN k then a n else 0) = infsum k a``, 18061 REPEAT GEN_TAC THEN 18062 MP_TAC(ISPECL [``a:num->real``, ``k:num->bool``] SUMMABLE_RESTRICT) THEN 18063 ASM_CASES_TAC ``summable k (a:num->real)`` THEN ASM_REWRITE_TAC[] THEN 18064 STRIP_TAC THENL 18065 [MATCH_MP_TAC INFSUM_UNIQUE THEN 18066 ASM_REWRITE_TAC[SERIES_RESTRICT, SUMS_INFSUM], 18067 FULL_SIMP_TAC std_ss [summable, NOT_EXISTS_THM] THEN 18068 ASM_REWRITE_TAC[infsum]]); 18069 18070val PARTIAL_SUMS_COMPONENT_LE_INFSUM = store_thm ("PARTIAL_SUMS_COMPONENT_LE_INFSUM", 18071 ``!f:num->real s n. 18072 (!i. i IN s ==> &0 <= f i) /\ summable s f 18073 ==> (sum (s INTER ((0:num)..n)) f) <= (infsum s f)``, 18074 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUMS_INFSUM] THEN 18075 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 18076 REWRITE_TAC[sums, LIM_SEQUENTIALLY] THEN DISCH_TAC THEN 18077 REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN 18078 FIRST_X_ASSUM(MP_TAC o SPEC 18079 ``sum (s INTER ((0:num)..n)) (f:num->real) - (infsum s f)``) THEN 18080 ASM_REWRITE_TAC[REAL_SUB_LT] THEN 18081 DISCH_THEN(X_CHOOSE_THEN ``N:num`` (MP_TAC o SPEC ``N + n:num``)) THEN 18082 REWRITE_TAC[LE_ADD, REAL_NOT_LT, dist] THEN 18083 MATCH_MP_TAC REAL_LE_TRANS THEN 18084 EXISTS_TAC ``abs((sum (s INTER ((0:num)..N + n)) f - infsum s f:real))`` THEN 18085 ASM_SIMP_TAC std_ss [REAL_LE_REFL] THEN 18086 MATCH_MP_TAC(REAL_ARITH ``s < a /\ a <= b ==> a - s <= abs(b - s:real)``) THEN 18087 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN 18088 KNOW_TAC ``sum (s INTER ((0:num)..n)) f <= 18089 sum (s INTER ((0:num)..n) UNION s INTER (n + (1:num)..n + N)) f`` THENL 18090 [ALL_TAC, SIMP_TAC std_ss [GSYM NUMSEG_ADD_SPLIT, ZERO_LESS_EQ, GSYM UNION_OVER_INTER]] THEN 18091 KNOW_TAC ``(sum (s INTER ((0:num)..n) UNION s INTER (n + (1:num)..n + N)) f = 18092 sum (s INTER ((0:num)..n)) f + sum (s INTER (n + (1:num)..n + N)) f)`` THENL 18093 [MATCH_MP_TAC SUM_UNION THEN 18094 SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG, DISJOINT_DEF, EXTENSION] THEN 18095 SIMP_TAC arith_ss [IN_INTER, NOT_IN_EMPTY, IN_NUMSEG] THEN CCONTR_TAC THEN 18096 FULL_SIMP_TAC arith_ss [], ALL_TAC] THEN 18097 DISCH_THEN SUBST1_TAC THEN 18098 REWRITE_TAC[REAL_LE_ADDR] THEN 18099 ASM_SIMP_TAC std_ss [] THEN MATCH_MP_TAC SUM_POS_LE THEN 18100 ASM_SIMP_TAC std_ss [FINITE_INTER, IN_INTER, FINITE_NUMSEG]); 18101 18102val PARTIAL_SUMS_DROP_LE_INFSUM = store_thm ("PARTIAL_SUMS_DROP_LE_INFSUM", 18103 ``!f s n. 18104 (!i. i IN s ==> &0 <= f i) /\ 18105 summable s f 18106 ==> sum (s INTER ((0:num)..n)) f <= (infsum s f)``, 18107 REPEAT STRIP_TAC THEN 18108 MATCH_MP_TAC PARTIAL_SUMS_COMPONENT_LE_INFSUM THEN 18109 ASM_REWRITE_TAC[LESS_EQ_REFL]); 18110 18111(* ------------------------------------------------------------------------- *) 18112(* Cauchy criterion for series. *) 18113(* ------------------------------------------------------------------------- *) 18114 18115val SEQUENCE_CAUCHY_WLOG = store_thm ("SEQUENCE_CAUCHY_WLOG", 18116 ``!P s. (!m n:num. P m /\ P n ==> dist(s m,s n) < e) <=> 18117 (!m n. P m /\ P n /\ m <= n ==> dist(s m,s n) < e)``, 18118 MESON_TAC[DIST_SYM, LE_CASES]); 18119 18120val SUM_DIFF_LEMMA = store_thm ("SUM_DIFF_LEMMA", 18121 ``!f:num->real k m n. 18122 m <= n 18123 ==> (sum (k INTER ((0:num) .. n)) f - sum (k INTER ((0:num)..m)) f = 18124 sum (k INTER ((m+1:num) .. n)) f)``, 18125 REPEAT STRIP_TAC THEN 18126 MP_TAC(ISPECL [``f:num->real``, ``k INTER ((0:num)..n)``, ``k INTER ((0:num)..m)``] 18127 SUM_DIFF) THEN 18128 KNOW_TAC ``FINITE (k INTER ((0:num) .. n)) /\ 18129 k INTER ((0:num) .. m) SUBSET k INTER ((0:num) .. n)`` THENL 18130 [SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN MATCH_MP_TAC 18131 (SET_RULE ``s SUBSET t ==> (u INTER s SUBSET u INTER t)``) THEN 18132 REWRITE_TAC[SUBSET_DEF, IN_NUMSEG] THEN POP_ASSUM MP_TAC THEN ARITH_TAC, 18133 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 18134 DISCH_THEN(SUBST1_TAC o SYM) THEN AP_THM_TAC THEN AP_TERM_TAC THEN 18135 REWRITE_TAC[SET_RULE 18136 ``(k INTER s) DIFF (k INTER t) = k INTER (s DIFF t)``] THEN 18137 AP_TERM_TAC THEN REWRITE_TAC[EXTENSION, IN_DIFF, IN_NUMSEG] THEN 18138 POP_ASSUM MP_TAC THEN ARITH_TAC]); 18139 18140val ABS_SUM_TRIVIAL_LEMMA = store_thm ("ABS_SUM_TRIVIAL_LEMMA", 18141 ``!e:real. &0 < e ==> (P ==> abs(sum(s INTER (m..n)) f) < e <=> 18142 P ==> n < m \/ abs(sum(s INTER (m..n)) f) < e)``, 18143 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``n:num < m`` THEN ASM_REWRITE_TAC[] THEN 18144 FIRST_X_ASSUM(SUBST1_TAC o REWRITE_RULE [GSYM NUMSEG_EMPTY]) THEN 18145 ASM_REWRITE_TAC[SUM_CLAUSES, ABS_0, INTER_EMPTY]); 18146 18147val SERIES_CAUCHY = store_thm ("SERIES_CAUCHY", 18148 ``!f s. (?l. (f sums l) s) = 18149 !e. &0 < e 18150 ==> ?N. !m n. m >= N 18151 ==> abs(sum(s INTER (m..n)) f) < e``, 18152 REPEAT GEN_TAC THEN REWRITE_TAC[sums, CONVERGENT_EQ_CAUCHY, cauchy] THEN 18153 SIMP_TAC std_ss [SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN 18154 SIMP_TAC std_ss [dist, SUM_DIFF_LEMMA, ABS_SUM_TRIVIAL_LEMMA] THEN 18155 REWRITE_TAC[GE, TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN 18156 REWRITE_TAC[NOT_LESS, ARITH_PROVE 18157 ``(N:num <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=> 18158 N + 1 <= m + 1 /\ m + 1 <= n``] THEN 18159 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN 18160 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN 18161 EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THENL 18162 [EXISTS_TAC ``N + 1:num``, EXISTS_TAC ``N:num``] THEN 18163 REPEAT STRIP_TAC THEN 18164 ASM_SIMP_TAC std_ss [ARITH_PROVE ``N + 1 <= m + 1 ==> N <= m + 1:num``] THEN 18165 FIRST_X_ASSUM(MP_TAC o SPECL [``m - 1:num``, ``n:num``]) THEN 18166 SUBGOAL_THEN ``m - 1 + 1 = m:num`` SUBST_ALL_TAC THENL 18167 [ALL_TAC, 18168 KNOW_TAC ``N <= m - 1 /\ m <= n:num`` THENL 18169 [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC []]] THEN 18170 ASM_ARITH_TAC); 18171 18172val SUMMABLE_CAUCHY = store_thm ("SUMMABLE_CAUCHY", 18173 ``!f s. summable s f <=> 18174 !e. &0 < e 18175 ==> ?N. !m n. m >= N ==> abs(sum(s INTER (m..n)) f) < e``, 18176 REWRITE_TAC[summable, GSYM SERIES_CAUCHY]); 18177 18178val SUMMABLE_IFF_EVENTUALLY = store_thm ("SUMMABLE_IFF_EVENTUALLY", 18179 ``!f g k. (?N. !n. N <= n /\ n IN k ==> (f n = g n)) 18180 ==> (summable k f <=> summable k g)``, 18181 REWRITE_TAC[summable, SERIES_CAUCHY] THEN REPEAT GEN_TAC THEN 18182 DISCH_THEN(X_CHOOSE_THEN ``N0:num`` STRIP_ASSUME_TAC) THEN 18183 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN 18184 BETA_TAC THEN AP_TERM_TAC THEN EQ_TAC THEN 18185 DISCH_THEN(X_CHOOSE_THEN ``N1:num`` 18186 (fn th => EXISTS_TAC ``N0 + N1:num`` THEN MP_TAC th)) THEN 18187 DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN 18188 POP_ASSUM (MP_TAC o Q.SPECL [`m:num`,`n:num`]) THEN 18189 DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN 18190 (KNOW_TAC ``m >= N1:num`` THENL [POP_ASSUM MP_TAC THEN ARITH_TAC, 18191 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC]) THEN 18192 MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN 18193 MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC std_ss [IN_INTER, IN_NUMSEG] THEN 18194 REPEAT STRIP_TAC THENL [ALL_TAC, CONV_TAC SYM_CONV] THEN 18195 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN 18196 ASM_ARITH_TAC); 18197 18198val SUMMABLE_EQ_EVENTUALLY = store_thm ("SUMMABLE_EQ_EVENTUALLY", 18199 ``!f g k. (?N. !n. N <= n /\ n IN k ==> (f n = g n)) /\ summable k f 18200 ==> summable k g``, 18201 MESON_TAC[SUMMABLE_IFF_EVENTUALLY]); 18202 18203val SUMMABLE_IFF_COFINITE = store_thm ("SUMMABLE_IFF_COFINITE", 18204 ``!f s t. FINITE((s DIFF t) UNION (t DIFF s)) 18205 ==> (summable s f <=> summable t f)``, 18206 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM SUMMABLE_RESTRICT] THEN 18207 MATCH_MP_TAC SUMMABLE_IFF_EVENTUALLY THEN 18208 FIRST_ASSUM(MP_TAC o ISPEC ``\x:num.x`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN 18209 DISCH_THEN(X_CHOOSE_THEN ``N:num`` MP_TAC) THEN REWRITE_TAC[IN_UNIV] THEN 18210 DISCH_TAC THEN EXISTS_TAC ``N + 1:num`` THEN 18211 REWRITE_TAC[ARITH_PROVE ``N + 1 <= n <=> ~(n <= N:num)``] THEN ASM_SET_TAC[]); 18212 18213val SUMMABLE_EQ_COFINITE = store_thm ("SUMMABLE_EQ_COFINITE", 18214 ``!f s t. FINITE((s DIFF t) UNION (t DIFF s)) /\ summable s f 18215 ==> summable t f``, 18216 MESON_TAC[SUMMABLE_IFF_COFINITE]); 18217 18218val SUMMABLE_FROM_ELSEWHERE = store_thm ("SUMMABLE_FROM_ELSEWHERE", 18219 ``!f m n. summable (from m) f ==> summable (from n) f``, 18220 REPEAT GEN_TAC THEN 18221 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] SUMMABLE_EQ_COFINITE) THEN 18222 MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``(0:num)..(m+n)`` THEN 18223 SIMP_TAC std_ss [FINITE_NUMSEG, SUBSET_DEF, IN_NUMSEG, IN_UNION, IN_DIFF, IN_FROM] THEN 18224 ARITH_TAC); 18225 18226(* ------------------------------------------------------------------------- *) 18227(* Uniform vesion of Cauchy criterion. *) 18228(* ------------------------------------------------------------------------- *) 18229 18230val SERIES_CAUCHY_UNIFORM = store_thm ("SERIES_CAUCHY_UNIFORM", 18231 ``!P f:'a->num->real k. 18232 (?l. !e. &0 < e 18233 ==> ?N. !n x. N <= n /\ P x 18234 ==> dist(sum(k INTER ((0:num)..n)) (f x), 18235 l x) < e) <=> 18236 (!e. &0 < e ==> ?N. !m n x. N <= m /\ P x 18237 ==> abs(sum(k INTER (m..n)) (f x)) < e)``, 18238 REPEAT GEN_TAC THEN 18239 SIMP_TAC std_ss [sums, UNIFORMLY_CONVERGENT_EQ_CAUCHY, cauchy] THEN 18240 ONCE_REWRITE_TAC [METIS [] ``(dist (sum (k INTER (0 .. n)) (f x), 18241 sum (k INTER (0 .. n')) (f x)) < e) = 18242 (\n n' x. dist (sum (k INTER (0 .. n)) (f x), 18243 sum (k INTER (0 .. n')) (f x)) < e) n n' x``] THEN 18244 ONCE_REWRITE_TAC[MESON[] 18245 ``(!m n:num y. N <= m /\ N <= n /\ P y ==> Q m n y) <=> 18246 (!y. P y ==> !m n. N <= m /\ N <= n ==> Q m n y)``] THEN 18247 SIMP_TAC std_ss [SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN 18248 SIMP_TAC std_ss [dist, SUM_DIFF_LEMMA, ABS_SUM_TRIVIAL_LEMMA] THEN 18249 REWRITE_TAC[GE, TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN 18250 REWRITE_TAC[NOT_LESS, ARITH_PROVE 18251 ``(N <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=> 18252 N + 1 <= m + 1 /\ m + 1 <= n:num``] THEN 18253 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN 18254 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN 18255 EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THENL 18256 [EXISTS_TAC ``N + 1:num``, EXISTS_TAC ``N:num``] THEN 18257 REPEAT STRIP_TAC THEN 18258 ASM_SIMP_TAC std_ss [ARITH_PROVE ``N + 1 <= m + 1 ==> N <= m + 1:num``] THEN 18259 FIRST_X_ASSUM(MP_TAC o SPEC ``x:'a``) THEN ASM_REWRITE_TAC[] THEN 18260 DISCH_THEN(MP_TAC o SPECL [``m - 1:num``, ``n:num``]) THEN 18261 SUBGOAL_THEN ``m - 1 + 1 = m:num`` SUBST_ALL_TAC THENL 18262 [ASM_ARITH_TAC, ALL_TAC] THEN 18263 KNOW_TAC ``N <= m - 1 /\ m <= n:num`` THENL 18264 [ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC []]); 18265 18266(* ------------------------------------------------------------------------- *) 18267(* So trivially, terms of a convergent series go to zero. *) 18268(* ------------------------------------------------------------------------- *) 18269 18270val SERIES_GOESTOZERO = store_thm ("SERIES_GOESTOZERO", 18271 ``!s x. summable s x 18272 ==> !e. &0 < e 18273 ==> eventually (\n. n IN s ==> abs(x n) < e) sequentially``, 18274 REPEAT GEN_TAC THEN REWRITE_TAC[summable, SERIES_CAUCHY] THEN 18275 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN 18276 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN 18277 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 18278 X_GEN_TAC ``n:num`` THEN BETA_TAC THEN REPEAT STRIP_TAC THEN 18279 FIRST_X_ASSUM(MP_TAC o SPECL [``n:num``, ``n:num``]) THEN 18280 ASM_SIMP_TAC std_ss [NUMSEG_SING, GE, SET_RULE ``n IN s ==> (s INTER {n} = {n})``] THEN 18281 REWRITE_TAC[SUM_SING]); 18282 18283val SUMMABLE_IMP_TOZERO = store_thm ("SUMMABLE_IMP_TOZERO", 18284 ``!f:num->real k. 18285 summable k f 18286 ==> ((\n. if n IN k then f(n) else 0) --> 0) sequentially``, 18287 REPEAT GEN_TAC THEN GEN_REWR_TAC LAND_CONV [GSYM SUMMABLE_RESTRICT] THEN 18288 REWRITE_TAC[summable, LIM_SEQUENTIALLY, INTER_UNIV, sums] THEN 18289 DISCH_THEN(X_CHOOSE_TAC ``l:real``) THEN X_GEN_TAC ``e:real`` THEN 18290 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 18291 ASM_SIMP_TAC std_ss [REAL_HALF, LEFT_IMP_EXISTS_THM] THEN 18292 X_GEN_TAC ``N:num`` THEN DISCH_TAC THEN EXISTS_TAC ``N + 1:num`` THEN 18293 X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 18294 UNDISCH_TAC ``!n:num. N <= n ==> 18295 dist (sum ((0:num) .. n) (\n. if n IN k then f n else 0),l) < e / 2:real`` THEN 18296 DISCH_TAC THEN 18297 FIRST_X_ASSUM(fn th => 18298 MP_TAC(SPEC ``n - 1:num`` th) THEN MP_TAC(SPEC ``n:num`` th)) THEN 18299 ASM_SIMP_TAC std_ss [ARITH_PROVE ``N + 1 <= n ==> N <= n /\ N <= n - 1:num``] THEN 18300 ABBREV_TAC ``m = n - 1:num`` THEN 18301 SUBGOAL_THEN ``n = SUC m`` SUBST1_TAC THENL 18302 [ASM_ARITH_TAC, ALL_TAC] THEN 18303 SIMP_TAC std_ss [SUM_CLAUSES_NUMSEG, ZERO_LESS_EQ, dist] THEN 18304 SIMP_TAC std_ss [REAL_ARITH ``abs(x - 0) = abs x:real``] THEN 18305 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [ABS_0] THEN 18306 SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 18307 REAL_ARITH_TAC); 18308 18309val SUMMABLE_IMP_BOUNDED = store_thm ("SUMMABLE_IMP_BOUNDED", 18310 ``!f:num->real k. summable k f ==> bounded (IMAGE f k)``, 18311 REPEAT GEN_TAC THEN 18312 DISCH_THEN(MP_TAC o MATCH_MP SUMMABLE_IMP_TOZERO) THEN 18313 DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN 18314 SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE, IN_UNIV] THEN 18315 METIS_TAC[REAL_LT_IMP_LE, ABS_0]); 18316 18317val SUMMABLE_IMP_SUMS_BOUNDED = store_thm ("SUMMABLE_IMP_SUMS_BOUNDED", 18318 ``!f:num->real k. 18319 summable (from k) f ==> bounded { sum(k..n) f | n IN univ(:num) }``, 18320 SIMP_TAC std_ss [summable, sums, LEFT_IMP_EXISTS_THM] THEN REPEAT GEN_TAC THEN 18321 DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN 18322 SIMP_TAC std_ss [FROM_INTER_NUMSEG, GSYM IMAGE_DEF]); 18323 18324(* ------------------------------------------------------------------------- *) 18325(* Comparison test. *) 18326(* ------------------------------------------------------------------------- *) 18327 18328val SERIES_COMPARISON = store_thm ("SERIES_COMPARISON", 18329 ``!f g s. (?l. (g sums l) s) /\ 18330 (?N. !n. n >= N /\ n IN s ==> abs(f n) <= g n) 18331 ==> ?l:real. (f sums l) s``, 18332 REPEAT GEN_TAC THEN REWRITE_TAC[SERIES_CAUCHY] THEN 18333 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC ``N1:num``)) THEN 18334 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN 18335 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN 18336 DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN 18337 EXISTS_TAC ``N1 + N2:num`` THEN 18338 MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``] THEN DISCH_TAC THEN 18339 MATCH_MP_TAC REAL_LET_TRANS THEN 18340 EXISTS_TAC ``abs (sum (s INTER (m .. n)) g)`` THEN CONJ_TAC THENL 18341 [SIMP_TAC std_ss [FINITE_INTER_NUMSEG] THEN 18342 MATCH_MP_TAC(REAL_ARITH ``x <= a ==> x <= abs(a:real)``) THEN 18343 MATCH_MP_TAC SUM_ABS_LE THEN 18344 REWRITE_TAC[FINITE_INTER_NUMSEG, IN_INTER, IN_NUMSEG] THEN 18345 ASM_MESON_TAC[ARITH_PROVE ``m >= N1 + N2:num /\ m <= x ==> x >= N1``], 18346 ASM_MESON_TAC[ARITH_PROVE ``m >= N1 + N2:num ==> m >= N2``]]); 18347 18348val SUMMABLE_COMPARISON = store_thm ("SUMMABLE_COMPARISON", 18349 ``!f g s. summable s g /\ 18350 (?N. !n. n >= N /\ n IN s ==> abs(f n) <= g n) 18351 ==> summable s f``, 18352 REWRITE_TAC[summable, SERIES_COMPARISON]); 18353 18354val SERIES_ABSCONV_IMP_CONV = store_thm ("SERIES_ABSCONV_IMP_CONV", 18355 ``!x:num->real k. summable k (\n. (abs(x n))) ==> summable k x``, 18356 REWRITE_TAC[summable] THEN REPEAT STRIP_TAC THEN 18357 MATCH_MP_TAC SERIES_COMPARISON THEN 18358 EXISTS_TAC ``\n:num. abs(x n:real)`` THEN 18359 ASM_SIMP_TAC std_ss [o_DEF, REAL_LE_REFL] THEN ASM_MESON_TAC[]); 18360 18361val SUMMABLE_SUBSET_ABSCONV = store_thm ("SUMMABLE_SUBSET_ABSCONV", 18362 ``!x:num->real s t. 18363 summable s (\n. abs(x n)) /\ t SUBSET s 18364 ==> summable t (\n. abs(x n))``, 18365 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_SUBSET THEN 18366 EXISTS_TAC ``s:num->bool`` THEN ASM_REWRITE_TAC[] THEN 18367 REWRITE_TAC[summable] THEN MATCH_MP_TAC SERIES_COMPARISON THEN 18368 EXISTS_TAC ``\n:num. abs(x n:real)`` THEN 18369 ASM_SIMP_TAC std_ss [o_DEF, GSYM summable] THEN 18370 EXISTS_TAC ``0:num`` THEN REPEAT STRIP_TAC THEN COND_CASES_TAC THEN 18371 SIMP_TAC std_ss [REAL_LE_REFL, ABS_ABS, ABS_0, ABS_POS]); 18372 18373val SERIES_COMPARISON_BOUND = store_thm ("SERIES_COMPARISON_BOUND", 18374 ``!f:num->real g s a. 18375 (g sums a) s /\ (!i. i IN s ==> abs(f i) <= (g i)) 18376 ==> ?l. (f sums l) s /\ abs(l) <= a``, 18377 REPEAT STRIP_TAC THEN 18378 MP_TAC(ISPECL [``f:num->real``, ``g:num->real``, ``s:num->bool``] 18379 SUMMABLE_COMPARISON) THEN 18380 SIMP_TAC std_ss [o_DEF, GE, ETA_AX, summable] THEN 18381 KNOW_TAC ``(?l. ((g:num->real) sums l) s) /\ 18382 (?N:num. !n. N <= n /\ n IN s ==> abs (f n) <= g n)`` THENL 18383 [ASM_MESON_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 18384 STRIP_TAC THEN EXISTS_TAC ``l:real`` THEN ASM_REWRITE_TAC[] THEN 18385 RULE_ASSUM_TAC(REWRITE_RULE[FROM_0, INTER_UNIV, sums]) THEN 18386 MATCH_MP_TAC SERIES_BOUND THEN MAP_EVERY EXISTS_TAC 18387 [``f:num->real``, ``g:num->real``, ``s:num->bool``] THEN 18388 ASM_SIMP_TAC std_ss [sums, o_DEF, ETA_AX]); 18389 18390(* ------------------------------------------------------------------------- *) 18391(* Uniform version of comparison test. *) 18392(* ------------------------------------------------------------------------- *) 18393 18394val SERIES_COMPARISON_UNIFORM = store_thm ("SERIES_COMPARISON_UNIFORM", 18395 ``!f g P s. (?l. (g sums l) s) /\ 18396 (?N. !n x. N <= n /\ n IN s /\ P x ==> abs(f x n) <= g n) 18397 ==> ?l:'a->real. 18398 !e. &0 < e 18399 ==> ?N. !n x. N <= n /\ P x 18400 ==> dist(sum(s INTER ((0:num)..n)) (f x), 18401 l x) < e``, 18402 REPEAT GEN_TAC THEN SIMP_TAC std_ss [GE, SERIES_CAUCHY, SERIES_CAUCHY_UNIFORM] THEN 18403 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC ``N1:num``)) THEN 18404 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN 18405 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN 18406 DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN 18407 EXISTS_TAC ``N1 + N2:num`` THEN 18408 MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``, ``x:'a``] THEN DISCH_TAC THEN 18409 MATCH_MP_TAC REAL_LET_TRANS THEN 18410 EXISTS_TAC ``abs (sum (s INTER (m .. n)) g)`` THEN CONJ_TAC THENL 18411 [SIMP_TAC std_ss [FINITE_INTER_NUMSEG] THEN 18412 MATCH_MP_TAC(REAL_ARITH ``x <= a ==> x <= abs(a:real)``) THEN 18413 MATCH_MP_TAC SUM_ABS_LE THEN 18414 REWRITE_TAC[FINITE_INTER_NUMSEG, IN_INTER, IN_NUMSEG] THEN 18415 ASM_MESON_TAC[ARITH_PROVE ``N1 + N2:num <= m /\ m <= x ==> N1 <= x``], 18416 ASM_MESON_TAC[ARITH_PROVE ``N1 + N2:num <= m ==> N2 <= m``]]); 18417 18418(* ------------------------------------------------------------------------- *) 18419(* Ratio test. *) 18420(* ------------------------------------------------------------------------- *) 18421 18422val SERIES_RATIO = store_thm ("SERIES_RATIO", 18423 ``!c a s N. 18424 c < &1 /\ 18425 (!n. n >= N ==> abs(a(SUC n)) <= c * abs(a(n))) 18426 ==> ?l:real. (a sums l) s``, 18427 REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN 18428 MATCH_MP_TAC SERIES_COMPARISON THEN 18429 DISJ_CASES_TAC(REAL_ARITH ``c <= &0 \/ &0 < c:real``) THENL 18430 [EXISTS_TAC ``\n:num. &0:real`` THEN REWRITE_TAC[o_DEF] THEN 18431 CONJ_TAC THENL [MESON_TAC[SERIES_0], ALL_TAC] THEN 18432 EXISTS_TAC ``N + 1:num`` THEN REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN 18433 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``c * abs(a(n - 1:num):real)`` THEN 18434 CONJ_TAC THENL 18435 [ASM_MESON_TAC[ARITH_PROVE ``N + 1 <= n ==> (SUC(n - 1) = n) /\ N <= n - 1``], 18436 ALL_TAC] THEN 18437 MATCH_MP_TAC(REAL_ARITH ``&0 <= -c * x ==> c * x <= &0:real``) THEN 18438 MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[ABS_POS] THEN 18439 UNDISCH_TAC ``c <= &0:real`` THEN REAL_ARITH_TAC, 18440 ASSUME_TAC(MATCH_MP REAL_LT_IMP_LE (ASSUME ``&0 < c:real``))] THEN 18441 EXISTS_TAC ``\n:num. abs(a(N):real) * c pow (n - N)`` THEN 18442 REWRITE_TAC[] THEN CONJ_TAC THENL 18443 [ALL_TAC, 18444 EXISTS_TAC ``N:num`` THEN 18445 SIMP_TAC std_ss [GE, LESS_EQ_EXISTS, CONJ_EQ_IMP, ADD_SUB2, LEFT_IMP_EXISTS_THM] THEN 18446 SUBGOAL_THEN ``!d:num. abs(a(N + d):real) <= abs(a N) * c pow d`` 18447 (fn th => MESON_TAC[th]) THEN INDUCT_TAC THEN 18448 REWRITE_TAC[ADD_CLAUSES, pow, REAL_MUL_RID, REAL_LE_REFL] THEN 18449 MATCH_MP_TAC REAL_LE_TRANS THEN 18450 EXISTS_TAC ``c * abs((a:num->real) (N + d:num))`` THEN 18451 ASM_SIMP_TAC std_ss [LE_ADD] THEN 18452 ASM_MESON_TAC[REAL_LE_LMUL, REAL_MUL_ASSOC, REAL_MUL_COMM]] THEN 18453 GEN_REWR_TAC I [SERIES_CAUCHY] THEN X_GEN_TAC ``e:real`` THEN 18454 SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN 18455 DISCH_TAC THEN SIMP_TAC std_ss [SUM_LMUL, FINITE_INTER, FINITE_NUMSEG] THEN 18456 ASM_CASES_TAC ``(a:num->real) N = 0:real`` THENL 18457 [ASM_REWRITE_TAC[ABS_0, REAL_MUL_LZERO, ABS_N], ALL_TAC] THEN 18458 MP_TAC(SPECL [``c:real``, ``((&1 - c) * e) / abs((a:num->real) N)``] 18459 REAL_ARCH_POW_INV) THEN 18460 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT_MUL, REAL_SUB_LT, GSYM ABS_NZ, GE] THEN 18461 DISCH_THEN(X_CHOOSE_TAC ``M:num``) THEN EXISTS_TAC ``N + M:num`` THEN 18462 MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``] THEN DISCH_TAC THEN 18463 MATCH_MP_TAC REAL_LET_TRANS THEN 18464 EXISTS_TAC ``abs(abs((a:num->real) N) * 18465 sum(m..n) (\i. c pow (i - N)))`` THEN 18466 CONJ_TAC THENL 18467 [REWRITE_TAC[ABS_MUL] THEN MATCH_MP_TAC REAL_LE_LMUL_IMP THEN 18468 REWRITE_TAC[ABS_POS] THEN 18469 MATCH_MP_TAC(REAL_ARITH ``&0 <= x /\ x <= y ==> abs x <= abs y:real``) THEN 18470 ASM_SIMP_TAC std_ss [SUM_POS_LE, FINITE_INTER_NUMSEG, POW_POS] THEN 18471 MATCH_MP_TAC SUM_SUBSET THEN ASM_SIMP_TAC std_ss [POW_POS] THEN 18472 REWRITE_TAC[FINITE_INTER_NUMSEG, FINITE_NUMSEG] THEN 18473 REWRITE_TAC[IN_INTER, IN_DIFF] THEN MESON_TAC[], 18474 ALL_TAC] THEN 18475 REWRITE_TAC[ABS_MUL, ABS_ABS] THEN 18476 DISJ_CASES_TAC(ARITH_PROVE ``n:num < m \/ m <= n``) THENL 18477 [ASM_SIMP_TAC std_ss [SUM_TRIV_NUMSEG, ABS_N, REAL_MUL_RZERO], ALL_TAC] THEN 18478 SUBGOAL_THEN ``(m = 0 + m) /\ (n = (n - m) + m:num)`` (CONJUNCTS_THEN SUBST1_TAC) THENL 18479 [UNDISCH_TAC ``m:num <= n`` THEN ARITH_TAC, ALL_TAC] THEN 18480 REWRITE_TAC[SUM_OFFSET] THEN UNDISCH_TAC ``N + M:num <= m`` THEN 18481 SIMP_TAC std_ss [LESS_EQ_EXISTS] THEN DISCH_THEN(X_CHOOSE_THEN ``d:num`` SUBST_ALL_TAC) THEN 18482 REWRITE_TAC[ARITH_PROVE ``(i + (N + M + d) - N:num) = (M + d) + i``] THEN 18483 ONCE_REWRITE_TAC[POW_ADD] THEN SIMP_TAC arith_ss [SUM_LMUL, SUM_GP] THEN 18484 ASM_SIMP_TAC std_ss [LT, REAL_LT_IMP_NE] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN 18485 FULL_SIMP_TAC std_ss [GSYM REAL_LT_RDIV_EQ, ABS_NZ, ABS_MUL] THEN 18486 REWRITE_TAC[GSYM POW_ABS] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN 18487 KNOW_TAC ``1 - c:real <> 0`` THENL 18488 [UNDISCH_TAC ``c < 1:real`` THEN REAL_ARITH_TAC, DISCH_TAC] THEN 18489 ASM_SIMP_TAC std_ss [GSYM REAL_LT_RDIV_EQ, ABS_DIV, REAL_POW_LT, ABS_NZ, REAL_ARITH 18490 ``&0 < c /\ c < &1 ==> &0 < abs c /\ &0 < abs(&1 - c:real)``, REAL_LT_LDIV_EQ] THEN 18491 ONCE_REWRITE_TAC [METIS [pow] ``x pow 0 = 1:real``] THEN 18492 MATCH_MP_TAC(REAL_ARITH 18493 ``&0 < x /\ x <= &1 /\ &1 <= e ==> abs(1 - x) < e:real``) THEN 18494 ASM_SIMP_TAC std_ss [REAL_POW_LT, REAL_POW_1_LE, REAL_LT_IMP_LE] THEN 18495 ASM_SIMP_TAC std_ss [REAL_ARITH ``c < &1 ==> (x * abs(&1 - c) = (&1 - c) * x:real)``] THEN 18496 KNOW_TAC ``(abs (c pow M) <> 0:real) /\ (abs (c pow d) <> 0:real)`` THENL 18497 [CONJ_TAC THEN ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN 18498 REWRITE_TAC [GSYM ABS_NZ] THEN ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN 18499 MATCH_MP_TAC REAL_LT_IMP_NE THEN METIS_TAC [REAL_POW_LT], STRIP_TAC] THEN 18500 FULL_SIMP_TAC real_ss [real_div, REAL_INV_MUL, ABS_NZ, REAL_POW_LT, REAL_POW_ADD, 18501 REAL_MUL_ASSOC, REAL_LT_IMP_NE, POW_ABS, ABS_MUL] THEN 18502 REWRITE_TAC[REAL_ARITH 18503 ``(a * b * c * d * e) = (e * ((a * b) * c)) * d:real``] THEN 18504 ASM_SIMP_TAC real_ss [GSYM real_div, REAL_LE_RDIV_EQ, REAL_POW_LT, REAL_MUL_LID, 18505 REAL_ARITH ``&0 < c ==> (abs c = c:real)``] THEN 18506 REWRITE_TAC [real_div] THEN 18507 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH 18508 ``xm < e ==> &0 <= (d - &1) * e ==> xm <= d * e:real``)) THEN 18509 MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THENL 18510 [REWRITE_TAC[REAL_SUB_LE, GSYM REAL_POW_INV] THEN 18511 MATCH_MP_TAC REAL_POW_LE_1 THEN 18512 MATCH_MP_TAC REAL_INV_1_LE THEN ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE], 18513 MATCH_MP_TAC REAL_LT_IMP_LE THEN 18514 ASM_SIMP_TAC std_ss [REAL_SUB_LT, REAL_LT_MUL, REAL_LT_DIV, ABS_NZ, GSYM real_div]]); 18515 18516(* ------------------------------------------------------------------------- *) 18517(* Ostensibly weaker versions of the boundedness of partial sums. *) 18518(* ------------------------------------------------------------------------- *) 18519 18520val BOUNDED_PARTIAL_SUMS = store_thm ("BOUNDED_PARTIAL_SUMS", 18521 ``!f:num->real k. 18522 bounded { sum(k..n) f | n IN univ(:num) } 18523 ==> bounded { sum(m..n) f | m IN univ(:num) /\ n IN univ(:num) }``, 18524 REPEAT STRIP_TAC THEN 18525 SUBGOAL_THEN ``bounded { sum((0:num)..n) f:real | n IN univ(:num) }`` MP_TAC THENL 18526 [FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [BOUNDED_POS]) THEN 18527 REWRITE_TAC[bounded_def] THEN 18528 SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, IN_UNIV] THEN 18529 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 18530 EXISTS_TAC ``sum { i:num | i < k} (\i. abs(f i:real)) + B`` THEN 18531 X_GEN_TAC ``i:num`` THEN ASM_CASES_TAC ``i:num < k`` THENL 18532 [MATCH_MP_TAC(REAL_ARITH 18533 ``!y. x <= y /\ y <= a /\ &0 < b ==> x <= a + b:real``) THEN 18534 EXISTS_TAC ``sum ((0:num)..i) (\i. abs(f i:real))`` THEN 18535 ASM_SIMP_TAC std_ss [SUM_ABS, FINITE_NUMSEG] THEN 18536 MATCH_MP_TAC SUM_SUBSET THEN 18537 REWRITE_TAC[FINITE_NUMSEG, FINITE_NUMSEG_LT, ABS_POS] THEN 18538 SIMP_TAC std_ss [IN_DIFF, IN_NUMSEG, GSPECIFICATION] THEN 18539 ASM_SIMP_TAC arith_ss [] THEN REAL_ARITH_TAC, 18540 ALL_TAC] THEN 18541 ASM_CASES_TAC ``k = 0:num`` THENL 18542 [FIRST_X_ASSUM SUBST_ALL_TAC THEN MATCH_MP_TAC(REAL_ARITH 18543 ``x <= B /\ &0 <= b ==> x <= b + B:real``) THEN 18544 ASM_SIMP_TAC std_ss [SUM_POS_LE, FINITE_NUMSEG_LT, ABS_POS], 18545 ALL_TAC] THEN 18546 MP_TAC(ISPECL [``f:num->real``, ``0:num``, ``k:num``, ``i:num``] 18547 SUM_COMBINE_L) THEN 18548 KNOW_TAC ``0 < k /\ 0 <= k /\ k <= i + 1:num`` THENL 18549 [ASM_SIMP_TAC arith_ss [], 18550 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 18551 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[NUMSEG_LT] THEN 18552 MATCH_MP_TAC(REAL_ARITH 18553 ``abs(x) <= a /\ abs(y) <= b ==> abs(x + y) <= a + b:real``) THEN 18554 ASM_SIMP_TAC std_ss [SUM_ABS, FINITE_NUMSEG], 18555 ALL_TAC] THEN 18556 DISCH_THEN(fn th => 18557 MP_TAC(MATCH_MP BOUNDED_DIFFS (W CONJ th)) THEN MP_TAC th) THEN 18558 REWRITE_TAC[AND_IMP_INTRO, GSYM BOUNDED_UNION] THEN 18559 MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b ==> c <=> b ==> a ==> c`] 18560 BOUNDED_SUBSET) THEN 18561 KNOW_TAC ``!x:real m n:num. 18562 (x = sum (m..n) f) 18563 ==> (?n. x = sum ((0:num)..n) f) \/ 18564 (?x' y. 18565 ((?n. x' = sum ((0:num)..n) f) /\ (?n. y = sum ((0:num)..n) f)) /\ 18566 (x = x' - y))`` THENL 18567 [ALL_TAC, SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNION, LEFT_IMP_EXISTS_THM, 18568 IN_UNIV, EXISTS_PROD] THEN METIS_TAC []] THEN 18569 MAP_EVERY X_GEN_TAC [``x:real``, ``m:num``, ``n:num``] THEN 18570 DISCH_THEN SUBST1_TAC THEN 18571 ASM_CASES_TAC ``m = 0:num`` THENL [ASM_MESON_TAC[], ALL_TAC] THEN 18572 ASM_CASES_TAC ``n:num < m`` THENL 18573 [DISJ2_TAC THEN REPEAT(EXISTS_TAC ``sum((0:num)..(0:num)) (f:num->real)``) THEN 18574 ASM_SIMP_TAC std_ss [SUM_TRIV_NUMSEG, REAL_SUB_REFL] THEN MESON_TAC[], 18575 ALL_TAC] THEN 18576 DISJ2_TAC THEN MAP_EVERY EXISTS_TAC 18577 [``sum((0:num)..n) (f:num->real)``, ``sum((0:num)..(m-1:num)) (f:num->real)``] THEN 18578 CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN 18579 MP_TAC(ISPECL [``f:num->real``, ``0:num``, ``m:num``, ``n:num``] 18580 SUM_COMBINE_L) THEN ASM_SIMP_TAC arith_ss [] THEN 18581 REAL_ARITH_TAC); 18582 18583(* ------------------------------------------------------------------------- *) 18584(* General Dirichlet convergence test (could make this uniform on a set). *) 18585(* ------------------------------------------------------------------------- *) 18586 18587val SUMMABLE_BILINEAR_PARTIAL_PRE = store_thm ("SUMMABLE_BILINEAR_PARTIAL_PRE", 18588 ``!f g h:real->real->real l k. 18589 bilinear h /\ 18590 ((\n. h (f(n + 1)) (g(n))) --> l) sequentially /\ 18591 summable (from k) (\n. h (f(n + 1) - f(n)) (g(n))) 18592 ==> summable (from k) (\n. h (f n) (g(n) - g(n - 1)))``, 18593 REPEAT GEN_TAC THEN 18594 SIMP_TAC std_ss [summable, sums, FROM_INTER_NUMSEG] THEN 18595 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 18596 FIRST_ASSUM(fn th => 18597 REWRITE_TAC[MATCH_MP BILINEAR_SUM_PARTIAL_PRE th]) THEN 18598 DISCH_THEN(X_CHOOSE_TAC ``l':real``) THEN 18599 EXISTS_TAC ``l - (h:real->real->real) ((f:num->real) k) (g(k - 1)) - l'`` THEN 18600 SIMP_TAC std_ss [LIM_CASES_SEQUENTIALLY] THEN 18601 KNOW_TAC ``(((\(n :num). 18602 (\n. (h :real -> real -> real) ((f :num -> real) (n + (1 :num))) 18603 ((g :num -> real) n) - h (f (k :num)) (g (k - (1 :num)))) n - 18604 (\n. sum (k .. n) (\(k :num). h (f (k + (1 :num)) - f k) (g k))) n) --> 18605 ((l :real) - h (f k) (g (k - (1 :num))) - (l' :real))) sequentially : 18606 bool)`` THENL 18607 [ALL_TAC, METIS_TAC []] THEN 18608 MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC std_ss [LIM_CONST] THEN 18609 KNOW_TAC ``(((\(n :num). 18610 (\n. (h :real -> real -> real) ((f :num -> real) (n + (1 :num))) 18611 ((g :num -> real) n)) n - (\n. h (f (k :num)) (g (k - (1 :num)))) n) --> 18612 ((l :real) - h (f k) (g (k - (1 :num))))) sequentially :bool)`` THENL 18613 [ALL_TAC, METIS_TAC []] THEN MATCH_MP_TAC LIM_SUB THEN 18614 ASM_SIMP_TAC std_ss [LIM_CONST]); 18615 18616val SERIES_DIRICHLET_BILINEAR = store_thm ("SERIES_DIRICHLET_BILINEAR", 18617 ``!f g h:real->real->real k m p l. 18618 bilinear h /\ 18619 bounded {sum (m..n) f | n IN univ(:num)} /\ 18620 summable (from p) (\n. abs(g(n + 1) - g(n))) /\ 18621 ((\n. h (g(n + 1)) (sum((1:num)..n) f)) --> l) sequentially 18622 ==> summable (from k) (\n. h (g n) (f n))``, 18623 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN 18624 EXISTS_TAC ``1:num`` THEN 18625 FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN 18626 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [BOUNDED_POS]) THEN 18627 SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, LEFT_IMP_EXISTS_THM, EXISTS_PROD] THEN 18628 X_GEN_TAC ``B:real`` THEN STRIP_TAC THEN 18629 FIRST_ASSUM(MP_TAC o MATCH_MP BILINEAR_BOUNDED_POS) THEN 18630 DISCH_THEN(X_CHOOSE_THEN ``C:real`` STRIP_ASSUME_TAC) THEN 18631 MATCH_MP_TAC SUMMABLE_EQ THEN 18632 EXISTS_TAC ``\n. (h:real->real->real) 18633 (g n) (sum ((1:num)..n) f - sum ((1:num)..n-1:num) f)`` THEN 18634 SIMP_TAC std_ss [IN_FROM, GSYM NUMSEG_RREC] THEN 18635 SIMP_TAC std_ss [SUM_CLAUSES, FINITE_NUMSEG, IN_NUMSEG, 18636 ARITH_PROVE ``1 <= n ==> ~(n <= n - 1:num)``] THEN 18637 CONJ_TAC THENL 18638 [REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [BILINEAR_RADD, BILINEAR_RSUB] THEN 18639 REAL_ARITH_TAC, 18640 ALL_TAC] THEN 18641 MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN EXISTS_TAC ``p:num`` THEN 18642 MP_TAC(ISPECL [``g:num->real``, ``\n. sum((1:num)..n) f:real``, 18643 ``h:real->real->real``, ``l:real``, ``p:num``] 18644 SUMMABLE_BILINEAR_PARTIAL_PRE) THEN 18645 SIMP_TAC std_ss [] THEN DISCH_THEN MATCH_MP_TAC THEN 18646 ASM_REWRITE_TAC[] THEN 18647 SUBGOAL_THEN 18648 ``summable (from p) ((\n. C * B * abs(g(n + 1) - g(n):real)))`` 18649 MP_TAC THENL [ASM_SIMP_TAC std_ss [o_DEF, SUMMABLE_CMUL], ALL_TAC] THEN 18650 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUMMABLE_COMPARISON) THEN 18651 EXISTS_TAC ``0:num`` THEN REWRITE_TAC[IN_FROM, GE, ZERO_LESS_EQ] THEN 18652 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC 18653 ``C * abs(g(n + 1:num) - g(n):real) * abs(sum ((1:num)..n) f:real)`` THEN 18654 ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN 18655 REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN 18656 ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN 18657 GEN_REWR_TAC RAND_CONV [REAL_MUL_SYM] THEN 18658 ASM_SIMP_TAC std_ss [REAL_LE_LMUL_IMP, ABS_POS]); 18659 18660val SERIES_DIRICHLET = store_thm ("SERIES_DIRICHLET", 18661 ``!f:num->real g N k m. 18662 bounded {sum (m..n) f | n IN univ(:num)} /\ 18663 (!n. N <= n ==> g(n + 1) <= g(n)) /\ 18664 (g --> 0) sequentially 18665 ==> summable (from k) (\n. g(n) * f(n))``, 18666 REPEAT STRIP_TAC THEN 18667 MP_TAC(ISPECL [``f:num->real``, ``g:num->real``, 18668 ``\x y:real. x * y``] SERIES_DIRICHLET_BILINEAR) THEN 18669 SIMP_TAC std_ss [o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN 18670 MAP_EVERY EXISTS_TAC [``m:num``, ``N:num``, ``0:real``] THEN CONJ_TAC THENL 18671 [SIMP_TAC std_ss [bilinear, linear] THEN 18672 REPEAT STRIP_TAC THEN REAL_ARITH_TAC, 18673 ALL_TAC] THEN 18674 ASM_REWRITE_TAC [] THEN 18675 FIRST_ASSUM(MP_TAC o SPEC ``1:num`` o MATCH_MP SEQ_OFFSET) THEN 18676 SIMP_TAC std_ss [o_THM] THEN DISCH_TAC THEN CONJ_TAC THENL 18677 [MATCH_MP_TAC SUMMABLE_EQ_EVENTUALLY THEN 18678 EXISTS_TAC ``(\n. (g:num->real)(n) - g(n + 1))`` THEN SIMP_TAC std_ss [] THEN 18679 CONJ_TAC THENL 18680 [EXISTS_TAC ``N:num`` THEN REPEAT STRIP_TAC THEN 18681 UNDISCH_TAC ``!n. N <= n ==> g (n + 1) <= (g:num->real) n`` THEN 18682 DISCH_THEN (MP_TAC o SPEC ``n:num``) THEN 18683 ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC, 18684 SIMP_TAC std_ss [summable, sums, FROM_INTER_NUMSEG, SUM_DIFFS] THEN 18685 SIMP_TAC std_ss [LIM_CASES_SEQUENTIALLY] THEN 18686 EXISTS_TAC ``(g(N:num)) - 0:real`` THEN 18687 ONCE_REWRITE_TAC [METIS [] ``((\n:num. g N - g (n + 1)) --> (g N - 0:real)) = 18688 ((\n. (\n. g N) n - (\n. g (n + 1)) n) --> (g N - 0))``] THEN 18689 MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[LIM_CONST]], 18690 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 18691 ONCE_REWRITE_TAC [METIS [] 18692 ``((\n. sum (1 .. n) f * (g:num->real) (n + 1)) --> 0) = 18693 ((\n. (\n. sum (1 .. n) f) n * (\n. g (n + 1)) n) --> 0)``] THEN 18694 MATCH_MP_TAC LIM_NULL_CMUL_BOUNDED THEN ASM_SIMP_TAC std_ss [o_DEF] THEN 18695 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN 18696 FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN 18697 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [BOUNDED_POS]) THEN 18698 SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, EXISTS_PROD] THEN METIS_TAC[]]); 18699 18700(* ------------------------------------------------------------------------- *) 18701(* Rearranging absolutely convergent series. *) 18702(* ------------------------------------------------------------------------- *) 18703 18704val lemma = prove ( 18705 ``!f:'a->real s t. 18706 FINITE s /\ FINITE t 18707 ==> (sum s f - sum t f = sum (s DIFF t) f - sum (t DIFF s) f)``, 18708 REPEAT STRIP_TAC THEN 18709 ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s DIFF (s INTER t)``] THEN 18710 ASM_SIMP_TAC std_ss [SUM_DIFF, INTER_SUBSET] THEN 18711 GEN_REWR_TAC (RAND_CONV o RAND_CONV o ONCE_DEPTH_CONV) [INTER_COMM] THEN 18712 REAL_ARITH_TAC); 18713 18714val SERIES_INJECTIVE_IMAGE_STRONG = store_thm ("SERIES_INJECTIVE_IMAGE_STRONG", 18715 ``!x:num->real s f. 18716 summable (IMAGE f s) (\n. abs(x n)) /\ 18717 (!m n. m IN s /\ n IN s /\ (f m = f n) ==> (m = n)) 18718 ==> ((\n. sum (IMAGE f s INTER ((0:num)..n)) x - 18719 sum (s INTER ((0:num)..n)) (x o f)) --> 0) 18720 sequentially``, 18721 REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN 18722 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 18723 UNDISCH_TAC ``(summable (IMAGE (f :num -> num) (s :num -> bool)) 18724 (\(n :num). abs ((x :num -> real) n)) :bool)`` THEN DISCH_TAC THEN 18725 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUMMABLE_CAUCHY]) THEN 18726 SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN 18727 GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [o_DEF] THEN 18728 SIMP_TAC std_ss [SUM_POS_LE, ABS_POS, FINITE_INTER, FINITE_NUMSEG] THEN 18729 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN 18730 ASM_REWRITE_TAC[dist, GE, REAL_SUB_RZERO, REAL_HALF] THEN 18731 DISCH_THEN(X_CHOOSE_THEN ``N:num`` STRIP_ASSUME_TAC) THEN 18732 UNDISCH_TAC ``!(m :num) (n :num). 18733 m IN (s :num -> bool) /\ n IN s /\ ((f :num -> num) m = f n) ==> 18734 (m = n)`` THEN DISCH_TAC THEN 18735 FIRST_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_ON_LEFT_INVERSE]) THEN 18736 DISCH_THEN(X_CHOOSE_TAC ``g:num->num``) THEN 18737 MP_TAC(ISPECL [``g:num->num``, ``((0:num)..N)``] UPPER_BOUND_FINITE_SET) THEN 18738 REWRITE_TAC[FINITE_NUMSEG, IN_NUMSEG, ZERO_LESS_EQ] THEN 18739 DISCH_THEN(X_CHOOSE_TAC ``P:num``) THEN 18740 EXISTS_TAC ``MAX N P:num`` THEN X_GEN_TAC ``n:num`` THEN 18741 REWRITE_TAC [MAX_DEF] THEN 18742 SIMP_TAC std_ss [ARITH_PROVE ``(if a < b then b else a) <= c <=> a <= c /\ b <= c:num``] THEN 18743 DISCH_TAC THEN 18744 W(MP_TAC o PART_MATCH (rand o rand) SUM_IMAGE o rand o 18745 rand o lhand o snd) THEN 18746 KNOW_TAC ``(!(x :num) (y :num). 18747 x IN (s :num -> bool) INTER ((0 :num) .. (n :num)) /\ 18748 y IN s INTER ((0 :num) .. n) /\ ((f :num -> num) x = f y) ==> 18749 (x = y))`` THENL 18750 [ASM_MESON_TAC[FINITE_INTER, FINITE_NUMSEG, IN_INTER], 18751 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 18752 DISCH_THEN(SUBST1_TAC o SYM)] THEN 18753 W(MP_TAC o PART_MATCH (lhand o rand) lemma o rand o lhand o snd) THEN 18754 SIMP_TAC std_ss [FINITE_INTER, IMAGE_FINITE, FINITE_NUMSEG] THEN 18755 DISCH_THEN SUBST1_TAC THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN 18756 MATCH_MP_TAC(REAL_ARITH 18757 ``abs a < x /\ abs b < y ==> abs(a - b:real) < x + y:real``) THEN 18758 CONJ_TAC THEN 18759 W(MP_TAC o PART_MATCH (lhand o rand) SUM_ABS o lhand o snd) THEN 18760 SIMP_TAC std_ss [FINITE_DIFF, IMAGE_FINITE, FINITE_INTER, FINITE_NUMSEG] THEN 18761 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN 18762 MATCH_MP_TAC REAL_LET_TRANS THENL 18763 [EXISTS_TAC 18764 ``sum((IMAGE (f:num->num) s) INTER (N..n)) (\i. abs(x i :real))`` THEN 18765 CONJ_TAC THENL [ALL_TAC, 18766 MATCH_MP_TAC (REAL_ARITH ``abs x < y ==> x < y:real``) THEN 18767 ASM_SIMP_TAC real_ss []] THEN 18768 MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN 18769 SIMP_TAC std_ss [ABS_POS, FINITE_INTER, FINITE_NUMSEG] THEN 18770 MATCH_MP_TAC(SET_RULE 18771 ``(!x. x IN s /\ f(x) IN n /\ ~(x IN m) ==> f x IN t) 18772 ==> (IMAGE f s INTER n) DIFF (IMAGE f (s INTER m)) SUBSET 18773 IMAGE f s INTER t``) THEN 18774 ASM_SIMP_TAC std_ss [IN_NUMSEG, ZERO_LESS_EQ, NOT_LESS_EQUAL] THEN 18775 X_GEN_TAC ``i:num`` THEN STRIP_TAC THEN 18776 MATCH_MP_TAC LESS_IMP_LESS_OR_EQ THEN ONCE_REWRITE_TAC[GSYM NOT_LESS_EQUAL] THEN 18777 UNDISCH_TAC ``!(x :num). x <= (N :num) ==> (g :num -> num) x <= (P :num)`` THEN 18778 DISCH_TAC THEN POP_ASSUM(MATCH_MP_TAC o ONCE_REWRITE_RULE [MONO_NOT_EQ]) THEN 18779 ASM_SIMP_TAC arith_ss [], 18780 MP_TAC(ISPECL [``f:num->num``, ``((0:num)..n)``] UPPER_BOUND_FINITE_SET) THEN 18781 REWRITE_TAC[FINITE_NUMSEG, IN_NUMSEG, ZERO_LESS_EQ] THEN 18782 DISCH_THEN(X_CHOOSE_TAC ``p:num``) THEN 18783 EXISTS_TAC 18784 ``sum(IMAGE (f:num->num) s INTER (N..p)) (\i. abs(x i :real))`` THEN 18785 CONJ_TAC THENL [ALL_TAC, 18786 MATCH_MP_TAC (REAL_ARITH ``abs x < y ==> x < y:real``) THEN 18787 ASM_SIMP_TAC real_ss []] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN 18788 SIMP_TAC std_ss [ABS_POS, FINITE_INTER, FINITE_NUMSEG] THEN 18789 MATCH_MP_TAC(SET_RULE 18790 ``(!x. x IN s /\ x IN n /\ ~(f x IN m) ==> f x IN t) 18791 ==> (IMAGE f (s INTER n) DIFF (IMAGE f s) INTER m) SUBSET 18792 (IMAGE f s INTER t)``) THEN 18793 ASM_SIMP_TAC arith_ss [IN_NUMSEG, ZERO_LESS_EQ]]); 18794 18795val SERIES_INJECTIVE_IMAGE = store_thm ("SERIES_INJECTIVE_IMAGE", 18796 ``!x:num->real s f l. 18797 summable (IMAGE f s) (\n. abs(x n)) /\ 18798 (!m n. m IN s /\ n IN s /\ (f m = f n) ==> (m = n)) 18799 ==> (((x o f) sums l) s <=> (x sums l) (IMAGE f s))``, 18800 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN REWRITE_TAC[sums] THEN 18801 MATCH_MP_TAC LIM_TRANSFORM_EQ THEN SIMP_TAC std_ss [] THEN 18802 MATCH_MP_TAC SERIES_INJECTIVE_IMAGE_STRONG THEN 18803 ASM_REWRITE_TAC[]); 18804 18805val SERIES_REARRANGE_EQ = store_thm ("SERIES_REARRANGE_EQ", 18806 ``!x:num->real s p l. 18807 (summable s (\n. abs(x n))) /\ (p permutes s) 18808 ==> (((x o p) sums l) s <=> (x sums l) s)``, 18809 REPEAT STRIP_TAC THEN 18810 MP_TAC(ISPECL [``x:num->real``, ``s:num->bool``, ``p:num->num``, ``l:real``] 18811 SERIES_INJECTIVE_IMAGE) THEN 18812 ASM_SIMP_TAC std_ss [PERMUTES_IMAGE] THEN 18813 ASM_MESON_TAC[PERMUTES_INJECTIVE]); 18814 18815val SERIES_REARRANGE = store_thm ("SERIES_REARRANGE", 18816 ``!x:num->real s p l. 18817 summable s (\n. abs(x n)) /\ p permutes s /\ (x sums l) s 18818 ==> ((x o p) sums l) s``, 18819 METIS_TAC[SERIES_REARRANGE_EQ]); 18820 18821val SUMMABLE_REARRANGE = store_thm ("SUMMABLE_REARRANGE", 18822 ``!x s p. 18823 summable s (\n. abs(x n)) /\ p permutes s 18824 ==> summable s (x o p)``, 18825 METIS_TAC[SERIES_ABSCONV_IMP_CONV, summable, SERIES_REARRANGE]); 18826 18827(* ------------------------------------------------------------------------- *) 18828(* Banach fixed point theorem (not really topological...) *) 18829(* ------------------------------------------------------------------------- *) 18830 18831val BANACH_FIX = store_thm ("BANACH_FIX", 18832 ``!f s c. complete s /\ ~(s = {}) /\ 18833 &0 <= c /\ c < &1 /\ 18834 (IMAGE f s) SUBSET s /\ 18835 (!x y. x IN s /\ y IN s ==> dist(f(x),f(y)) <= c * dist(x,y)) 18836 ==> ?!x:real. x IN s /\ (f x = x)``, 18837 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [EXISTS_UNIQUE_THM] THEN CONJ_TAC THENL 18838 [ALL_TAC, 18839 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 18840 SUBGOAL_THEN ``dist((f:real->real) x,f y) <= c * dist(x,y)`` MP_TAC THENL 18841 [ASM_MESON_TAC[], ALL_TAC] THEN 18842 ASM_REWRITE_TAC[REAL_ARITH ``a <= c * a <=> &0 <= -a * (&1 - c:real)``] THEN 18843 ASM_SIMP_TAC std_ss [GSYM REAL_LE_LDIV_EQ, REAL_SUB_LT, real_div] THEN 18844 REWRITE_TAC[REAL_MUL_LZERO, REAL_ARITH ``&0:real <= -x <=> ~(&0 < x)``] THEN 18845 MESON_TAC[DIST_POS_LT]] THEN 18846 KNOW_TAC ``?z. (z 0 = @x:real. x IN s) /\ (!n. z(SUC n) = f(z n))`` THENL 18847 [RW_TAC std_ss [num_Axiom], STRIP_TAC] THEN 18848 SUBGOAL_THEN ``!n. (z:num->real) n IN s`` ASSUME_TAC THENL 18849 [INDUCT_TAC THEN ASM_SIMP_TAC std_ss [] THEN 18850 METIS_TAC[MEMBER_NOT_EMPTY, SUBSET_DEF, IN_IMAGE], 18851 ALL_TAC] THEN 18852 UNDISCH_THEN ``z (0:num) = @x:real. x IN s`` (K ALL_TAC) THEN 18853 SUBGOAL_THEN ``?x:real. x IN s /\ (z --> x) sequentially`` MP_TAC THENL 18854 [ALL_TAC, 18855 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 18856 POP_ASSUM MP_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 18857 ABBREV_TAC ``e = dist(f(a:real),a)`` THEN 18858 SUBGOAL_THEN ``~(&0 < e:real)`` (fn th => METIS_TAC[th, DIST_POS_LT]) THEN 18859 DISCH_TAC THEN UNDISCH_TAC ``(z --> a) sequentially`` THEN DISCH_TAC THEN 18860 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LIM_SEQUENTIALLY]) THEN 18861 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN 18862 ASM_REWRITE_TAC[REAL_HALF] THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THEN 18863 SUBGOAL_THEN 18864 ``dist(f(z N),a:real) < e / &2 /\ dist(f(z(N:num)),f(a)) < e / &2`` 18865 (fn th => ASM_MESON_TAC[th, DIST_TRIANGLE_HALF_R, REAL_LT_REFL]) THEN 18866 CONJ_TAC THENL [ASM_MESON_TAC[ARITH_PROVE ``N <= SUC N``], ALL_TAC] THEN 18867 MATCH_MP_TAC REAL_LET_TRANS THEN 18868 EXISTS_TAC ``c * dist((z:num->real) N,a)`` THEN ASM_SIMP_TAC std_ss [] THEN 18869 MATCH_MP_TAC(REAL_ARITH ``x < y /\ c * x <= &1 * x ==> c * x < y:real``) THEN 18870 ASM_SIMP_TAC std_ss [LESS_EQ_REFL, REAL_LE_RMUL_IMP, DIST_POS_LE, REAL_LT_IMP_LE]] THEN 18871 UNDISCH_TAC ``complete s`` THEN DISCH_TAC THEN 18872 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE [complete]) THEN 18873 ASM_REWRITE_TAC[CAUCHY] THEN 18874 SUBGOAL_THEN ``!n. dist(z(n):real,z(SUC n)) <= c pow n * dist(z(0),z(1))`` 18875 ASSUME_TAC THENL 18876 [INDUCT_TAC THEN 18877 SIMP_TAC arith_ss [pow, REAL_MUL_LID, REAL_LE_REFL] THEN 18878 MATCH_MP_TAC REAL_LE_TRANS THEN 18879 EXISTS_TAC ``c * dist(z(n):real,z(SUC n))`` THEN 18880 CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC] THEN 18881 REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC std_ss [REAL_LE_LMUL_IMP], 18882 ALL_TAC] THEN 18883 SUBGOAL_THEN 18884 ``!m n:num. (&1 - c) * dist(z(m):real,z(m+n)) 18885 <= c pow m * dist(z(0),z(1:num)) * (&1 - c pow n)`` 18886 ASSUME_TAC THENL 18887 [GEN_TAC THEN INDUCT_TAC THENL 18888 [REWRITE_TAC[ADD_CLAUSES, DIST_REFL, REAL_MUL_RZERO, GSYM REAL_MUL_ASSOC] THEN 18889 MATCH_MP_TAC REAL_LE_MUL THEN 18890 ASM_SIMP_TAC std_ss [REAL_LE_MUL, POW_POS, DIST_POS_LE, REAL_SUB_LE, 18891 REAL_POW_1_LE, REAL_LT_IMP_LE], 18892 ALL_TAC] THEN 18893 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC 18894 ``(&1 - c) * (dist(z m:real,z(m + n)) + dist(z(m + n),z(m + SUC n)))`` THEN 18895 ASM_SIMP_TAC std_ss [REAL_LE_LMUL_IMP, REAL_SUB_LE, REAL_LT_IMP_LE, DIST_TRIANGLE] THEN 18896 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH 18897 ``c * x <= y ==> c * x' + y <= y' ==> c * (x + x') <= y':real``)) THEN 18898 REWRITE_TAC[REAL_ARITH 18899 ``q + a * b * (&1 - x) <= a * b * (&1 - y) <=> q <= a * b * (x - y:real)``] THEN 18900 REWRITE_TAC[ADD_CLAUSES, pow] THEN 18901 REWRITE_TAC[REAL_ARITH ``a * b * (d - c * d) = (&1 - c) * a * d * b:real``] THEN 18902 REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN MATCH_MP_TAC REAL_LE_LMUL_IMP THEN 18903 ASM_SIMP_TAC std_ss [REAL_SUB_LE, REAL_LT_IMP_LE] THEN 18904 REWRITE_TAC[GSYM REAL_POW_ADD, REAL_MUL_ASSOC] THEN ASM_MESON_TAC[], 18905 ALL_TAC] THEN 18906 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 18907 ASM_CASES_TAC ``(z:num->real) 0 = z 1`` THENL 18908 [FIRST_X_ASSUM SUBST_ALL_TAC THEN EXISTS_TAC ``0:num`` THEN 18909 REWRITE_TAC[GE, ZERO_LESS_EQ] THEN X_GEN_TAC ``n:num`` THEN 18910 FIRST_X_ASSUM(MP_TAC o SPECL [``0:num``, ``n:num``]) THEN 18911 REWRITE_TAC[ADD_CLAUSES, DIST_REFL, REAL_MUL_LZERO, REAL_MUL_RZERO] THEN 18912 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 18913 ASM_CASES_TAC ``(z:num->real) 0 = z n`` THEN 18914 ASM_REWRITE_TAC[DIST_REFL, REAL_NOT_LE] THEN 18915 ASM_SIMP_TAC std_ss [REAL_LT_MUL, DIST_POS_LT, REAL_SUB_LT], 18916 ALL_TAC] THEN 18917 MP_TAC(SPECL [``c:real``, ``e * (&1 - c) / dist((z:num->real) 0,z 1)``] 18918 REAL_ARCH_POW_INV) THEN 18919 ASM_SIMP_TAC std_ss [REAL_LT_MUL, REAL_LT_DIV, REAL_SUB_LT, DIST_POS_LT] THEN 18920 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 18921 POP_ASSUM MP_TAC THEN REWRITE_TAC[real_div, GE, REAL_MUL_ASSOC] THEN 18922 ASM_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, GSYM real_div, DIST_POS_LT] THEN 18923 ASM_SIMP_TAC std_ss [GSYM REAL_LT_LDIV_EQ, REAL_SUB_LT] THEN DISCH_TAC THEN 18924 SIMP_TAC std_ss [LESS_EQ_EXISTS, LEFT_IMP_EXISTS_THM] THEN 18925 X_GEN_TAC ``d:num`` THEN ONCE_REWRITE_TAC[DIST_SYM] THEN 18926 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(REAL_ARITH 18927 ``d < e ==> x <= d ==> x < e:real``)) THEN 18928 ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_SUB_LT] THEN 18929 FIRST_X_ASSUM(MP_TAC o SPECL [``N:num``, ``d:num``]) THEN 18930 MATCH_MP_TAC(REAL_ARITH 18931 ``(c * d) * e <= (c * d) * &1 ==> x * y <= c * d * e ==> y * x <= c * d:real``) THEN 18932 MATCH_MP_TAC REAL_LE_LMUL_IMP THEN 18933 ASM_SIMP_TAC std_ss [REAL_LE_MUL, POW_POS, DIST_POS_LE, REAL_ARITH 18934 ``&0 <= x ==> &1 - x <= &1:real``]); 18935 18936(* ------------------------------------------------------------------------- *) 18937(* Dini's theorem. *) 18938(* ------------------------------------------------------------------------- *) 18939 18940val DINI = store_thm ("DINI", 18941 ``!f:num->real->real g s. 18942 compact s /\ (!n. (f n) continuous_on s) /\ g continuous_on s /\ 18943 (!x. x IN s ==> ((\n. (f n x)) --> g x) sequentially) /\ 18944 (!n x. x IN s ==> (f n x) <= (f (n + 1) x)) 18945 ==> !e. &0 < e 18946 ==> eventually (\n. !x. x IN s ==> abs(f n x - g x) < e) 18947 sequentially``, 18948 REPEAT STRIP_TAC THEN 18949 SUBGOAL_THEN 18950 ``!x:real m n:num. x IN s /\ m <= n ==> (f m x):real <= (f n x)`` 18951 ASSUME_TAC THENL 18952 [GEN_TAC THEN ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_REWRITE_TAC[] THEN 18953 ONCE_REWRITE_TAC [METIS [] ``!m n. (f:num->real->real) m x <= f n x <=> 18954 (\m n. f m x <= f n x) m n``] THEN 18955 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SIMP_TAC std_ss [ADD1] THEN 18956 REAL_ARITH_TAC, ALL_TAC] THEN 18957 SUBGOAL_THEN ``!n:num x:real. x IN s ==> (f n x):real <= (g x)`` 18958 ASSUME_TAC THENL 18959 [REPEAT STRIP_TAC THEN 18960 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_DROP_LE) THEN 18961 EXISTS_TAC ``\m:num. (f:num->real->real) n x`` THEN 18962 EXISTS_TAC ``\m:num. (f:num->real->real) m x`` THEN 18963 ASM_SIMP_TAC std_ss [LIM_CONST, TRIVIAL_LIMIT_SEQUENTIALLY] THEN 18964 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN ASM_MESON_TAC[], 18965 ALL_TAC] THEN 18966 RULE_ASSUM_TAC(REWRITE_RULE[LIM_SEQUENTIALLY, dist]) THEN 18967 UNDISCH_TAC ``compact s`` THEN DISCH_TAC THEN 18968 FIRST_ASSUM(MP_TAC o REWRITE_RULE 18969 [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN 18970 DISCH_THEN(MP_TAC o SPEC 18971 ``IMAGE (\n. { x | x IN s /\ abs((f:num->real->real) n x - g x) < e}) 18972 univ(:num)``) THEN 18973 SIMP_TAC std_ss [FORALL_IN_IMAGE, IN_UNIV] THEN 18974 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN 18975 SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE, SUBSET_UNION, BIGUNION_IMAGE] THEN 18976 SIMP_TAC std_ss [IN_UNIV, GSPECIFICATION, EVENTUALLY_SEQUENTIALLY] THEN 18977 SIMP_TAC std_ss [SUBSET_DEF, IN_UNIV, GSPECIFICATION] THEN 18978 KNOW_TAC ``(!(n :num). 18979 open_in (subtopology euclidean (s :real -> bool)) 18980 {x | 18981 x IN s /\ 18982 abs ((f :num -> real -> real) n x - (g :real -> real) x) < 18983 (e :real)}) /\ 18984 (!(x :real). x IN s ==> ?(n :num). abs (f n x - g x) < e)`` THENL 18985 [CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[LESS_EQ_REFL]] THEN 18986 X_GEN_TAC ``n:num`` THEN REWRITE_TAC[GSYM IN_BALL_0] THEN 18987 ONCE_REWRITE_TAC [METIS [] ``f n x - g x = 18988 (\x. (f:num->real->real) n x - g x) x``] THEN 18989 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN 18990 METIS_TAC [OPEN_BALL, CONTINUOUS_ON_SUB, ETA_AX], 18991 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 18992 DISCH_THEN(X_CHOOSE_THEN ``k:num->bool`` (CONJUNCTS_THEN2 18993 (MP_TAC o SPEC ``\n:num. n`` o MATCH_MP UPPER_BOUND_FINITE_SET) 18994 ASSUME_TAC)) THEN 18995 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 18996 POP_ASSUM MP_TAC THEN 18997 SIMP_TAC std_ss [] THEN STRIP_TAC THEN X_GEN_TAC ``n:num`` THEN 18998 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 18999 UNDISCH_TAC ``!x. x IN s ==> ?n. n IN k /\ 19000 abs ((f:num->real->real) n x - g x) < e`` THEN 19001 DISCH_TAC THEN 19002 FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 19003 DISCH_THEN(X_CHOOSE_THEN ``m:num`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 19004 MATCH_MP_TAC(REAL_ARITH 19005 ``m <= n /\ n <= g ==> abs(m - g) < e ==> abs(n - g) < e:real``) THEN 19006 METIS_TAC[LESS_EQ_TRANS]]); 19007 19008(* ------------------------------------------------------------------------- *) 19009(* Closest point of a (closed) set to a point. *) 19010(* ------------------------------------------------------------------------- *) 19011 19012val closest_point = new_definition ("closest_point", 19013 ``closest_point s a = @x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)``); 19014 19015val CLOSEST_POINT_EXISTS = store_thm ("CLOSEST_POINT_EXISTS", 19016 ``!s a. closed s /\ ~(s = {}) 19017 ==> (closest_point s a) IN s /\ 19018 !y. y IN s ==> dist(a,closest_point s a) <= dist(a,y)``, 19019 REWRITE_TAC[closest_point] THEN CONV_TAC(ONCE_DEPTH_CONV SELECT_CONV) THEN 19020 REWRITE_TAC[DISTANCE_ATTAINS_INF]); 19021 19022val CLOSEST_POINT_IN_SET = store_thm ("CLOSEST_POINT_IN_SET", 19023 ``!s a. closed s /\ ~(s = {}) ==> (closest_point s a) IN s``, 19024 MESON_TAC[CLOSEST_POINT_EXISTS]); 19025 19026val CLOSEST_POINT_LE = store_thm ("CLOSEST_POINT_LE", 19027 ``!s a x. closed s /\ x IN s ==> dist(a,closest_point s a) <= dist(a,x)``, 19028 MESON_TAC[CLOSEST_POINT_EXISTS, MEMBER_NOT_EMPTY]); 19029 19030val CLOSEST_POINT_SELF = store_thm ("CLOSEST_POINT_SELF", 19031 ``!s x:real. x IN s ==> (closest_point s x = x)``, 19032 REPEAT STRIP_TAC THEN REWRITE_TAC[closest_point] THEN 19033 MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN GEN_TAC THEN EQ_TAC THENL 19034 [BETA_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN 19035 ASM_SIMP_TAC std_ss [DIST_LE_0, DIST_REFL], 19036 BETA_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[DIST_REFL, DIST_POS_LE]]); 19037 19038val CLOSEST_POINT_REFL = store_thm ("CLOSEST_POINT_REFL", 19039 ``!s x:real. closed s /\ ~(s = {}) ==> ((closest_point s x = x) <=> x IN s)``, 19040 MESON_TAC[CLOSEST_POINT_IN_SET, CLOSEST_POINT_SELF]); 19041 19042val DIST_CLOSEST_POINT_LIPSCHITZ = store_thm ("DIST_CLOSEST_POINT_LIPSCHITZ", 19043 ``!s x y:real. 19044 closed s /\ ~(s = {}) 19045 ==> abs(dist(x,closest_point s x) - dist(y,closest_point s y)) 19046 <= dist(x,y)``, 19047 REPEAT GEN_TAC THEN DISCH_TAC THEN 19048 FIRST_ASSUM(MP_TAC o MATCH_MP CLOSEST_POINT_EXISTS) THEN 19049 DISCH_THEN(fn th => 19050 CONJUNCTS_THEN2 ASSUME_TAC 19051 (MP_TAC o SPEC ``closest_point s (y:real)``) (SPEC ``x:real`` th) THEN 19052 CONJUNCTS_THEN2 ASSUME_TAC 19053 (MP_TAC o SPEC ``closest_point s (x:real)``) (SPEC ``y:real`` th)) THEN 19054 ASM_SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 19055 19056val CONTINUOUS_AT_DIST_CLOSEST_POINT = store_thm ("CONTINUOUS_AT_DIST_CLOSEST_POINT", 19057 ``!s x:real. 19058 closed s /\ ~(s = {}) 19059 ==> (\x. (dist(x,closest_point s x))) continuous (at x)``, 19060 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [continuous_at] THEN REWRITE_TAC [dist] THEN 19061 METIS_TAC[REWRITE_RULE [dist] DIST_CLOSEST_POINT_LIPSCHITZ, REAL_LET_TRANS]); 19062 19063val CONTINUOUS_ON_DIST_CLOSEST_POINT = store_thm ("CONTINUOUS_ON_DIST_CLOSEST_POINT", 19064 ``!s t. closed s /\ ~(s = {}) 19065 ==> (\x. (dist(x,closest_point s x))) continuous_on t``, 19066 METIS_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON, 19067 CONTINUOUS_AT_DIST_CLOSEST_POINT]); 19068 19069val UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT = store_thm ("UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT", 19070 ``!s t:real->bool. 19071 closed s /\ ~(s = {}) 19072 ==> (\x. (dist(x,closest_point s x))) uniformly_continuous_on t``, 19073 REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN 19074 REWRITE_TAC [dist] THEN 19075 METIS_TAC[REWRITE_RULE [dist] DIST_CLOSEST_POINT_LIPSCHITZ, REAL_LET_TRANS]); 19076 19077val SEGMENT_TO_CLOSEST_POINT = store_thm ("SEGMENT_TO_CLOSEST_POINT", 19078 ``!s a:real. 19079 closed s /\ ~(s = {}) 19080 ==> (segment(a,closest_point s a) INTER s = {})``, 19081 REPEAT STRIP_TAC THEN 19082 REWRITE_TAC[SET_RULE ``(s INTER t = {}) <=> !x. x IN s ==> ~(x IN t)``] THEN 19083 GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP DIST_IN_OPEN_SEGMENT) THEN 19084 MATCH_MP_TAC(TAUT `(r ==> ~p) ==> p /\ q ==> ~r`) THEN 19085 METIS_TAC [CLOSEST_POINT_EXISTS, REAL_NOT_LT, DIST_SYM]); 19086 19087val SEGMENT_TO_POINT_EXISTS = store_thm ("SEGMENT_TO_POINT_EXISTS", 19088 ``!s a:real. 19089 closed s /\ ~(s = {}) ==> ?b. b IN s /\ (segment(a,b) INTER s = {})``, 19090 MESON_TAC[SEGMENT_TO_CLOSEST_POINT, CLOSEST_POINT_EXISTS]); 19091 19092val CLOSEST_POINT_IN_INTERIOR = store_thm 19093 ("CLOSEST_POINT_IN_INTERIOR", 19094 ``!s x:real. 19095 closed s /\ ~(s = {}) 19096 ==> ((closest_point s x) IN interior s <=> x IN interior s)``, 19097 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``(x:real) IN s`` THEN 19098 ASM_SIMP_TAC std_ss [CLOSEST_POINT_SELF] THEN 19099 MATCH_MP_TAC(TAUT `~q /\ ~p ==> (p <=> q)`) THEN 19100 CONJ_TAC THENL [METIS_TAC[INTERIOR_SUBSET, SUBSET_DEF], STRIP_TAC] THEN 19101 FIRST_ASSUM(MP_TAC o REWRITE_RULE [IN_INTERIOR_CBALL]) THEN 19102 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 19103 SUBGOAL_THEN ``closest_point s (x:real) IN s`` ASSUME_TAC THENL 19104 [METIS_TAC[INTERIOR_SUBSET, SUBSET_DEF], ALL_TAC] THEN 19105 SUBGOAL_THEN ``~(closest_point s (x:real) = x)`` ASSUME_TAC THENL 19106 [ASM_MESON_TAC[], ALL_TAC] THEN 19107 MP_TAC(ISPECL [``s:real->bool``, ``x:real``, 19108 ``closest_point s x - 19109 (min (&1) (e / abs(closest_point s x - x))) * 19110 (closest_point s x - x):real``] 19111 CLOSEST_POINT_LE) THEN 19112 ASM_REWRITE_TAC[dist, NOT_IMP, REAL_ARITH 19113 ``x - (y - e * (y - x)):real = (&1 - e) * (x - y:real)``] THEN 19114 CONJ_TAC THENL 19115 [ (* goal 1 (of 2) *) 19116 UNDISCH_TAC ``cball (closest_point s x,e) SUBSET s`` THEN DISCH_TAC THEN 19117 FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 19118 REWRITE_TAC[dist, IN_CBALL, REAL_ARITH ``abs(a:real - a - x) = abs x``] THEN 19119 SIMP_TAC real_ss [ABS_MUL, ABS_DIV, ABS_ABS] THEN 19120 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM REAL_SUB_0]) THEN 19121 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [ABS_NZ]) THEN 19122 19123 ASM_SIMP_TAC std_ss [GSYM REAL_LE_RDIV_EQ, min_def] THEN 19124 KNOW_TAC ``!a:real. &0 <= a ==> abs (if 1 <= a then 1 else a) <= a`` 19125 >- ( RW_TAC real_ss [] >> PROVE_TAC [abs, REAL_LE_REFL] ) THEN 19126 DISCH_THEN MATCH_MP_TAC THEN 19127 ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE, REAL_LE_DIV, ABS_POS], 19128 (* goal 2 (of 2) *) 19129 REWRITE_TAC[ABS_MUL, REAL_ARITH 19130 ``~(n <= a * n) <=> &0 < (&1 - a) * n:real``] THEN 19131 MATCH_MP_TAC REAL_LT_MUL THEN 19132 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``(a <> b) <=> (b - a <> 0:real)``]) THEN 19133 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [ABS_NZ]) THEN ASM_SIMP_TAC std_ss [] THEN 19134 KNOW_TAC ``!e:real. &0 < e /\ e <= &1 ==> &0 < &1 - abs(&1 - e)`` 19135 >- ( RW_TAC real_ss [] \\ 19136 `0 <= 1 - e'` by ASM_REAL_ARITH_TAC \\ 19137 ASM_SIMP_TAC real_ss [abs] ) THEN 19138 DISCH_THEN MATCH_MP_TAC THEN 19139 REWRITE_TAC[REAL_MIN_LE, REAL_LT_MIN, REAL_LT_01, REAL_LE_REFL] THEN 19140 METIS_TAC [REAL_LT_DIV, ABS_SUB] ]); 19141 19142val CLOSEST_POINT_IN_FRONTIER = store_thm ("CLOSEST_POINT_IN_FRONTIER", 19143 ``!s x:real. 19144 closed s /\ ~(s = {}) /\ ~(x IN interior s) 19145 ==> (closest_point s x) IN frontier s``, 19146 SIMP_TAC std_ss [frontier, IN_DIFF, CLOSEST_POINT_IN_INTERIOR] THEN 19147 SIMP_TAC std_ss [CLOSEST_POINT_IN_SET, CLOSURE_CLOSED]); 19148 19149(* ------------------------------------------------------------------------- *) 19150(* More general infimum of distance between two sets. *) 19151(* ------------------------------------------------------------------------- *) 19152 19153val setdist = new_definition ("setdist", 19154 ``setdist(s,t) = 19155 if (s = {}) \/ (t = {}) then &0 19156 else inf {dist(x,y) | x IN s /\ y IN t}``); 19157 19158val SETDIST_EMPTY = store_thm ("SETDIST_EMPTY", 19159 ``(!t. setdist({},t) = &0) /\ (!s. setdist(s,{}) = &0)``, 19160 REWRITE_TAC[setdist]); 19161 19162val SETDIST_POS_LE = store_thm ("SETDIST_POS_LE", 19163 ``!s t. &0 <= setdist(s,t)``, 19164 REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN 19165 COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN 19166 MATCH_MP_TAC REAL_LE_INF THEN 19167 SIMP_TAC std_ss [FORALL_IN_GSPEC, DIST_POS_LE] THEN 19168 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[]); 19169 19170val SETDIST_SUBSETS_EQ = store_thm ("SETDIST_SUBSETS_EQ", 19171 ``!s t s' t':real->bool. 19172 s' SUBSET s /\ t' SUBSET t /\ 19173 (!x y. x IN s /\ y IN t 19174 ==> ?x' y'. x' IN s' /\ y' IN t' /\ dist(x',y') <= dist(x,y)) 19175 ==> (setdist(s',t') = setdist(s,t))``, 19176 REPEAT STRIP_TAC THEN 19177 ASM_CASES_TAC ``s:real->bool = {}`` THENL 19178 [ASM_CASES_TAC ``s':real->bool = {}`` THEN 19179 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN ASM_SET_TAC[], 19180 ALL_TAC] THEN 19181 ASM_CASES_TAC ``t:real->bool = {}`` THENL 19182 [ASM_CASES_TAC ``t':real->bool = {}`` THEN 19183 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN ASM_SET_TAC[], 19184 ALL_TAC] THEN 19185 ASM_CASES_TAC ``s':real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN 19186 ASM_CASES_TAC ``t':real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN 19187 ASM_REWRITE_TAC[setdist] THEN MATCH_MP_TAC INF_EQ THEN 19188 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 19189 CONJ_TAC >- (SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, 19190 EXISTS_PROD, NOT_IN_EMPTY] \\ 19191 fs [GSYM MEMBER_NOT_EMPTY] \\ 19192 rename1 `a IN s'` >> Q.EXISTS_TAC `a` \\ 19193 rename1 `b IN t'` >> Q.EXISTS_TAC `b` \\ 19194 ASM_REWRITE_TAC []) \\ 19195 CONJ_TAC >- (Q.EXISTS_TAC `0` >> rw [DIST_POS_LE]) \\ 19196 CONJ_TAC >- (SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, 19197 EXISTS_PROD, NOT_IN_EMPTY] \\ 19198 fs [GSYM MEMBER_NOT_EMPTY] \\ 19199 rename1 `a IN s` >> Q.EXISTS_TAC `a` \\ 19200 rename1 `b IN t` >> Q.EXISTS_TAC `b` \\ 19201 ASM_REWRITE_TAC []) \\ 19202 CONJ_TAC >- (Q.EXISTS_TAC `0` >> rw [DIST_POS_LE]) \\ 19203 ASM_MESON_TAC[SUBSET_DEF, REAL_LE_TRANS]); 19204 19205val REAL_LE_SETDIST = store_thm ("REAL_LE_SETDIST", 19206 ``!s t:real->bool d. 19207 ~(s = {}) /\ ~(t = {}) /\ 19208 (!x y. x IN s /\ y IN t ==> d <= dist(x,y)) 19209 ==> d <= setdist(s,t)``, 19210 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[setdist] THEN 19211 MP_TAC(ISPEC ``{dist(x:real,y) | x IN s /\ y IN t}`` INF) THEN 19212 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 19213 KNOW_TAC ``{dist (x,y) | x IN s /\ y IN t} <> {} /\ 19214 (?b. !x y. x IN s /\ y IN t ==> b <= dist (x,y))`` THENL 19215 [CONJ_TAC THENL 19216 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 19217 ASM_SET_TAC[], MESON_TAC[DIST_POS_LE]], 19218 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 19219 ASM_MESON_TAC[]); 19220 19221val SETDIST_LE_DIST = store_thm ("SETDIST_LE_DIST", 19222 ``!s t x y:real. x IN s /\ y IN t ==> setdist(s,t) <= dist(x,y)``, 19223 REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN 19224 COND_CASES_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 19225 MP_TAC(ISPEC ``{dist(x:real,y) | x IN s /\ y IN t}`` INF) THEN 19226 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 19227 KNOW_TAC ``{dist (x,y) | x IN s /\ y IN t} <> {} /\ 19228 (?b. !x y. x IN s /\ y IN t ==> b <= dist (x,y))`` THENL 19229 [CONJ_TAC THENL 19230 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 19231 ASM_SET_TAC[], MESON_TAC[DIST_POS_LE]], 19232 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 19233 ASM_MESON_TAC[]); 19234 19235val REAL_LE_SETDIST_EQ = store_thm ("REAL_LE_SETDIST_EQ", 19236 ``!d s t:real->bool. 19237 d <= setdist(s,t) <=> 19238 (!x y. x IN s /\ y IN t ==> d <= dist(x,y)) /\ 19239 ((s = {}) \/ (t = {}) ==> d <= &0)``, 19240 REPEAT GEN_TAC THEN MAP_EVERY ASM_CASES_TAC 19241 [``s:real->bool = {}``, ``t:real->bool = {}``] THEN 19242 ASM_REWRITE_TAC[SETDIST_EMPTY, NOT_IN_EMPTY] THEN 19243 ASM_MESON_TAC[REAL_LE_SETDIST, SETDIST_LE_DIST, REAL_LE_TRANS]); 19244 19245val REAL_SETDIST_LT_EXISTS = store_thm ("REAL_SETDIST_LT_EXISTS", 19246 ``!s t:real->bool b. 19247 ~(s = {}) /\ ~(t = {}) /\ setdist(s,t) < b 19248 ==> ?x y. x IN s /\ y IN t /\ dist(x,y) < b``, 19249 REWRITE_TAC[GSYM REAL_NOT_LE, REAL_LE_SETDIST_EQ] THEN MESON_TAC[]); 19250 19251val SETDIST_REFL = store_thm ("SETDIST_REFL", 19252 ``!s:real->bool. setdist(s,s) = &0``, 19253 GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM, SETDIST_POS_LE] THEN 19254 ASM_CASES_TAC ``s:real->bool = {}`` THENL 19255 [ASM_REWRITE_TAC[setdist, REAL_LE_REFL], ALL_TAC] THEN 19256 ASM_MESON_TAC[SETDIST_LE_DIST, MEMBER_NOT_EMPTY, DIST_REFL]); 19257 19258val SETDIST_SYM = store_thm ("SETDIST_SYM", 19259 ``!s t. setdist(s,t) = setdist(t,s)``, 19260 REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN ONCE_REWRITE_TAC [DISJ_SYM] THEN 19261 COND_CASES_TAC THEN ONCE_REWRITE_TAC [DISJ_SYM] THEN ASM_SIMP_TAC std_ss [] THEN 19262 AP_TERM_TAC THEN SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 19263 METIS_TAC[DIST_SYM]); 19264 19265val SETDIST_TRIANGLE = store_thm ("SETDIST_TRIANGLE", 19266 ``!s a t:real->bool. 19267 setdist(s,t) <= setdist(s,{a}) + setdist({a},t)``, 19268 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 19269 ASM_REWRITE_TAC[SETDIST_EMPTY, REAL_ADD_LID, SETDIST_POS_LE] THEN 19270 ASM_CASES_TAC ``t:real->bool = {}`` THEN 19271 ASM_REWRITE_TAC[SETDIST_EMPTY, REAL_ADD_RID, SETDIST_POS_LE] THEN 19272 ONCE_REWRITE_TAC[GSYM REAL_LE_SUB_RADD] THEN 19273 MATCH_MP_TAC REAL_LE_SETDIST THEN 19274 ASM_SIMP_TAC std_ss [NOT_INSERT_EMPTY, IN_SING, CONJ_EQ_IMP, 19275 RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2] THEN 19276 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 19277 ONCE_REWRITE_TAC[REAL_ARITH ``x - y <= z <=> x - z <= y:real``] THEN 19278 MATCH_MP_TAC REAL_LE_SETDIST THEN 19279 ASM_REWRITE_TAC[NOT_INSERT_EMPTY, IN_SING, CONJ_EQ_IMP, 19280 RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2] THEN 19281 X_GEN_TAC ``y:real`` THEN REPEAT STRIP_TAC THEN 19282 REWRITE_TAC[REAL_LE_SUB_RADD] THEN MATCH_MP_TAC REAL_LE_TRANS THEN 19283 EXISTS_TAC ``dist(x:real,y')`` THEN 19284 ASM_SIMP_TAC std_ss [SETDIST_LE_DIST, dist] THEN REAL_ARITH_TAC); 19285 19286val SETDIST_SINGS = store_thm ("SETDIST_SINGS", 19287 ``!x y. setdist({x},{y}) = dist(x,y)``, 19288 REWRITE_TAC[setdist, NOT_INSERT_EMPTY] THEN 19289 ONCE_REWRITE_TAC [METIS [] ``dist (x,y) = (\x y. dist (x,y)) x y``] THEN 19290 KNOW_TAC ``!f:real->real->real x y a b. {f x y | x IN {a} /\ y IN {b}} = {f a b}`` THENL 19291 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN SET_TAC [], 19292 DISCH_TAC] THEN ASM_REWRITE_TAC [] THEN 19293 SIMP_TAC std_ss [INF_INSERT_FINITE, FINITE_EMPTY]); 19294 19295val SETDIST_LIPSCHITZ = store_thm ("SETDIST_LIPSCHITZ", 19296 ``!s t x y:real. abs(setdist({x},s) - setdist({y},s)) <= dist(x,y)``, 19297 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SETDIST_SINGS] THEN 19298 REWRITE_TAC[REAL_ARITH 19299 ``abs(x - y) <= z <=> x <= z + y /\ y <= z + x:real``] THEN 19300 MESON_TAC[SETDIST_TRIANGLE, SETDIST_SYM]); 19301 19302val CONTINUOUS_AT_SETDIST = store_thm ("CONTINUOUS_AT_SETDIST", 19303 ``!s x:real. (\y. setdist({y},s)) continuous (at x)``, 19304 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at] THEN 19305 SIMP_TAC std_ss [dist] THEN 19306 METIS_TAC[REWRITE_RULE [dist] SETDIST_LIPSCHITZ, REAL_LET_TRANS]); 19307 19308val CONTINUOUS_ON_SETDIST = store_thm ("CONTINUOUS_ON_SETDIST", 19309 ``!s t:real->bool. (\y. setdist({y},s)) continuous_on t``, 19310 METIS_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON, 19311 CONTINUOUS_AT_SETDIST]); 19312 19313val UNIFORMLY_CONTINUOUS_ON_SETDIST = store_thm ("UNIFORMLY_CONTINUOUS_ON_SETDIST", 19314 ``!s t:real->bool. 19315 (\y. setdist({y},s)) uniformly_continuous_on t``, 19316 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN 19317 BETA_TAC THEN METIS_TAC[dist, SETDIST_LIPSCHITZ, REAL_LET_TRANS]); 19318 19319val SETDIST_DIFFERENCES = store_thm ("SETDIST_DIFFERENCES", 19320 ``!s t. setdist(s,t) = setdist({0},{x - y:real | x IN s /\ y IN t})``, 19321 REPEAT GEN_TAC THEN 19322 KNOW_TAC ``!f:real->real->real x y s t. 19323 ({f x y | x IN s /\ y IN t} = {}) <=> (s = {}) \/ (t = {})`` THENL 19324 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN SET_TAC [], 19325 DISCH_TAC] THEN 19326 ONCE_REWRITE_TAC [METIS [] ``x - y = (\x y. x - y) x y:real``] THEN 19327 ASM_REWRITE_TAC[setdist, NOT_INSERT_EMPTY] THEN 19328 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [] THEN AP_TERM_TAC THEN 19329 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_SING, EXISTS_PROD] THEN 19330 SIMP_TAC std_ss [GSYM CONJ_ASSOC, RIGHT_EXISTS_AND_THM, UNWIND_THM2, DIST_0] THEN 19331 REWRITE_TAC[dist] THEN MESON_TAC[]); 19332 19333val SETDIST_SUBSET_RIGHT = store_thm ("SETDIST_SUBSET_RIGHT", 19334 ``!s t u:real->bool. 19335 ~(t = {}) /\ t SUBSET u ==> setdist(s,u) <= setdist(s,t)``, 19336 REPEAT STRIP_TAC THEN 19337 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``u:real->bool = {}``] THEN 19338 ASM_SIMP_TAC std_ss [SETDIST_EMPTY, SETDIST_POS_LE, REAL_LE_REFL] THEN 19339 ASM_REWRITE_TAC[setdist] THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN 19340 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, SUBSET_DEF, EXISTS_PROD, GSPECIFICATION] THEN 19341 REPEAT(CONJ_TAC THENL 19342 [ASM_SIMP_TAC std_ss [EXTENSION, EXISTS_PROD, GSPECIFICATION] THEN ASM_SET_TAC[], 19343 ALL_TAC]) THEN METIS_TAC[DIST_POS_LE]); 19344 19345val SETDIST_SUBSET_LEFT = store_thm ("SETDIST_SUBSET_LEFT", 19346 ``!s t u:real->bool. 19347 ~(s = {}) /\ s SUBSET t ==> setdist(t,u) <= setdist(s,u)``, 19348 MESON_TAC[SETDIST_SUBSET_RIGHT, SETDIST_SYM]); 19349 19350val SETDIST_CLOSURE = store_thm ("SETDIST_CLOSURE", 19351 ``(!s t:real->bool. setdist(closure s,t) = setdist(s,t)) /\ 19352 (!s t:real->bool. setdist(s,closure t) = setdist(s,t))``, 19353 REWRITE_TAC [METIS [SWAP_FORALL_THM] 19354 ``(!s t. setdist (s,closure t) = setdist (s,t)) = 19355 (!t s. setdist (s,closure t) = setdist (s,t))``] THEN 19356 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SETDIST_SYM] THEN 19357 SIMP_TAC std_ss [] THEN 19358 REWRITE_TAC[MESON[REAL_LE_ANTISYM] 19359 ``(x:real = y) <=> !d. d <= x <=> d <= y``] THEN 19360 REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN 19361 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN 19362 ASM_REWRITE_TAC[CLOSURE_EQ_EMPTY, CLOSURE_EMPTY, NOT_IN_EMPTY] THEN 19363 ONCE_REWRITE_TAC [METIS [] ``d <= dist (x,y) <=> (\x y. d <= dist (x,y)) x y``] THEN 19364 ONCE_REWRITE_TAC [METIS [] ``x IN s /\ y IN t <=> x IN s /\ (\y. y IN t) y``] THEN 19365 MATCH_MP_TAC(SET_RULE 19366 ``s SUBSET c /\ 19367 (!y. Q y /\ (!x. x IN s ==> P x y) ==> (!x. x IN c ==> P x y)) 19368 ==> ((!x y. x IN c /\ Q y ==> P x y) <=> 19369 (!x y. x IN s /\ Q y ==> P x y))``) THEN 19370 SIMP_TAC std_ss [CLOSURE_SUBSET] THEN GEN_TAC THEN STRIP_TAC THEN 19371 ONCE_REWRITE_TAC [METIS [] ``dist (x,y) = (\x. dist (x, y)) x``] THEN 19372 MATCH_MP_TAC CONTINUOUS_GE_ON_CLOSURE THEN ASM_SIMP_TAC std_ss [] THEN 19373 ASM_SIMP_TAC std_ss [o_DEF, dist] THEN 19374 ONCE_REWRITE_TAC [METIS [] ``abs (x - y) = abs ((\x. x - y) x:real)``] THEN 19375 MATCH_MP_TAC CONTINUOUS_ON_ABS_COMPOSE THEN 19376 SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID]); 19377 19378val SETDIST_FRONTIER = store_thm ("SETDIST_FRONTIER", 19379 ``(!s t:real->bool. 19380 DISJOINT s t ==> (setdist(frontier s,t) = setdist(s,t))) /\ 19381 (!s t:real->bool. 19382 DISJOINT s t ==> (setdist(s,frontier t) = setdist(s,t)))``, 19383 MATCH_MP_TAC(TAUT `(p ==> q) /\ p ==> p /\ q`) THEN 19384 CONJ_TAC THENL [MESON_TAC[SETDIST_SYM, DISJOINT_SYM], ALL_TAC] THEN 19385 REPEAT STRIP_TAC THEN 19386 GEN_REWR_TAC RAND_CONV [GSYM(CONJUNCT1 SETDIST_CLOSURE)] THEN 19387 MATCH_MP_TAC SETDIST_SUBSETS_EQ THEN 19388 SIMP_TAC std_ss [frontier, IN_DIFF, DIFF_SUBSET, SUBSET_REFL] THEN 19389 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 19390 ASM_CASES_TAC ``(x:real) IN interior s`` THENL 19391 [ALL_TAC, ASM_MESON_TAC[REAL_LE_REFL]] THEN 19392 KNOW_TAC ``?y' x'. (x' IN closure s /\ x' NOTIN interior s) /\ 19393 y' IN t /\ dist (x',y') <= dist (x,y)`` THENL 19394 [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN 19395 EXISTS_TAC ``y:real`` THEN ASM_REWRITE_TAC[] THEN 19396 MP_TAC(ISPECL [``segment[x:real,y]``, ``s:real->bool``] 19397 CONNECTED_INTER_FRONTIER) THEN 19398 REWRITE_TAC[CONNECTED_SEGMENT, GSYM MEMBER_NOT_EMPTY] THEN 19399 KNOW_TAC ``(?x'. x' IN segment [(x,y)] INTER s) /\ 19400 (?x'. x' IN segment [(x,y)] DIFF s)`` THENL 19401 [CONJ_TAC THENL [EXISTS_TAC ``x:real``, EXISTS_TAC ``y:real``] THEN 19402 ASM_SIMP_TAC std_ss [IN_INTER, IN_DIFF, ENDS_IN_SEGMENT] THEN 19403 MP_TAC(ISPEC ``s:real->bool`` INTERIOR_SUBSET) THEN ASM_SET_TAC[], 19404 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 19405 DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN 19406 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [IN_INTER, frontier, IN_DIFF] THEN 19407 MESON_TAC[DIST_IN_CLOSED_SEGMENT]]); 19408 19409val SETDIST_COMPACT_CLOSED = store_thm ("SETDIST_COMPACT_CLOSED", 19410 ``!s t:real->bool. 19411 compact s /\ closed t /\ ~(s = {}) /\ ~(t = {}) 19412 ==> ?x y. x IN s /\ y IN t /\ (dist(x,y) = setdist(s,t))``, 19413 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN 19414 KNOW_TAC ``?x y. (\x. x IN s) x /\ (\y. y IN t) y /\ 19415 (\x y. dist (x,y) <= setdist (s,t)) x y /\ 19416 (\x y. setdist (s,t) <= dist (x,y)) x y`` THENL 19417 [ALL_TAC, METIS_TAC []] THEN 19418 MATCH_MP_TAC(METIS [] 19419 ``(!x y. P x /\ Q y ==> R' x y) /\ (?x y. (P x /\ Q y /\ R x y)) 19420 ==> (?x y. P x /\ Q y /\ R x y /\ R' x y)``) THEN 19421 SIMP_TAC std_ss [SETDIST_LE_DIST] THEN 19422 ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN 19423 MP_TAC(ISPECL [``{x - y:real | x IN s /\ y IN t}``, ``0:real``] 19424 DISTANCE_ATTAINS_INF) THEN 19425 ASM_SIMP_TAC std_ss [COMPACT_CLOSED_DIFFERENCES, EXISTS_IN_GSPEC, FORALL_IN_GSPEC, 19426 DIST_0, GSYM CONJ_ASSOC, GSPECIFICATION, EXISTS_PROD] THEN 19427 REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN 19428 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[]); 19429 19430val SETDIST_CLOSED_COMPACT = store_thm ("SETDIST_CLOSED_COMPACT", 19431 ``!s t:real->bool. 19432 closed s /\ compact t /\ ~(s = {}) /\ ~(t = {}) 19433 ==> ?x y. x IN s /\ y IN t /\ (dist(x,y) = setdist(s,t))``, 19434 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN 19435 KNOW_TAC ``?x y. (\x. x IN s) x /\ (\y. y IN t) y /\ 19436 (\x y. dist (x,y) <= setdist (s,t)) x y /\ 19437 (\x y. setdist (s,t) <= dist (x,y)) x y`` THENL 19438 [ALL_TAC, METIS_TAC []] THEN 19439 MATCH_MP_TAC(METIS[] 19440 ``(!x y. P x /\ Q y ==> R' x y) /\ (?x y. P x /\ Q y /\ R x y) 19441 ==> ?x y. P x /\ Q y /\ R x y /\ R' x y``) THEN 19442 SIMP_TAC std_ss [SETDIST_LE_DIST] THEN 19443 ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN 19444 MP_TAC(ISPECL [``{x - y:real | x IN s /\ y IN t}``, ``0:real``] 19445 DISTANCE_ATTAINS_INF) THEN 19446 ASM_SIMP_TAC std_ss [CLOSED_COMPACT_DIFFERENCES, EXISTS_IN_GSPEC, FORALL_IN_GSPEC, 19447 DIST_0, GSYM CONJ_ASSOC, GSPECIFICATION, EXISTS_PROD] THEN 19448 REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN 19449 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[]); 19450 19451val SETDIST_EQ_0_COMPACT_CLOSED = store_thm ("SETDIST_EQ_0_COMPACT_CLOSED", 19452 ``!s t:real->bool. 19453 compact s /\ closed t 19454 ==> ((setdist(s,t) = &0) <=> (s = {}) \/ (t = {}) \/ ~(s INTER t = {}))``, 19455 REPEAT STRIP_TAC THEN 19456 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN 19457 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN EQ_TAC THENL 19458 [MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] 19459 SETDIST_COMPACT_CLOSED) THEN ASM_REWRITE_TAC[] THEN 19460 REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN MESON_TAC[DIST_EQ_0], 19461 REWRITE_TAC[GSYM REAL_LE_ANTISYM, SETDIST_POS_LE] THEN 19462 REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN 19463 MESON_TAC[SETDIST_LE_DIST, DIST_EQ_0]]); 19464 19465val SETDIST_EQ_0_CLOSED_COMPACT = store_thm ("SETDIST_EQ_0_CLOSED_COMPACT", 19466 ``!s t:real->bool. 19467 closed s /\ compact t 19468 ==> ((setdist(s,t) = &0) <=> (s = {}) \/ (t = {}) \/ ~(s INTER t = {}))``, 19469 ONCE_REWRITE_TAC[SETDIST_SYM] THEN 19470 SIMP_TAC std_ss [SETDIST_EQ_0_COMPACT_CLOSED] THEN SET_TAC[]); 19471 19472val SETDIST_EQ_0_BOUNDED = store_thm ("SETDIST_EQ_0_BOUNDED", 19473 ``!s t:real->bool. 19474 (bounded s \/ bounded t) 19475 ==> ((setdist(s,t) = &0) <=> 19476 (s = {}) \/ (t = {}) \/ ~(closure(s) INTER closure(t) = {}))``, 19477 REPEAT GEN_TAC THEN 19478 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN 19479 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN STRIP_TAC THEN 19480 ONCE_REWRITE_TAC[MESON[SETDIST_CLOSURE] 19481 ``setdist(s,t) = setdist(closure s,closure t)``] THEN 19482 ASM_SIMP_TAC std_ss [SETDIST_EQ_0_COMPACT_CLOSED, SETDIST_EQ_0_CLOSED_COMPACT, 19483 COMPACT_CLOSURE, CLOSED_CLOSURE, CLOSURE_EQ_EMPTY]); 19484 19485val SETDIST_TRANSLATION = store_thm ("SETDIST_TRANSLATION", 19486 ``!a:real s t. 19487 setdist(IMAGE (\x. a + x) s,IMAGE (\x. a + x) t) = setdist(s,t)``, 19488 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[SETDIST_DIFFERENCES] THEN 19489 AP_TERM_TAC THEN AP_TERM_TAC THEN 19490 KNOW_TAC ``!f:real->real->real x:real y:real g:real->real s:real->bool t:real->bool. 19491 {f x y | x IN IMAGE g s /\ y IN IMAGE g t} = {f (g x) (g y) | x IN s /\ y IN t}`` THENL 19492 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 19493 ASM_SET_TAC[], DISCH_TAC] THEN 19494 ONCE_REWRITE_TAC [METIS [] ``x - y = (\x y. x - y) x y:real``] THEN 19495 ASM_REWRITE_TAC [] THEN 19496 SIMP_TAC std_ss [REAL_ARITH ``(a + x) - (a + y):real = x - y``]); 19497 19498val SETDIST_LINEAR_IMAGE = store_thm ("SETDIST_LINEAR_IMAGE", 19499 ``!f:real->real s t. 19500 linear f /\ (!x. abs(f x) = abs x) 19501 ==> (setdist(IMAGE f s,IMAGE f t) = setdist(s,t))``, 19502 REPEAT STRIP_TAC THEN REWRITE_TAC[setdist, IMAGE_EQ_EMPTY] THEN 19503 COND_CASES_TAC THEN ASM_REWRITE_TAC[dist] THEN AP_TERM_TAC THEN 19504 ONCE_REWRITE_TAC [METIS [] ``abs (x - y) = (\x y. abs (x - y)) x y:real``] THEN 19505 KNOW_TAC ``!f:real->real->real x:real y:real g:real->real s:real->bool t:real->bool. 19506 {f x y | x IN IMAGE g s /\ y IN IMAGE g t} = {f (g x) (g y) | x IN s /\ y IN t}`` THENL 19507 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 19508 ASM_SET_TAC[], DISCH_TAC] THEN ASM_REWRITE_TAC [] THEN BETA_TAC THEN 19509 FIRST_X_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN 19510 ASM_SIMP_TAC std_ss []); 19511 19512val SETDIST_UNIQUE = store_thm ("SETDIST_UNIQUE", 19513 ``!s t a b:real d. 19514 a IN s /\ b IN t /\ (dist(a,b) = d) /\ 19515 (!x y. x IN s /\ y IN t ==> dist(a,b) <= dist(x,y)) 19516 ==> (setdist(s,t) = d)``, 19517 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL 19518 [ASM_MESON_TAC[SETDIST_LE_DIST], 19519 MATCH_MP_TAC REAL_LE_SETDIST THEN ASM_SET_TAC[]]); 19520 19521val SETDIST_UNIV = store_thm ("SETDIST_UNIV", 19522 ``(!s. setdist(s,univ(:real)) = &0) /\ 19523 (!t. setdist(univ(:real),t) = &0)``, 19524 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SETDIST_SYM] THEN 19525 REWRITE_TAC[] THEN X_GEN_TAC ``s:real->bool`` THEN 19526 ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[SETDIST_EMPTY] THEN 19527 MATCH_MP_TAC SETDIST_UNIQUE THEN 19528 SIMP_TAC std_ss [IN_UNIV, DIST_EQ_0, RIGHT_EXISTS_AND_THM] THEN 19529 ASM_REWRITE_TAC[UNWIND_THM1, DIST_REFL, DIST_POS_LE, MEMBER_NOT_EMPTY]); 19530 19531val SETDIST_ZERO = store_thm ("SETDIST_ZERO", 19532 ``!s t:real->bool. ~(DISJOINT s t) ==> (setdist(s,t) = &0)``, 19533 REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_UNIQUE THEN 19534 KNOW_TAC ``?a. a IN s /\ a IN t /\ (dist (a,a) = 0) /\ 19535 !x y. x IN s /\ y IN t ==> dist (a,a) <= dist (x,y)`` THENL 19536 [ALL_TAC, METIS_TAC []] THEN 19537 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r /\ s <=> r /\ p /\ q /\ s`] THEN 19538 REWRITE_TAC[DIST_EQ_0, UNWIND_THM2, DIST_REFL, DIST_POS_LE] THEN 19539 ASM_SET_TAC[]); 19540 19541val SETDIST_ZERO_STRONG = store_thm ("SETDIST_ZERO_STRONG", 19542 ``!s t:real->bool. 19543 ~(DISJOINT (closure s) (closure t)) ==> (setdist(s,t) = &0)``, 19544 MESON_TAC[SETDIST_CLOSURE, SETDIST_ZERO]); 19545 19546val SETDIST_FRONTIERS = store_thm ("SETDIST_FRONTIERS", 19547 ``!s t:real->bool. 19548 setdist(s,t) = 19549 if DISJOINT s t then setdist(frontier s,frontier t) else &0``, 19550 REPEAT STRIP_TAC THEN 19551 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [SETDIST_ZERO] THEN 19552 ASSUME_TAC SETDIST_FRONTIER THEN POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 19553 DISCH_THEN (CONJUNCTS_THEN2 K_TAC ASSUME_TAC) THEN ASM_SIMP_TAC std_ss [] THEN 19554 POP_ASSUM K_TAC THEN 19555 ASM_CASES_TAC ``DISJOINT s (frontier t:real->bool)`` THENL 19556 [ASM_MESON_TAC[SETDIST_FRONTIER], ALL_TAC] THEN 19557 GEN_REWR_TAC LAND_CONV [GSYM(CONJUNCT1 SETDIST_CLOSURE)] THEN 19558 CONV_TAC SYM_CONV THEN MATCH_MP_TAC SETDIST_SUBSETS_EQ THEN 19559 SIMP_TAC std_ss [frontier, DIFF_SUBSET, SUBSET_REFL, IN_DIFF] THEN 19560 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 19561 KNOW_TAC ``?y' x'. 19562 (x' IN closure s /\ x' NOTIN interior s) /\ 19563 (y' IN closure t /\ y' NOTIN interior t) /\ dist (x',y') <= dist (x,y)`` THENL 19564 [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN EXISTS_TAC ``y:real`` THEN 19565 ASM_REWRITE_TAC[] THEN 19566 ASM_CASES_TAC ``(x:real) IN interior s`` THENL 19567 [ALL_TAC, ASM_MESON_TAC[REAL_LE_REFL]] THEN 19568 MP_TAC(ISPECL [``segment[x:real,y]``, ``interior s:real->bool``] 19569 CONNECTED_INTER_FRONTIER) THEN 19570 REWRITE_TAC[CONNECTED_SEGMENT, GSYM MEMBER_NOT_EMPTY] THEN 19571 KNOW_TAC ``(?x'. x' IN segment [(x,y)] INTER interior s) /\ 19572 (?x'. x' IN segment [(x,y)] DIFF interior s)`` THENL 19573 [CONJ_TAC THENL [EXISTS_TAC ``x:real``, EXISTS_TAC ``y:real``] THEN 19574 ASM_SIMP_TAC std_ss [IN_INTER, IN_DIFF, ENDS_IN_SEGMENT] THEN 19575 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE 19576 ``y IN u ==> (u INTER v = {}) ==> ~(y IN v)``)) THEN 19577 REWRITE_TAC[INTERIOR_CLOSURE, SET_RULE 19578 ``(s INTER (UNIV DIFF t) = {}) <=> s SUBSET t``] THEN 19579 MATCH_MP_TAC SUBSET_CLOSURE THEN ASM_SET_TAC[], 19580 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 19581 DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN 19582 POP_ASSUM MP_TAC THEN 19583 SIMP_TAC std_ss [IN_INTER, GSYM frontier, GSYM IN_DIFF] THEN 19584 MESON_TAC[FRONTIER_INTERIOR_SUBSET, SUBSET_DEF, DIST_IN_CLOSED_SEGMENT]]); 19585 19586val SETDIST_SING_FRONTIER = store_thm ("SETDIST_SING_FRONTIER", 19587 ``!s x:real. ~(x IN s) ==> (setdist({x},frontier s) = setdist({x},s))``, 19588 MESON_TAC[SET_RULE ``DISJOINT {x} s <=> ~(x IN s)``, SETDIST_FRONTIER]); 19589 19590val SETDIST_CLOSEST_POINT = store_thm ("SETDIST_CLOSEST_POINT", 19591 ``!a:real s. 19592 closed s /\ ~(s = {}) ==> (setdist({a},s) = dist(a,closest_point s a))``, 19593 REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_UNIQUE THEN 19594 SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM, IN_SING, UNWIND_THM2] THEN 19595 EXISTS_TAC ``closest_point s (a:real)`` THEN 19596 ASM_MESON_TAC[CLOSEST_POINT_EXISTS, DIST_SYM]); 19597 19598val SETDIST_EQ_0_SING = store_thm ("SETDIST_EQ_0_SING", 19599 ``(!s x:real. (setdist({x},s) = &0) <=> (s = {}) \/ x IN closure s) /\ 19600 (!s x:real. (setdist(s,{x}) = &0) <=> (s = {}) \/ x IN closure s)``, 19601 SIMP_TAC std_ss [SETDIST_EQ_0_BOUNDED, BOUNDED_SING, CLOSURE_SING] THEN SET_TAC[]); 19602 19603val SETDIST_EQ_0_CLOSED = store_thm ("SETDIST_EQ_0_CLOSED", 19604 ``!s x. closed s ==> ((setdist({x},s) = &0) <=> (s = {}) \/ x IN s)``, 19605 SIMP_TAC std_ss [SETDIST_EQ_0_COMPACT_CLOSED, COMPACT_SING] THEN SET_TAC[]); 19606 19607val SETDIST_EQ_0_CLOSED_IN = store_thm ("SETDIST_EQ_0_CLOSED_IN", 19608 ``!u s x. closed_in (subtopology euclidean u) s /\ x IN u 19609 ==> ((setdist({x},s) = &0) <=> (s = {}) \/ x IN s)``, 19610 REWRITE_TAC[SETDIST_EQ_0_SING, CLOSED_IN_INTER_CLOSURE] THEN SET_TAC[]); 19611 19612val SETDIST_SING_IN_SET = store_thm ("SETDIST_SING_IN_SET", 19613 ``!x s. x IN s ==> (setdist({x},s) = &0)``, 19614 SIMP_TAC std_ss [SETDIST_EQ_0_SING, REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET]); 19615 19616val SETDIST_SING_FRONTIER_CASES = store_thm ("SETDIST_SING_FRONTIER_CASES", 19617 ``!s x:real. 19618 setdist({x},s) = if x IN s then &0 else setdist({x},frontier s)``, 19619 REPEAT GEN_TAC THEN COND_CASES_TAC THEN 19620 ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, SETDIST_SING_FRONTIER]); 19621 19622val SETDIST_SING_TRIANGLE = store_thm ("SETDIST_SING_TRIANGLE", 19623 ``!s x y:real. abs(setdist({x},s) - setdist({y},s)) <= dist(x,y)``, 19624 REPEAT GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 19625 ASM_REWRITE_TAC[SETDIST_EMPTY, REAL_SUB_REFL, ABS_N, DIST_POS_LE] THEN 19626 REWRITE_TAC[ABS_BOUNDS, REAL_NEG_SUB] THEN REPEAT STRIP_TAC THEN 19627 ONCE_REWRITE_TAC[REAL_ARITH ``a - b <= c <=> a - c <= b:real``, 19628 REAL_ARITH ``-a <= b - c <=> c - a <= b:real``] THEN 19629 MATCH_MP_TAC REAL_LE_SETDIST THEN ASM_REWRITE_TAC[NOT_INSERT_EMPTY] THEN 19630 SIMP_TAC std_ss [IN_SING, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2] THEN 19631 X_GEN_TAC ``z:real`` THEN DISCH_TAC THEN REWRITE_TAC [dist] THENL 19632 [MATCH_MP_TAC(REAL_ARITH 19633 ``a <= abs(y:real - z) ==> a - abs(x - y) <= abs(x - z:real)``), 19634 MATCH_MP_TAC(REAL_ARITH 19635 ``a <= abs(x:real - z) ==> a - abs(x - y) <= abs(y - z)``)] THEN 19636 REWRITE_TAC [GSYM dist] THEN 19637 MATCH_MP_TAC SETDIST_LE_DIST THEN ASM_REWRITE_TAC[IN_SING]); 19638 19639val SETDIST_LE_SING = store_thm ("SETDIST_LE_SING", 19640 ``!s t x:real. x IN s ==> setdist(s,t) <= setdist({x},t)``, 19641 REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_SUBSET_LEFT THEN ASM_SET_TAC[]); 19642 19643val SETDIST_BALLS = store_thm ("SETDIST_BALLS", 19644 ``(!a b:real r s. 19645 setdist(ball(a,r),ball(b,s)) = 19646 if r <= &0 \/ s <= &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\ 19647 (!a b:real r s. 19648 setdist(ball(a,r),cball(b,s)) = 19649 if r <= &0 \/ s < &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\ 19650 (!a b:real r s. 19651 setdist(cball(a,r),ball(b,s)) = 19652 if r < &0 \/ s <= &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\ 19653 (!a b:real r s. 19654 setdist(cball(a,r),cball(b,s)) = 19655 if r < &0 \/ s < &0 then &0 else max (&0) (dist(a,b) - (r + s)))``, 19656 REWRITE_TAC[METIS[] 19657 ``(x = if p then y else z) <=> (p ==> (x = y)) /\ (~p ==> (x = z))``] THEN 19658 SIMP_TAC std_ss [TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN 19659 SIMP_TAC std_ss [BALL_EMPTY, CBALL_EMPTY, SETDIST_EMPTY, DE_MORGAN_THM] THEN 19660 ONCE_REWRITE_TAC[METIS[SETDIST_CLOSURE] 19661 ``setdist(s,t) = setdist(closure s,closure t)``] THEN 19662 SIMP_TAC std_ss [REAL_NOT_LE, REAL_NOT_LT, CLOSURE_BALL] THEN 19663 REWRITE_TAC[SETDIST_CLOSURE] THEN 19664 MATCH_MP_TAC(TAUT `(s ==> p /\ q /\ r) /\ s ==> p /\ q /\ r /\ s`) THEN 19665 CONJ_TAC THENL [METIS_TAC[REAL_LT_IMP_LE], REPEAT GEN_TAC] THEN 19666 REWRITE_TAC[max_def, REAL_SUB_LE] THEN COND_CASES_TAC THEN 19667 SIMP_TAC std_ss [SETDIST_EQ_0_BOUNDED, BOUNDED_CBALL, CLOSED_CBALL, CLOSURE_CLOSED, 19668 CBALL_EQ_EMPTY, INTER_BALLS_EQ_EMPTY] 19669 THENL [ALL_TAC, ASM_REAL_ARITH_TAC] THEN 19670 ASM_CASES_TAC ``b:real = a`` THENL 19671 [FIRST_X_ASSUM SUBST_ALL_TAC THEN 19672 RULE_ASSUM_TAC(REWRITE_RULE[DIST_REFL]) THEN 19673 ASM_CASES_TAC ``(r = &0:real) /\ (s = &0:real)`` THENL [ALL_TAC, ASM_REAL_ARITH_TAC] THEN 19674 ASM_SIMP_TAC std_ss [CBALL_SING, SETDIST_SINGS, dist] THEN REAL_ARITH_TAC, 19675 STRIP_TAC] THEN 19676 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL 19677 [ALL_TAC, 19678 MATCH_MP_TAC REAL_LE_SETDIST THEN 19679 ASM_REWRITE_TAC[CBALL_EQ_EMPTY, REAL_NOT_LT, IN_CBALL, dist] THEN 19680 REAL_ARITH_TAC] THEN 19681 MATCH_MP_TAC REAL_LE_TRANS THEN 19682 EXISTS_TAC ``dist(a + r / dist(a,b) * (b - a):real, 19683 b - s / dist(a,b) * (b - a))`` THEN 19684 CONJ_TAC THENL 19685 [MATCH_MP_TAC SETDIST_LE_DIST THEN 19686 REWRITE_TAC[dist, IN_CBALL, REAL_ARITH ``abs(a - (a + x)) = abs x:real``, 19687 REAL_ARITH ``abs(a - (a - x)) = abs x:real``] THEN 19688 REWRITE_TAC [GSYM dist] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN 19689 FULL_SIMP_TAC real_ss [dist, ABS_MUL, ABS_DIV, ABS_ABS, ABS_NZ, 19690 REAL_LT_IMP_NE, REAL_ARITH ``(b <> a) = (b - a <> 0:real)``] THEN 19691 KNOW_TAC ``abs (b - a:real) <> 0`` THENL [METIS_TAC [REAL_LT_IMP_NE], DISCH_TAC] THEN 19692 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_SUB_0, ABS_ZERO] THEN 19693 ASM_REAL_ARITH_TAC, 19694 REWRITE_TAC[dist, REAL_ARITH 19695 ``(a + d * (b - a)) - (b - e * (b - a)):real = 19696 (&1 - d - e) * (a - b:real)``] THEN 19697 REWRITE_TAC[ABS_MUL, real_div, REAL_ARITH 19698 ``&1 - r * y - s * y = &1 - (r + s) * y:real``] THEN REWRITE_TAC [GSYM real_div] THEN 19699 REWRITE_TAC [METIS [GSYM ABS_ABS] ``d * abs (a - b) = d * abs(abs (a - b:real))``] THEN 19700 REWRITE_TAC[GSYM ABS_MUL] THEN 19701 KNOW_TAC ``!n x:real. ~(n = &0) ==> ((&1 - x / n) * n = n - x)`` THENL 19702 [REPEAT GEN_TAC THEN DISCH_TAC THEN 19703 ASM_SIMP_TAC std_ss [REAL_SUB_RDISTRIB, REAL_DIV_RMUL] THEN 19704 REAL_ARITH_TAC, DISCH_TAC] THEN 19705 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``(b <> a) = (abs (a - b) <> 0:real)``]) THEN 19706 ASM_SIMP_TAC real_ss [REAL_SUB_0, ABS_ZERO] THEN 19707 FULL_SIMP_TAC std_ss [dist] THEN SIMP_TAC std_ss [REAL_LE_LT] THEN 19708 DISJ2_TAC THEN REWRITE_TAC [ABS_REFL, REAL_SUB_LE] THEN ASM_REWRITE_TAC []]); 19709 19710(* ------------------------------------------------------------------------- *) 19711(* Use set distance for an easy proof of separation properties etc. *) 19712(* ------------------------------------------------------------------------- *) 19713 19714val SEPARATION_CLOSURES = store_thm ("SEPARATION_CLOSURES", 19715 ``!s t:real->bool. 19716 (s INTER closure(t) = {}) /\ (t INTER closure(s) = {}) 19717 ==> ?u v. DISJOINT u v /\ open u /\ open v /\ 19718 s SUBSET u /\ t SUBSET v``, 19719 REPEAT STRIP_TAC THEN 19720 ASM_CASES_TAC ``s:real->bool = {}`` THENL 19721 [MAP_EVERY EXISTS_TAC [``{}:real->bool``, ``univ(:real)``] THEN 19722 ASM_REWRITE_TAC[OPEN_EMPTY, OPEN_UNIV] THEN ASM_SET_TAC[], 19723 ALL_TAC] THEN 19724 ASM_CASES_TAC ``t:real->bool = {}`` THENL 19725 [MAP_EVERY EXISTS_TAC [``univ(:real)``, ``{}:real->bool``] THEN 19726 ASM_REWRITE_TAC[OPEN_EMPTY, OPEN_UNIV] THEN ASM_SET_TAC[], 19727 ALL_TAC] THEN 19728 EXISTS_TAC ``{x | x IN univ(:real) /\ 19729 (setdist({x},t) - setdist({x},s)) IN 19730 {x | &0 < x}}`` THEN 19731 EXISTS_TAC ``{x | x IN univ(:real) /\ 19732 (setdist({x},t) - setdist({x},s)) IN 19733 {x | x < &0}}`` THEN 19734 REPEAT CONJ_TAC THENL 19735 [REWRITE_TAC[SET_RULE ``DISJOINT s t <=> !x. x IN s /\ x IN t ==> F``] THEN 19736 SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV] THEN REAL_ARITH_TAC, 19737 ONCE_REWRITE_TAC [METIS [] ``(setdist ({x},t) - setdist ({x},s)) = 19738 (\x. setdist ({x},t) - setdist ({x},s)) x``] THEN 19739 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN 19740 SIMP_TAC std_ss [REWRITE_RULE[real_gt] OPEN_HALFSPACE_COMPONENT_GT, OPEN_UNIV] THEN 19741 SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_SETDIST], 19742 ONCE_REWRITE_TAC [METIS [] ``(setdist ({x},t) - setdist ({x},s)) = 19743 (\x. setdist ({x},t) - setdist ({x},s)) x``] THEN 19744 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN 19745 SIMP_TAC std_ss [OPEN_HALFSPACE_COMPONENT_LT, OPEN_UNIV] THEN 19746 SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_SETDIST], 19747 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNIV] THEN 19748 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH 19749 ``&0 <= x /\ (y = &0) /\ ~(x = &0) ==> &0 < x - y:real``), 19750 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNIV] THEN 19751 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH 19752 ``&0 <= y /\ (x = &0) /\ ~(y = &0) ==> x - y < &0:real``)] THEN 19753 ASM_SIMP_TAC std_ss [SETDIST_POS_LE, SETDIST_EQ_0_BOUNDED, BOUNDED_SING] THEN 19754 ASM_SIMP_TAC std_ss [CLOSED_SING, CLOSURE_CLOSED, NOT_INSERT_EMPTY, 19755 REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET, 19756 SET_RULE ``({a} INTER s = {}) <=> ~(a IN s)``] THEN 19757 ASM_SET_TAC[]); 19758 19759val SEPARATION_NORMAL = store_thm ("SEPARATION_NORMAL", 19760 ``!s t:real->bool. 19761 closed s /\ closed t /\ (s INTER t = {}) 19762 ==> ?u v. open u /\ open v /\ 19763 s SUBSET u /\ t SUBSET v /\ (u INTER v = {})``, 19764 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM DISJOINT_DEF] THEN 19765 ONCE_REWRITE_TAC[TAUT 19766 `a /\ b /\ c /\ d /\ e <=> e /\ a /\ b /\ c /\ d`] THEN 19767 MATCH_MP_TAC SEPARATION_CLOSURES THEN 19768 ASM_SIMP_TAC std_ss [CLOSURE_CLOSED] THEN ASM_SET_TAC[]); 19769 19770val SEPARATION_NORMAL_LOCAL = store_thm ("SEPARATION_NORMAL_LOCAL", 19771 ``!s t u:real->bool. 19772 closed_in (subtopology euclidean u) s /\ 19773 closed_in (subtopology euclidean u) t /\ 19774 (s INTER t = {}) 19775 ==> ?s' t'. open_in (subtopology euclidean u) s' /\ 19776 open_in (subtopology euclidean u) t' /\ 19777 s SUBSET s' /\ t SUBSET t' /\ (s' INTER t' = {})``, 19778 REPEAT STRIP_TAC THEN 19779 ASM_CASES_TAC ``s:real->bool = {}`` THENL 19780 [MAP_EVERY EXISTS_TAC [``{}:real->bool``, ``u:real->bool``] THEN 19781 ASM_SIMP_TAC std_ss [OPEN_IN_REFL, OPEN_IN_EMPTY, INTER_EMPTY, EMPTY_SUBSET] THEN 19782 ASM_MESON_TAC[CLOSED_IN_IMP_SUBSET], 19783 ALL_TAC] THEN 19784 ASM_CASES_TAC ``t:real->bool = {}`` THENL 19785 [MAP_EVERY EXISTS_TAC [``u:real->bool``, ``{}:real->bool``] THEN 19786 ASM_SIMP_TAC std_ss [OPEN_IN_REFL, OPEN_IN_EMPTY, INTER_EMPTY, EMPTY_SUBSET] THEN 19787 ASM_MESON_TAC[CLOSED_IN_IMP_SUBSET], 19788 ALL_TAC] THEN 19789 EXISTS_TAC ``{x:real | x IN u /\ setdist({x},s) < setdist({x},t)}`` THEN 19790 EXISTS_TAC ``{x:real | x IN u /\ setdist({x},t) < setdist({x},s)}`` THEN 19791 SIMP_TAC std_ss [EXTENSION, SUBSET_DEF, GSPECIFICATION, SETDIST_SING_IN_SET, IN_INTER, 19792 NOT_IN_EMPTY, SETDIST_POS_LE, CONJ_ASSOC, 19793 REAL_ARITH ``&0 < x <=> &0 <= x /\ ~(x = &0:real)``] THEN 19794 CONJ_TAC THENL [ALL_TAC, METIS_TAC[REAL_LT_ANTISYM]] THEN 19795 ONCE_REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL 19796 [ALL_TAC, 19797 ASM_MESON_TAC[SETDIST_EQ_0_CLOSED_IN, CLOSED_IN_IMP_SUBSET, SUBSET_DEF, 19798 MEMBER_NOT_EMPTY, IN_INTER]] THEN 19799 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN 19800 ONCE_REWRITE_TAC [METIS [] ``(setdist ({x},t) - setdist ({x},s)) = 19801 (\x. setdist ({x},t) - setdist ({x},s)) x``] THEN 19802 REWRITE_TAC[SET_RULE 19803 ``{x:real | x IN u /\ &0 < (f:real->real) x} = 19804 {x:real | x IN u /\ f x IN {x | &0 < x}}``] THEN 19805 CONJ_TAC THEN 19806 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN 19807 REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT, 19808 REWRITE_RULE[real_gt] OPEN_HALFSPACE_COMPONENT_GT, OPEN_UNIV] THEN 19809 SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_SETDIST]); 19810 19811val SEPARATION_NORMAL_COMPACT = store_thm ("SEPARATION_NORMAL_COMPACT", 19812 ``!s t:real->bool. 19813 compact s /\ closed t /\ (s INTER t = {}) 19814 ==> ?u v. open u /\ compact(closure u) /\ open v /\ 19815 s SUBSET u /\ t SUBSET v /\ (u INTER v = {})``, 19816 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE] THEN 19817 REPEAT STRIP_TAC THEN FIRST_ASSUM 19818 (MP_TAC o SPEC ``0:real`` o MATCH_MP BOUNDED_SUBSET_BALL) THEN 19819 DISCH_THEN(X_CHOOSE_THEN ``r:real`` STRIP_ASSUME_TAC) THEN 19820 MP_TAC(ISPECL [``s:real->bool``, ``t UNION (univ(:real) DIFF ball(0,r))``] 19821 SEPARATION_NORMAL) THEN 19822 ASM_SIMP_TAC std_ss [CLOSED_UNION, GSYM OPEN_CLOSED, OPEN_BALL] THEN 19823 KNOW_TAC ``((s :real -> bool) INTER 19824 ((t :real -> bool) UNION 19825 (univ(:real) DIFF ball ((0 :real),(r :real)))) = 19826 ({} :real -> bool))`` THENL [ASM_SET_TAC[], DISCH_TAC THEN 19827 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 19828 STRIP_TAC THEN EXISTS_TAC ``u:real->bool`` THEN 19829 EXISTS_TAC ``v:real->bool`` THEN ASM_REWRITE_TAC[] THEN 19830 CONJ_TAC THENL [MATCH_MP_TAC BOUNDED_CLOSURE, ASM_SET_TAC[]] THEN 19831 MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC ``ball(0:real,r)`` THEN 19832 REWRITE_TAC[BOUNDED_BALL] THEN ASM_SET_TAC[]); 19833 19834val SEPARATION_HAUSDORFF = store_thm ("SEPARATION_HAUSDORFF", 19835 ``!x:real y. 19836 ~(x = y) 19837 ==> ?u v. open u /\ open v /\ x IN u /\ y IN v /\ (u INTER v = {})``, 19838 REPEAT STRIP_TAC THEN 19839 MP_TAC(SPECL [``{x:real}``, ``{y:real}``] SEPARATION_NORMAL) THEN 19840 REWRITE_TAC[SING_SUBSET, CLOSED_SING] THEN 19841 DISCH_THEN MATCH_MP_TAC THEN ASM_SET_TAC[]); 19842 19843val SEPARATION_T2 = store_thm ("SEPARATION_T2", 19844 ``!x:real y. 19845 ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ y IN v /\ 19846 (u INTER v = {})``, 19847 REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC std_ss [SEPARATION_HAUSDORFF] THEN 19848 REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN MESON_TAC[]); 19849 19850val SEPARATION_T1 = store_thm ("SEPARATION_T1", 19851 ``!x:real y. 19852 ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ ~(y IN u) /\ 19853 ~(x IN v) /\ y IN v``, 19854 REPEAT STRIP_TAC THEN EQ_TAC THENL 19855 [ASM_SIMP_TAC std_ss [SEPARATION_T2, EXTENSION, NOT_IN_EMPTY, IN_INTER], 19856 ALL_TAC] THEN MESON_TAC[]); 19857 19858val SEPARATION_T0 = store_thm ("SEPARATION_T0", 19859 ``!x:real y. ~(x = y) <=> ?u. open u /\ ~(x IN u <=> y IN u)``, 19860 MESON_TAC[SEPARATION_T1]); 19861 19862(* ------------------------------------------------------------------------- *) 19863(* Connectedness of the intersection of a chain. *) 19864(* ------------------------------------------------------------------------- *) 19865 19866val CONNECTED_CHAIN = store_thm ("CONNECTED_CHAIN", 19867 ``!f:(real->bool)->bool. 19868 (!s. s IN f ==> compact s /\ connected s) /\ 19869 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) 19870 ==> connected(BIGINTER f)``, 19871 REPEAT STRIP_TAC THEN 19872 ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN 19873 ASM_REWRITE_TAC[BIGINTER_EMPTY, CONNECTED_UNIV] THEN 19874 ABBREV_TAC ``c:real->bool = BIGINTER f`` THEN 19875 SUBGOAL_THEN ``compact(c:real->bool)`` ASSUME_TAC THENL 19876 [EXPAND_TAC "c" THEN MATCH_MP_TAC COMPACT_BIGINTER THEN ASM_SET_TAC[], 19877 ALL_TAC] THEN 19878 ASM_SIMP_TAC std_ss [CONNECTED_CLOSED_SET, COMPACT_IMP_CLOSED, NOT_EXISTS_THM] THEN 19879 MAP_EVERY X_GEN_TAC [``a:real->bool``, ``b:real->bool``] THEN CCONTR_TAC THEN 19880 FULL_SIMP_TAC std_ss [] THEN 19881 MP_TAC(ISPECL [``a:real->bool``, ``b:real->bool``] SEPARATION_NORMAL) THEN 19882 ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN 19883 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 19884 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 19885 SUBGOAL_THEN ``?k:real->bool. k IN f`` STRIP_ASSUME_TAC THENL 19886 [ASM_SET_TAC[], ALL_TAC] THEN 19887 SUBGOAL_THEN ``?n:real->bool. open n /\ k SUBSET n`` MP_TAC THENL 19888 [ASM_MESON_TAC[BOUNDED_SUBSET_BALL, COMPACT_IMP_BOUNDED, OPEN_BALL], 19889 REWRITE_TAC[BIGUNION_SUBSET] THEN STRIP_TAC] THEN 19890 MP_TAC(ISPEC ``k:real->bool`` COMPACT_IMP_HEINE_BOREL) THEN 19891 ASM_SIMP_TAC std_ss [] THEN 19892 KNOW_TAC ``~(!(f' :(real -> bool) -> bool). 19893 ((!(t :real -> bool). t IN f' ==> (open t :bool)) /\ 19894 (k :real -> bool) SUBSET BIGUNION f') ==> 19895 ?(f'' :(real -> bool) -> bool). 19896 (f'' SUBSET f') /\ FINITE f'' /\ (k SUBSET BIGUNION f''))`` THENL 19897 [ALL_TAC, METIS_TAC []] THEN DISCH_THEN (MP_TAC o SPEC 19898 ``(u UNION v:real->bool) INSERT {n DIFF s | s IN f}``) THEN 19899 SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_INSERT, FORALL_IN_IMAGE] THEN 19900 ASM_SIMP_TAC std_ss [OPEN_UNION, OPEN_DIFF, COMPACT_IMP_CLOSED, NOT_IMP] THEN 19901 CONJ_TAC THENL 19902 [REWRITE_TAC[BIGUNION_INSERT] THEN REWRITE_TAC[SUBSET_DEF] THEN 19903 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN ONCE_REWRITE_TAC[IN_UNION] THEN 19904 ASM_CASES_TAC ``(x:real) IN c`` THENL [ASM_SET_TAC[], DISJ2_TAC] THEN 19905 SIMP_TAC std_ss [BIGUNION_IMAGE, GSPECIFICATION] THEN 19906 UNDISCH_TAC ``~((x:real) IN c)`` THEN 19907 SUBST1_TAC(SYM(ASSUME ``BIGINTER f:real->bool = c``)) THEN 19908 SIMP_TAC std_ss [IN_BIGINTER, NOT_FORALL_THM] THEN 19909 STRIP_TAC THEN EXISTS_TAC ``P:real->bool`` THEN ASM_SET_TAC[], 19910 ALL_TAC] THEN 19911 X_GEN_TAC ``g:(real->bool)->bool`` THEN 19912 REWRITE_TAC [GSYM DE_MORGAN_THM] THEN 19913 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN 19914 REWRITE_TAC[SUBSET_INSERT_DELETE] THEN 19915 SUBGOAL_THEN ``FINITE(g DELETE (u UNION v:real->bool))`` MP_TAC THENL 19916 [ASM_REWRITE_TAC[FINITE_DELETE], 19917 REWRITE_TAC[TAUT `p ==> ~q <=> ~(p /\ q)`]] THEN 19918 REWRITE_TAC[FINITE_SUBSET_IMAGE] THEN 19919 DISCH_THEN(X_CHOOSE_THEN ``f':(real->bool)->bool`` STRIP_ASSUME_TAC) THEN 19920 SUBGOAL_THEN 19921 ``?j:real->bool. j IN f /\ 19922 BIGUNION(IMAGE (\s. n DIFF s) f') SUBSET (n DIFF j)`` 19923 STRIP_ASSUME_TAC THENL 19924 [ASM_CASES_TAC ``f':(real->bool)->bool = {}`` THEN 19925 ASM_REWRITE_TAC[IMAGE_EMPTY, IMAGE_INSERT, BIGUNION_EMPTY, EMPTY_SUBSET] THENL 19926 [ASM_SET_TAC[], ALL_TAC] THEN 19927 SUBGOAL_THEN 19928 ``?j:real->bool. j IN f' /\ 19929 BIGUNION(IMAGE (\s. n DIFF s) f') SUBSET (n DIFF j)`` 19930 MP_TAC THENL [ALL_TAC, ASM_MESON_TAC[SUBSET_DEF]] THEN 19931 SUBGOAL_THEN 19932 ``!s t:real->bool. s IN f' /\ t IN f' ==> s SUBSET t \/ t SUBSET s`` 19933 MP_TAC THENL [ASM_MESON_TAC[SUBSET_DEF], ALL_TAC] THEN 19934 UNDISCH_TAC ``~(f':(real->bool)->bool = {})`` THEN 19935 UNDISCH_TAC ``FINITE(f':(real->bool)->bool)`` THEN 19936 SPEC_TAC(``f':(real->bool)->bool``,``f':(real->bool)->bool``) THEN 19937 KNOW_TAC ``!(f' :(real -> bool) -> bool). (f' <> {} ==> 19938 (!s t. s IN f' /\ t IN f' ==> s SUBSET t \/ t SUBSET s) ==> 19939 ?j. j IN f' /\ BIGUNION (IMAGE (\s. n DIFF s) f') SUBSET n DIFF j) = 19940 (\f'. f' <> {} ==> 19941 (!s t. s IN f' /\ t IN f' ==> s SUBSET t \/ t SUBSET s) ==> 19942 ?j. j IN f' /\ BIGUNION (IMAGE (\s. n DIFF s) f') SUBSET n DIFF j) f'`` 19943 THENL [METIS_TAC [], DISC_RW_KILL] THEN 19944 MATCH_MP_TAC FINITE_INDUCT THEN SIMP_TAC std_ss [] THEN 19945 SIMP_TAC std_ss [EXISTS_IN_INSERT, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 19946 SIMP_TAC std_ss [FORALL_IN_INSERT] THEN POP_ASSUM_LIST(K ALL_TAC) THEN 19947 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 19948 MAP_EVERY X_GEN_TAC [``f:(real->bool)->bool``, ``i:real->bool``] THEN 19949 ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN 19950 ASM_SIMP_TAC std_ss [IMAGE_EMPTY, IMAGE_INSERT, BIGUNION_INSERT, NOT_IN_EMPTY, 19951 BIGUNION_EMPTY, UNION_EMPTY, SUBSET_REFL] THEN 19952 REWRITE_TAC [AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN 19953 REWRITE_TAC [GSYM CONJ_ASSOC] THEN REWRITE_TAC [GSYM AND_IMP_INTRO] THEN 19954 DISCH_THEN(fn th => REPEAT DISCH_TAC THEN MP_TAC th) THEN 19955 KNOW_TAC ``(!(s' :real -> bool) (t :real -> bool). 19956 s' IN (f :(real -> bool) -> bool) ==> t IN f ==> 19957 s' SUBSET t \/ t SUBSET s')`` THENL 19958 [ASM_MESON_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 19959 DISCH_THEN(X_CHOOSE_THEN ``j:real->bool`` STRIP_ASSUME_TAC) THEN 19960 SUBGOAL_THEN ``(n DIFF j) SUBSET (n DIFF i) \/ 19961 (n DIFF i:real->bool) SUBSET (n DIFF j)`` 19962 STRIP_ASSUME_TAC THENL 19963 [ASM_SET_TAC[], 19964 DISJ1_TAC THEN ASM_SET_TAC[], 19965 DISJ2_TAC THEN EXISTS_TAC ``j:real->bool`` THEN ASM_SET_TAC[]], 19966 ALL_TAC] THEN 19967 SUBGOAL_THEN ``(j INTER k:real->bool) SUBSET (u UNION v)`` ASSUME_TAC THENL 19968 [MATCH_MP_TAC(SET_RULE 19969 ``k SUBSET (u UNION v) UNION (n DIFF j) 19970 ==> (j INTER k) SUBSET (u UNION v)``) THEN 19971 MATCH_MP_TAC SUBSET_TRANS THEN 19972 EXISTS_TAC ``BIGUNION g :real->bool`` THEN ASM_SIMP_TAC std_ss [] THEN 19973 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC 19974 ``BIGUNION((u UNION v:real->bool) INSERT (g DELETE (u UNION v)))`` THEN 19975 CONJ_TAC THENL [MATCH_MP_TAC SUBSET_BIGUNION THEN SET_TAC[], ALL_TAC] THEN 19976 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[BIGUNION_INSERT] THEN 19977 ASM_SET_TAC[], 19978 ALL_TAC] THEN 19979 SUBGOAL_THEN ``connected(j INTER k:real->bool)`` MP_TAC THENL 19980 [ASM_MESON_TAC[SET_RULE ``s SUBSET t ==> (s INTER t = s)``, INTER_COMM], 19981 REWRITE_TAC[connected] THEN 19982 MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN 19983 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]]); 19984 19985val CONNECTED_CHAIN_GEN = store_thm ("CONNECTED_CHAIN_GEN", 19986 ``!f:(real->bool)->bool. 19987 (!s. s IN f ==> closed s /\ connected s) /\ 19988 (?s. s IN f /\ compact s) /\ 19989 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) 19990 ==> connected(BIGINTER f)``, 19991 GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 19992 FIRST_X_ASSUM(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN 19993 SUBGOAL_THEN 19994 ``BIGINTER f = BIGINTER(IMAGE (\t:real->bool. s INTER t) f)`` 19995 SUBST1_TAC THENL 19996 [SIMP_TAC std_ss [EXTENSION, BIGINTER_IMAGE] THEN ASM_SET_TAC[], 19997 MATCH_MP_TAC CONNECTED_CHAIN THEN 19998 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, FORALL_IN_IMAGE] THEN 19999 ASM_SIMP_TAC std_ss [COMPACT_INTER_CLOSED] THEN 20000 CONJ_TAC THENL [X_GEN_TAC ``t:real->bool``, ASM_SET_TAC[]] THEN 20001 DISCH_TAC THEN 20002 SUBGOAL_THEN ``(s INTER t:real->bool = s) \/ (s INTER t = t)`` 20003 (DISJ_CASES_THEN SUBST1_TAC) THEN 20004 ASM_SET_TAC[]]); 20005 20006val CONNECTED_NEST = store_thm ("CONNECTED_NEST", 20007 ``!s. (!n. compact(s n) /\ connected(s n)) /\ 20008 (!m n. m <= n ==> s n SUBSET s m) 20009 ==> connected(BIGINTER {s n | n IN univ(:num)})``, 20010 GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC CONNECTED_CHAIN THEN 20011 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 20012 ONCE_REWRITE_TAC [METIS [] ``(s n SUBSET s n' \/ s n' SUBSET s n) = 20013 (\n n'. s n SUBSET s n' \/ s n' SUBSET s n) n n'``] THEN 20014 MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]); 20015 20016val CONNECTED_NEST_GEN = store_thm ("CONNECTED_NEST_GEN", 20017 ``!s. (!n. closed(s n) /\ connected(s n)) /\ (?n. compact(s n)) /\ 20018 (!m n. m <= n ==> s n SUBSET s m) 20019 ==> connected(BIGINTER {s n | n IN univ(:num)})``, 20020 GEN_TAC THEN 20021 DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN 20022 MATCH_MP_TAC CONNECTED_CHAIN_GEN THEN 20023 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, 20024 EXISTS_IN_GSPEC] THEN 20025 ONCE_REWRITE_TAC [METIS [] ``(s n SUBSET s n' \/ s n' SUBSET s n) = 20026 (\n n'. s n SUBSET s n' \/ s n' SUBSET s n) n n'``] THEN 20027 MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]); 20028 20029(* ------------------------------------------------------------------------- *) 20030(* Hausdorff distance between sets. *) 20031(* ------------------------------------------------------------------------- *) 20032 20033val hausdist = new_definition ("hausdist", 20034 ``hausdist(s:real->bool,t:real->bool) = 20035 if (({setdist({x},t) | x IN s} UNION {setdist({y},s) | y IN t} <> {}) /\ 20036 (?b. !d. d IN {setdist({x},t) | x IN s} UNION {setdist({y},s) | y IN t} ==> d <= b)) 20037 then sup ({setdist({x},t) | x IN s} UNION {setdist({y},s) | y IN t}) else &0``); 20038 20039val HAUSDIST_POS_LE = store_thm ("HAUSDIST_POS_LE", 20040 ``!s t:real->bool. &0 <= hausdist(s,t)``, 20041 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN 20042 SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION] THEN 20043 COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN 20044 MATCH_MP_TAC REAL_LE_SUP THEN 20045 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION, SETDIST_POS_LE] THEN 20046 KNOW_TAC ``?(y :real) (b :real). 20047 y IN {setdist ({x},(t :real -> bool)) | x IN (s :real -> bool)} UNION 20048 {setdist ({y},s) | y IN t} /\ (0 :real) <= y /\ 20049 (!(x :real). x IN s ==> setdist ({x},t) <= b) /\ 20050 !(y :real). y IN t ==> setdist ({y},s) <= b`` THENL 20051 [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN 20052 ASM_SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM] THEN 20053 ONCE_REWRITE_TAC [METIS [] ``(0 <= y:real) = (\y. 0 <= y) y``] THEN 20054 MATCH_MP_TAC(SET_RULE 20055 ``~(s = {}) /\ (!x. x IN s ==> P x) ==> ?y. y IN s /\ P y``) THEN 20056 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION, SETDIST_POS_LE]); 20057 20058val HAUSDIST_REFL = store_thm ("HAUSDIST_REFL", 20059 ``!s:real->bool. hausdist(s,s) = &0``, 20060 GEN_TAC THEN SIMP_TAC std_ss [GSYM REAL_LE_ANTISYM, HAUSDIST_POS_LE] THEN 20061 REWRITE_TAC[hausdist] THEN 20062 COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN 20063 MATCH_MP_TAC REAL_SUP_LE' THEN 20064 SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION] THEN 20065 ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, REAL_LE_REFL]); 20066 20067val HAUSDIST_SYM = store_thm ("HAUSDIST_SYM", 20068 ``!s t:real->bool. hausdist(s,t) = hausdist(t,s)``, 20069 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN 20070 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [UNION_COMM] THEN 20071 REWRITE_TAC[]); 20072 20073val HAUSDIST_EMPTY = store_thm ("HAUSDIST_EMPTY", 20074 ``(!t:real->bool. hausdist ({},t) = &0) /\ 20075 (!s:real->bool. hausdist (s,{}) = &0)``, 20076 REWRITE_TAC[hausdist, SETDIST_EMPTY] THEN 20077 REWRITE_TAC[SET_RULE ``{setdist ({x},t) | x IN {}} = {}``, UNION_EMPTY] THEN 20078 REWRITE_TAC[SET_RULE ``({c |x| x IN s} = {}) <=> (s = {})``] THEN 20079 X_GEN_TAC ``s:real->bool`` THEN 20080 ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[] THEN 20081 ASM_SIMP_TAC std_ss [SET_RULE ``~(s = {}) ==> ({c |x| x IN s} = {c})``] THEN 20082 REWRITE_TAC[SUP_SING, COND_ID]); 20083 20084val HAUSDIST_SINGS = store_thm ("HAUSDIST_SINGS", 20085 ``!x y:real. hausdist({x},{y}) = dist(x,y)``, 20086 REWRITE_TAC[hausdist, SETDIST_SINGS] THEN 20087 REWRITE_TAC[SET_RULE ``{dist (x,y) | x IN {a}} = {dist (a,y)}``] THEN 20088 ONCE_REWRITE_TAC [METIS [DIST_SYM] ``{dist (x,y)} UNION {dist (y,x)} = 20089 {dist (x,y)} UNION {dist (x,y)}``] THEN 20090 SIMP_TAC std_ss [UNION_IDEMPOT, SUP_SING, NOT_INSERT_EMPTY] THEN 20091 SIMP_TAC std_ss [IN_SING, UNWIND_FORALL_THM2] THEN 20092 METIS_TAC[REAL_LE_REFL]); 20093 20094val HAUSDIST_EQ = store_thm ("HAUSDIST_EQ", 20095 ``!s t:real->bool s' t':real->bool. 20096 (!b. (!x. x IN s ==> setdist({x},t) <= b) /\ 20097 (!y. y IN t ==> setdist({y},s) <= b) <=> 20098 (!x. x IN s' ==> setdist({x},t') <= b) /\ 20099 (!y. y IN t' ==> setdist({y},s') <= b)) 20100 ==> (hausdist(s,t) = hausdist(s',t'))``, 20101 REPEAT STRIP_TAC THEN REWRITE_TAC[hausdist] THEN 20102 MATCH_MP_TAC(METIS[] 20103 ``(p <=> p') /\ (s = s') 20104 ==> ((if p then s else &0:real) = (if p' then s' else &0:real))``) THEN 20105 CONJ_TAC THENL 20106 [BINOP_TAC THENL 20107 [PURE_REWRITE_TAC[SET_RULE ``(s = {}) <=> !x. x IN s ==> F``], 20108 AP_TERM_TAC THEN ABS_TAC], 20109 MATCH_MP_TAC SUP_EQ] THEN 20110 SIMP_TAC std_ss [FORALL_IN_UNION, FORALL_IN_GSPEC] THEN 20111 ASM_REWRITE_TAC[] THEN 20112 ONCE_REWRITE_TAC [METIS [] ``(a = b) = (~a = ~b:bool)``] THEN 20113 REWRITE_TAC [DE_MORGAN_THM] THEN 20114 SIMP_TAC std_ss [NOT_FORALL_THM, MEMBER_NOT_EMPTY] THEN 20115 REWRITE_TAC[GSYM DE_MORGAN_THM] THEN AP_TERM_TAC THEN EQ_TAC THEN 20116 DISCH_THEN(fn th => POP_ASSUM MP_TAC THEN ASSUME_TAC th) THEN 20117 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN 20118 DISCH_THEN(MP_TAC o SPEC ``-(&1):real``) THEN 20119 SIMP_TAC std_ss [SETDIST_POS_LE, REAL_ARITH ``&0 <= x ==> ~(x <= -(&1:real))``] THEN 20120 SET_TAC[]); 20121 20122val HAUSDIST_TRANSLATION = store_thm ("HAUSDIST_TRANSLATION", 20123 ``!a s t:real->bool. 20124 hausdist(IMAGE (\x. a + x) s,IMAGE (\x. a + x) t) = hausdist(s,t)``, 20125 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN 20126 SIMP_TAC real_ss [SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN 20127 SIMP_TAC real_ss [SET_RULE ``{a + x:real} = IMAGE (\x. a + x) {x}``] THEN 20128 REWRITE_TAC[SETDIST_TRANSLATION]); 20129 20130val HAUSDIST_LINEAR_IMAGE = store_thm ("HAUSDIST_LINEAR_IMAGE", 20131 ``!f:real->real s t. 20132 linear f /\ (!x. abs(f x) = abs x) 20133 ==> (hausdist(IMAGE f s,IMAGE f t) = hausdist(s,t))``, 20134 REPEAT STRIP_TAC THEN 20135 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN 20136 SIMP_TAC real_ss [SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN 20137 ONCE_REWRITE_TAC[SET_RULE ``{(f:real->real) x} = IMAGE f {x}``] THEN 20138 ASM_SIMP_TAC std_ss [SETDIST_LINEAR_IMAGE]); 20139 20140val HAUSDIST_CLOSURE = store_thm ("HAUSDIST_CLOSURE", 20141 ``(!s t:real->bool. hausdist(closure s,t) = hausdist(s,t)) /\ 20142 (!s t:real->bool. hausdist(s,closure t) = hausdist(s,t))``, 20143 REPEAT STRIP_TAC THEN MATCH_MP_TAC HAUSDIST_EQ THEN 20144 GEN_TAC THEN BINOP_TAC THEN REWRITE_TAC[SETDIST_CLOSURE] THEN 20145 ONCE_REWRITE_TAC [METIS [] ``setdist ({x},t) <= b <=> (\x. setdist ({x},t) <= b) x``] THEN 20146 PURE_ONCE_REWRITE_TAC[SET_RULE 20147 ``(!x. x IN P ==> Q x) <=> (!x. x IN P ==> (\x. x) x IN {x | Q x})``] THEN 20148 MATCH_MP_TAC FORALL_IN_CLOSURE_EQ THEN 20149 SIMP_TAC std_ss [GSPEC_F, CONTINUOUS_ON_ID, CLOSED_EMPTY] THEN 20150 ONCE_REWRITE_TAC [METIS [] ``setdist ({x},t) = (\x. setdist ({x},t)) x``] THEN 20151 REWRITE_TAC[SET_RULE 20152 ``{x | (f x) <= b:real} = 20153 {x | x IN UNIV /\ (f x) IN {x | x <= b}}``] THEN 20154 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN 20155 SIMP_TAC std_ss [CLOSED_UNIV, CONTINUOUS_ON_SETDIST] THEN 20156 REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE]); 20157 20158val REAL_HAUSDIST_LE = store_thm ("REAL_HAUSDIST_LE", 20159 ``!s t:real->bool b. 20160 ~(s = {}) /\ ~(t = {}) /\ 20161 (!x. x IN s ==> setdist({x},t) <= b) /\ 20162 (!y. y IN t ==> setdist({y},s) <= b) 20163 ==> hausdist(s,t) <= b``, 20164 REPEAT STRIP_TAC THEN 20165 REWRITE_TAC[hausdist, SETDIST_SINGS] THEN 20166 ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN 20167 SIMP_TAC std_ss [FORALL_IN_UNION, FORALL_IN_GSPEC] THEN 20168 COND_CASES_TAC THENL [ALL_TAC, METIS_TAC[]] THEN 20169 MATCH_MP_TAC REAL_SUP_LE' THEN 20170 ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN 20171 ASM_SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC]); 20172 20173val REAL_HAUSDIST_LE_SUMS = store_thm ("REAL_HAUSDIST_LE_SUMS", 20174 ``!s t:real->bool b. 20175 ~(s = {}) /\ ~(t = {}) /\ 20176 s SUBSET {y + z | y IN t /\ z IN cball(0,b)} /\ 20177 t SUBSET {y + z | y IN s /\ z IN cball(0,b)} 20178 ==> hausdist(s,t) <= b``, 20179 SIMP_TAC real_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD, IN_CBALL_0] THEN 20180 SIMP_TAC real_ss [REAL_ARITH ``(a:real = b + x) <=> (a - b = x)``, 20181 ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN 20182 REWRITE_TAC[GSYM dist] THEN REPEAT STRIP_TAC THEN 20183 MATCH_MP_TAC REAL_HAUSDIST_LE THEN 20184 METIS_TAC[SETDIST_LE_DIST, REAL_LE_TRANS, IN_SING]); 20185 20186val REAL_LE_HAUSDIST = store_thm ("REAL_LE_HAUSDIST", 20187 ``!s t:real->bool a b c z. 20188 ~(s = {}) /\ ~(t = {}) /\ 20189 (!x. x IN s ==> setdist({x},t) <= b) /\ 20190 (!y. y IN t ==> setdist({y},s) <= c) /\ 20191 (z IN s /\ a <= setdist({z},t) \/ z IN t /\ a <= setdist({z},s)) 20192 ==> a <= hausdist(s,t)``, 20193 REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 20194 REWRITE_TAC[hausdist, SETDIST_SINGS] THEN 20195 ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN 20196 SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC] THEN COND_CASES_TAC THENL 20197 [MATCH_MP_TAC REAL_LE_SUP THEN 20198 ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN 20199 SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC], 20200 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [NOT_EXISTS_THM]) THEN 20201 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 20202 SIMP_TAC real_ss [NOT_FORALL_THM]] THEN 20203 EXISTS_TAC ``max b c:real`` THEN 20204 ASM_SIMP_TAC real_ss [REAL_LE_MAX] THEN ASM_SET_TAC[]); 20205 20206val SETDIST_LE_HAUSDIST = store_thm ("SETDIST_LE_HAUSDIST", 20207 ``!s t:real->bool. 20208 bounded s /\ bounded t ==> setdist(s,t) <= hausdist(s,t)``, 20209 REPEAT STRIP_TAC THEN 20210 ASM_CASES_TAC ``s:real->bool = {}`` THEN 20211 ASM_SIMP_TAC real_ss [SETDIST_EMPTY, HAUSDIST_EMPTY, REAL_LE_REFL] THEN 20212 ASM_CASES_TAC ``t:real->bool = {}`` THEN 20213 ASM_SIMP_TAC real_ss [SETDIST_EMPTY, HAUSDIST_EMPTY, REAL_LE_REFL] THEN 20214 MATCH_MP_TAC REAL_LE_HAUSDIST THEN REWRITE_TAC[CONJ_ASSOC] THEN 20215 ASM_SIMP_TAC real_ss [RIGHT_EXISTS_AND_THM, LEFT_EXISTS_AND_THM] THEN 20216 CONJ_TAC THENL 20217 [ALL_TAC, METIS_TAC[SETDIST_LE_SING, MEMBER_NOT_EMPTY]] THEN 20218 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20219 ASM_REWRITE_TAC[] THEN SIMP_TAC real_ss [bounded_def, FORALL_IN_GSPEC, GSYM dist] THEN 20220 DISCH_THEN(X_CHOOSE_TAC ``b:real``) THEN 20221 CONJ_TAC THEN EXISTS_TAC ``b:real`` THEN REPEAT STRIP_TAC THEN 20222 METIS_TAC[REAL_LE_TRANS, SETDIST_LE_DIST, MEMBER_NOT_EMPTY, IN_SING, DIST_SYM]); 20223 20224val SETDIST_SING_LE_HAUSDIST = store_thm ("SETDIST_SING_LE_HAUSDIST", 20225 ``!s t x:real. 20226 bounded s /\ bounded t /\ x IN s ==> setdist({x},t) <= hausdist(s,t)``, 20227 REPEAT GEN_TAC THEN 20228 ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN 20229 ASM_CASES_TAC ``t:real->bool = {}`` THEN 20230 ASM_REWRITE_TAC[SETDIST_EMPTY, HAUSDIST_EMPTY, REAL_LE_REFL] THEN 20231 STRIP_TAC THEN MATCH_MP_TAC REAL_LE_HAUSDIST THEN 20232 ASM_SIMP_TAC real_ss [RIGHT_EXISTS_AND_THM] THEN 20233 SIMP_TAC real_ss [LEFT_EXISTS_AND_THM, EXISTS_OR_THM, CONJ_ASSOC] THEN 20234 CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[REAL_LE_REFL]] THEN CONJ_TAC THEN 20235 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20236 ASM_REWRITE_TAC[] THEN SIMP_TAC real_ss [bounded_def, FORALL_IN_GSPEC] THEN 20237 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 20238 POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM dist] THENL 20239 [ALL_TAC, 20240 KNOW_TAC ``(!y x:real. x IN s /\ y IN t ==> dist (x,y) <= a) ==> 20241 !y. y IN t ==> setdist ({y},s) <= a`` THENL 20242 [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]]] THEN 20243 DISCH_TAC THEN X_GEN_TAC ``y:real`` THEN POP_ASSUM (MP_TAC o SPEC ``y:real``) THEN 20244 REPEAT STRIP_TAC THENL 20245 [UNDISCH_TAC ``~(t:real->bool = {})``, 20246 UNDISCH_TAC ``~(s:real->bool = {})``] THEN 20247 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN 20248 DISCH_THEN(X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN 20249 FIRST_X_ASSUM(MP_TAC o SPEC ``z:real``) THEN ASM_REWRITE_TAC[] THEN 20250 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] REAL_LE_TRANS) THENL 20251 [ALL_TAC, ONCE_REWRITE_TAC[DIST_SYM]] THEN 20252 MATCH_MP_TAC SETDIST_LE_DIST THEN ASM_REWRITE_TAC[IN_SING]); 20253 20254val SETDIST_HAUSDIST_TRIANGLE = store_thm ("SETDIST_HAUSDIST_TRIANGLE", 20255 ``!s t u:real->bool. 20256 ~(t = {}) /\ bounded t /\ bounded u 20257 ==> setdist(s,u) <= setdist(s,t) + hausdist(t,u)``, 20258 REPEAT STRIP_TAC THEN 20259 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``u:real->bool = {}``] THEN 20260 ASM_SIMP_TAC real_ss [SETDIST_EMPTY, REAL_LE_ADD, REAL_ADD_LID, 20261 SETDIST_POS_LE, HAUSDIST_POS_LE] THEN 20262 ONCE_REWRITE_TAC[REAL_ARITH ``a <= b + c <=> a - c <= b:real``] THEN 20263 ASM_SIMP_TAC real_ss [REAL_LE_SETDIST_EQ, NOT_INSERT_EMPTY, IN_SING] THEN 20264 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 20265 REWRITE_TAC[REAL_LE_SUB_RADD] THEN 20266 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``setdist({x:real},u)`` THEN 20267 ASM_SIMP_TAC real_ss [SETDIST_LE_SING] THEN 20268 MP_TAC(ISPECL [``u:real->bool``, ``x:real``, ``y:real``] 20269 SETDIST_SING_TRIANGLE) THEN 20270 MATCH_MP_TAC(REAL_ARITH 20271 ``yu <= z ==> abs(xu - yu) <= d ==> xu <= d + z:real``) THEN 20272 MATCH_MP_TAC SETDIST_SING_LE_HAUSDIST THEN ASM_REWRITE_TAC[]); 20273 20274val HAUSDIST_SETDIST_TRIANGLE = store_thm ("HAUSDIST_SETDIST_TRIANGLE", 20275 ``!s t u:real->bool. 20276 ~(t = {}) /\ bounded s /\ bounded t 20277 ==> setdist(s,u) <= hausdist(s,t) + setdist(t,u)``, 20278 ONCE_REWRITE_TAC[SETDIST_SYM, HAUSDIST_SYM] THEN 20279 ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN 20280 SIMP_TAC real_ss [SETDIST_HAUSDIST_TRIANGLE]); 20281 20282val REAL_LT_HAUSDIST_POINT_EXISTS = store_thm ("REAL_LT_HAUSDIST_POINT_EXISTS", 20283 ``!s t x:real d. 20284 bounded s /\ bounded t /\ ~(t = {}) /\ hausdist(s,t) < d /\ x IN s 20285 ==> ?y. y IN t /\ dist(x,y) < d``, 20286 REPEAT STRIP_TAC THEN 20287 MP_TAC(ISPECL [``{x:real}``, ``t:real->bool``, ``d:real``] 20288 REAL_SETDIST_LT_EXISTS) THEN 20289 SIMP_TAC real_ss [IN_SING, RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN 20290 DISCH_THEN MATCH_MP_TAC THEN 20291 ASM_REWRITE_TAC[NOT_INSERT_EMPTY] THEN 20292 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``hausdist(s:real->bool,t)`` THEN 20293 ASM_SIMP_TAC real_ss [] THEN MATCH_MP_TAC SETDIST_SING_LE_HAUSDIST THEN 20294 ASM_REWRITE_TAC[]); 20295 20296val UPPER_LOWER_HEMICONTINUOUS = store_thm ("UPPER_LOWER_HEMICONTINUOUS", 20297 ``!f:real->real->bool t s. 20298 (!x. x IN s ==> f(x) SUBSET t) /\ 20299 (!u. open_in (subtopology euclidean t) u 20300 ==> open_in (subtopology euclidean s) 20301 {x | x IN s /\ f(x) SUBSET u}) /\ 20302 (!u. closed_in (subtopology euclidean t) u 20303 ==> closed_in (subtopology euclidean s) 20304 {x | x IN s /\ f(x) SUBSET u}) 20305 ==> !x e. x IN s /\ &0 < e /\ bounded(f x) 20306 ==> ?d. &0 < d /\ 20307 !x'. x' IN s /\ dist(x,x') < d 20308 ==> hausdist(f x,f x') < e``, 20309 REPEAT GEN_TAC THEN DISCH_TAC THEN REPEAT STRIP_TAC THEN 20310 ASM_CASES_TAC ``(f:real->real->bool) x = {}`` THENL 20311 [ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN METIS_TAC[REAL_LT_01], ALL_TAC] THEN 20312 FIRST_ASSUM(MP_TAC o SPECL [``x:real``, ``e / &2:real``] o MATCH_MP 20313 UPPER_LOWER_HEMICONTINUOUS_EXPLICIT) THEN 20314 ASM_REWRITE_TAC[REAL_HALF] THEN 20315 DISCH_THEN(X_CHOOSE_THEN ``d1:real`` STRIP_ASSUME_TAC) THEN 20316 FIRST_ASSUM(MP_TAC o SPEC ``0:real`` o MATCH_MP BOUNDED_SUBSET_BALL) THEN 20317 DISCH_THEN(X_CHOOSE_THEN ``r:real`` STRIP_ASSUME_TAC) THEN 20318 FIRST_ASSUM(MP_TAC o SPEC ``t INTER ball(0:real,r)`` o 20319 CONJUNCT1 o CONJUNCT2) THEN 20320 SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN REWRITE_TAC[open_in] THEN 20321 DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN 20322 ASM_SIMP_TAC std_ss [SUBSET_INTER, GSPECIFICATION] THEN 20323 DISCH_THEN(X_CHOOSE_THEN ``d2:real`` STRIP_ASSUME_TAC) THEN 20324 EXISTS_TAC ``min d1 d2:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 20325 X_GEN_TAC ``x':real`` THEN STRIP_TAC THEN 20326 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC ``x':real``)) THEN 20327 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN ASM_SIMP_TAC std_ss [] THEN 20328 STRIP_TAC THEN STRIP_TAC THEN 20329 ASM_CASES_TAC ``(f:real->real->bool) x' = {}`` THEN 20330 ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN 20331 KNOW_TAC ``0 < e / 2:real`` THENL [ASM_REWRITE_TAC [REAL_HALF], DISCH_TAC] THEN 20332 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN 20333 MATCH_MP_TAC(REAL_ARITH ``&0 < e / 2 /\ x <= e / &2 ==> x < e / 2 + e / 2:real``) THEN 20334 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_HAUSDIST_LE THEN 20335 METIS_TAC[SETDIST_LE_DIST, DIST_SYM, REAL_LE_TRANS, 20336 IN_SING, REAL_LT_IMP_LE]); 20337 20338val HAUSDIST_NONTRIVIAL = store_thm ("HAUSDIST_NONTRIVIAL", 20339 ``!s t:real->bool. 20340 bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {}) 20341 ==> (hausdist(s,t) = 20342 sup({setdist ({x},t) | x IN s} UNION {setdist ({y},s) | y IN t}))``, 20343 REPEAT STRIP_TAC THEN REWRITE_TAC[hausdist] THEN 20344 COND_CASES_TAC THEN ASM_SIMP_TAC real_ss [] THEN 20345 FIRST_X_ASSUM(MP_TAC o SIMP_RULE real_ss [DE_MORGAN_THM]) THEN 20346 ASM_SIMP_TAC real_ss [EMPTY_UNION, GSYM IMAGE_DEF, IMAGE_EQ_EMPTY] THEN 20347 REWRITE_TAC [METIS [] ``(!b. ?d. d IN P /\ ~(d <= b)) = 20348 ~(?b. !d. d IN P ==> d <= b:real)``] THEN 20349 MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN 20350 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20351 ASM_SIMP_TAC real_ss [bounded_def, FORALL_IN_UNION, FORALL_IN_IMAGE, GSYM dist] THEN 20352 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN POP_ASSUM MP_TAC THEN 20353 SIMP_TAC real_ss [FORALL_IN_GSPEC] THEN 20354 METIS_TAC[SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS, 20355 MEMBER_NOT_EMPTY, IN_SING]); 20356 20357val HAUSDIST_NONTRIVIAL_ALT = store_thm ("HAUSDIST_NONTRIVIAL_ALT", 20358 ``!s t:real->bool. 20359 bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {}) 20360 ==> (hausdist(s,t) = max (sup {setdist ({x},t) | x IN s}) 20361 (sup {setdist ({y},s) | y IN t}))``, 20362 REPEAT STRIP_TAC THEN ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL] THEN 20363 MATCH_MP_TAC SUP_UNION THEN 20364 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, IMAGE_EQ_EMPTY] THEN 20365 CONJ_TAC THEN 20366 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20367 ASM_SIMP_TAC real_ss [bounded_def, FORALL_IN_UNION, FORALL_IN_IMAGE, GSYM dist] THEN 20368 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 20369 POP_ASSUM MP_TAC THEN SIMP_TAC real_ss [FORALL_IN_GSPEC, GSYM dist] THEN 20370 METIS_TAC [SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS, 20371 MEMBER_NOT_EMPTY, IN_SING]); 20372 20373val REAL_HAUSDIST_LE_EQ = store_thm ("REAL_HAUSDIST_LE_EQ", 20374 ``!s t:real->bool b. 20375 ~(s = {}) /\ ~(t = {}) /\ bounded s /\ bounded t 20376 ==> (hausdist(s,t) <= b <=> 20377 (!x. x IN s ==> setdist({x},t) <= b) /\ 20378 (!y. y IN t ==> setdist({y},s) <= b))``, 20379 REPEAT STRIP_TAC THEN 20380 ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL_ALT, REAL_MAX_LE] THEN 20381 BINOP_TAC THEN 20382 ONCE_REWRITE_TAC [METIS [] ``setdist ({x},t) = (\x. setdist ({x},t)) x:real``] THEN 20383 ONCE_REWRITE_TAC [SET_RULE ``(!x. x IN s ==> f x <= b) <=> 20384 (!y. y IN {f x | x IN s} ==> y <= b:real)``] THEN 20385 MATCH_MP_TAC REAL_SUP_LE_EQ THEN 20386 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, IMAGE_EQ_EMPTY, FORALL_IN_IMAGE] THEN 20387 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20388 ASM_SIMP_TAC real_ss [bounded_def, FORALL_IN_UNION, FORALL_IN_IMAGE, GSYM dist] THEN 20389 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 20390 POP_ASSUM MP_TAC THEN SIMP_TAC real_ss [FORALL_IN_GSPEC, GSYM dist] THEN 20391 METIS_TAC[SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS, 20392 MEMBER_NOT_EMPTY, IN_SING]); 20393 20394val HAUSDIST_UNION_LE = store_thm ("HAUSDIST_UNION_LE", 20395 ``!s t u:real->bool. 20396 bounded s /\ bounded t /\ bounded u /\ ~(t = {}) /\ ~(u = {}) 20397 ==> hausdist(s UNION t,s UNION u) <= hausdist(t,u)``, 20398 REPEAT STRIP_TAC THEN 20399 ASM_SIMP_TAC real_ss [REAL_HAUSDIST_LE_EQ, BOUNDED_UNION, EMPTY_UNION] THEN 20400 SIMP_TAC real_ss [FORALL_IN_UNION] THEN 20401 SIMP_TAC real_ss [SETDIST_SING_IN_SET, IN_UNION, HAUSDIST_POS_LE] THEN 20402 ASM_SIMP_TAC real_ss [GSYM REAL_HAUSDIST_LE_EQ, BOUNDED_UNION, EMPTY_UNION] THEN 20403 CONJ_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THENL 20404 [MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``setdist({x:real},u)``, 20405 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``setdist({x:real},t)``] THEN 20406 ASM_SIMP_TAC real_ss [SETDIST_SUBSET_RIGHT, SUBSET_UNION] THENL 20407 [ALL_TAC, ONCE_REWRITE_TAC[HAUSDIST_SYM]] THEN 20408 MATCH_MP_TAC SETDIST_SING_LE_HAUSDIST THEN ASM_REWRITE_TAC[]); 20409 20410val HAUSDIST_INSERT_LE = store_thm ("HAUSDIST_INSERT_LE", 20411 ``!s t a:real. 20412 bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {}) 20413 ==> hausdist(a INSERT s,a INSERT t) <= hausdist(s,t)``, 20414 ONCE_REWRITE_TAC[SET_RULE ``a INSERT s = {a} UNION s``] THEN 20415 ASM_SIMP_TAC real_ss [HAUSDIST_UNION_LE, NOT_INSERT_EMPTY, BOUNDED_SING]); 20416 20417val HAUSDIST_COMPACT_EXISTS = store_thm ("HAUSDIST_COMPACT_EXISTS", 20418 ``!s t:real->bool. 20419 bounded s /\ compact t /\ ~(t = {}) 20420 ==> !x. x IN s ==> ?y. y IN t /\ dist(x,y) <= hausdist(s,t)``, 20421 REPEAT STRIP_TAC THEN 20422 ASM_CASES_TAC ``s:real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN 20423 MP_TAC(ISPECL [``{x:real}``, ``t:real->bool``] 20424 SETDIST_COMPACT_CLOSED) THEN 20425 ASM_SIMP_TAC real_ss [COMPACT_SING, COMPACT_IMP_CLOSED, NOT_INSERT_EMPTY] THEN 20426 SIMP_TAC real_ss [IN_SING, UNWIND_THM2, RIGHT_EXISTS_AND_THM, UNWIND_THM1] THEN 20427 DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN POP_ASSUM MP_TAC THEN 20428 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 20429 MATCH_MP_TAC REAL_LE_HAUSDIST THEN 20430 ASM_SIMP_TAC real_ss [LEFT_EXISTS_AND_THM, RIGHT_EXISTS_AND_THM] THEN 20431 REWRITE_TAC[CONJ_ASSOC] THEN 20432 CONJ_TAC THENL [CONJ_TAC, METIS_TAC[REAL_LE_REFL]] THEN 20433 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20434 ASM_SIMP_TAC real_ss [COMPACT_IMP_BOUNDED] THEN 20435 SIMP_TAC real_ss [bounded_def, FORALL_IN_GSPEC, GSYM dist] THEN 20436 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 20437 METIS_TAC[SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS, 20438 MEMBER_NOT_EMPTY, IN_SING]); 20439 20440val HAUSDIST_TRIANGLE = store_thm ("HAUSDIST_TRIANGLE", 20441 ``!s t u:real->bool. 20442 bounded s /\ bounded t /\ bounded u /\ ~(t = {}) 20443 ==> hausdist(s,u) <= hausdist(s,t) + hausdist(t,u)``, 20444 ONCE_REWRITE_TAC[GSYM(CONJUNCT1 HAUSDIST_CLOSURE)] THEN 20445 ONCE_REWRITE_TAC[GSYM(CONJUNCT2 HAUSDIST_CLOSURE)] THEN 20446 ONCE_REWRITE_TAC[GSYM COMPACT_CLOSURE, GSYM CLOSURE_EQ_EMPTY] THEN 20447 REPEAT GEN_TAC THEN MAP_EVERY 20448 (fn t => SPEC_TAC(mk_comb(``closure:(real->bool)->real->bool``,t),t)) 20449 [``u:real->bool``, ``t:real->bool``, ``s:real->bool``] THEN 20450 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 20451 ASM_REWRITE_TAC[HAUSDIST_EMPTY, HAUSDIST_POS_LE, REAL_ADD_LID] THEN 20452 ASM_CASES_TAC ``u:real->bool = {}`` THEN 20453 ASM_REWRITE_TAC[HAUSDIST_EMPTY, HAUSDIST_POS_LE, REAL_ADD_RID] THEN 20454 ASM_SIMP_TAC real_ss [REAL_HAUSDIST_LE_EQ, COMPACT_IMP_BOUNDED] THEN 20455 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [HAUSDIST_SYM] THEN 20456 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [REAL_ADD_SYM] THEN 20457 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 20458 MAP_EVERY (fn t => SPEC_TAC(t,t)) 20459 [``u:real->bool``, ``t:real->bool``, ``s:real->bool``] THEN 20460 ONCE_REWRITE_TAC [METIS [] ``(~(u = {}) /\ ~(s = {}) /\ ~(t = {}) /\ 20461 compact u /\ compact t /\ compact s) = 20462 (\s t u. ~(u = {}) /\ ~(s = {}) /\ ~(t = {}) /\ 20463 compact u /\ compact t /\ compact s) s t u``] THEN 20464 ONCE_REWRITE_TAC [METIS [] ``(!x. x IN s ==> setdist ({x},u) <= 20465 hausdist (s,t) + hausdist (t,u)) = 20466 (\s t u. !x. x IN s ==> setdist ({x},u) <= 20467 hausdist (s,t) + hausdist (t,u)) s t u ``] THEN 20468 MATCH_MP_TAC(METIS[] 20469 ``(!s t u. P s t u ==> P u t s) /\ 20470 (!s t u. P s t u ==> Q s t u) 20471 ==> (!s t u. P s t u ==> Q s t u /\ Q u t s)``) THEN BETA_TAC THEN 20472 CONJ_TAC THENL [METIS_TAC[CONJ_ACI], REPEAT GEN_TAC THEN STRIP_TAC] THEN 20473 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 20474 SUBGOAL_THEN ``?y:real. y IN t /\ dist(x,y) <= hausdist(s,t)`` 20475 STRIP_ASSUME_TAC THENL 20476 [METIS_TAC[HAUSDIST_COMPACT_EXISTS, COMPACT_IMP_BOUNDED], ALL_TAC] THEN 20477 SUBGOAL_THEN ``?z:real. z IN u /\ dist(y,z) <= hausdist(t,u)`` 20478 STRIP_ASSUME_TAC THENL 20479 [METIS_TAC[HAUSDIST_COMPACT_EXISTS, COMPACT_IMP_BOUNDED], ALL_TAC] THEN 20480 RULE_ASSUM_TAC (REWRITE_RULE [dist]) THEN 20481 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH 20482 ``abs(y - z) <= b ==> abs(x - y) <= a /\ s <= abs(x - z) ==> s <= a + b:real``)) THEN 20483 ASM_REWRITE_TAC[GSYM dist] THEN MATCH_MP_TAC SETDIST_LE_DIST THEN 20484 ASM_REWRITE_TAC[IN_SING]); 20485 20486val HAUSDIST_COMPACT_SUMS = store_thm ("HAUSDIST_COMPACT_SUMS", 20487 ``!s t:real->bool. 20488 bounded s /\ compact t /\ ~(t = {}) 20489 ==> s SUBSET {y + z | y IN t /\ z IN cball(0,hausdist(s,t))}``, 20490 SIMP_TAC real_ss [SUBSET_DEF, GSPECIFICATION, IN_CBALL_0, EXISTS_PROD] THEN 20491 SIMP_TAC real_ss [REAL_ARITH ``(a:real = b + x) <=> (a - b = x)``, 20492 ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN 20493 SIMP_TAC real_ss [GSYM dist, HAUSDIST_COMPACT_EXISTS]); 20494 20495val lemma = prove ( 20496 ``!s t u:real->bool. 20497 bounded s /\ bounded t /\ bounded u /\ 20498 ~(s = {}) /\ ~(t = {}) /\ ~(u = {}) 20499 ==> !x. x IN s ==> setdist({x},u) <= hausdist(s,t) + hausdist(t,u)``, 20500 REPEAT STRIP_TAC THEN 20501 MP_TAC(ISPECL [``closure s:real->bool``, ``closure t:real->bool``] 20502 HAUSDIST_COMPACT_EXISTS) THEN 20503 ASM_SIMP_TAC real_ss [COMPACT_CLOSURE, BOUNDED_CLOSURE, CLOSURE_EQ_EMPTY] THEN 20504 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 20505 ASM_SIMP_TAC real_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET, HAUSDIST_CLOSURE] THEN 20506 DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN 20507 MP_TAC(ISPECL [``closure t:real->bool``, ``closure u:real->bool``] 20508 HAUSDIST_COMPACT_EXISTS) THEN 20509 ASM_SIMP_TAC real_ss [COMPACT_CLOSURE, BOUNDED_CLOSURE, CLOSURE_EQ_EMPTY] THEN 20510 DISCH_THEN(MP_TAC o SPEC ``y:real``) THEN 20511 ASM_SIMP_TAC real_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET, HAUSDIST_CLOSURE] THEN 20512 DISCH_THEN(X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN 20513 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(x:real,z)`` THEN CONJ_TAC THENL 20514 [METIS_TAC[SETDIST_CLOSURE, SETDIST_LE_DIST, IN_SING], ALL_TAC] THEN 20515 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(x:real,y) + dist(y,z)`` THEN 20516 REWRITE_TAC[DIST_TRIANGLE] THEN ASM_REAL_ARITH_TAC); 20517 20518val HAUSDIST_TRANS = store_thm ("HAUSDIST_TRANS", 20519 ``!s t u:real->bool. 20520 bounded s /\ bounded t /\ bounded u /\ ~(t = {}) 20521 ==> hausdist(s,u) <= hausdist(s,t) + hausdist(t,u)``, 20522 REPEAT STRIP_TAC THEN 20523 ASM_CASES_TAC ``s:real->bool = {}`` THEN 20524 ASM_REWRITE_TAC[HAUSDIST_EMPTY, REAL_ADD_LID, HAUSDIST_POS_LE] THEN 20525 ASM_CASES_TAC ``u:real->bool = {}`` THEN 20526 ASM_REWRITE_TAC[HAUSDIST_EMPTY, REAL_ADD_RID, HAUSDIST_POS_LE] THEN 20527 ASM_SIMP_TAC real_ss [REAL_HAUSDIST_LE_EQ] THEN 20528 ASM_MESON_TAC[lemma, HAUSDIST_SYM, SETDIST_SYM, REAL_ADD_SYM]); 20529 20530val HAUSDIST_EQ_0 = store_thm ("HAUSDIST_EQ_0", 20531 ``!s t:real->bool. 20532 bounded s /\ bounded t 20533 ==> ((hausdist(s,t) = &0) <=> (s = {}) \/ (t = {}) \/ (closure s = closure t))``, 20534 REPEAT STRIP_TAC THEN 20535 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN 20536 ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN 20537 ASM_SIMP_TAC real_ss [GSYM REAL_LE_ANTISYM, HAUSDIST_POS_LE, REAL_HAUSDIST_LE_EQ] THEN 20538 SIMP_TAC real_ss [SETDIST_POS_LE, REAL_ARITH ``&0 <= x ==> (x <= &0 <=> (x = &0:real))``] THEN 20539 ASM_SIMP_TAC real_ss [SETDIST_EQ_0_SING, GSYM SUBSET_ANTISYM_EQ, SUBSET_DEF] THEN 20540 SIMP_TAC std_ss [FORALL_IN_CLOSURE_EQ, CLOSED_CLOSURE, CONTINUOUS_ON_ID]); 20541 20542val HAUSDIST_COMPACT_NONTRIVIAL = store_thm ("HAUSDIST_COMPACT_NONTRIVIAL", 20543 ``!s t:real->bool. 20544 compact s /\ compact t /\ ~(s = {}) /\ ~(t = {}) 20545 ==> (hausdist(s,t) = 20546 inf {e | &0 <= e /\ 20547 s SUBSET {x + y | x IN t /\ abs y <= e} /\ 20548 t SUBSET {x + y | x IN s /\ abs y <= e}})``, 20549 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN 20550 MATCH_MP_TAC REAL_INF_UNIQUE THEN 20551 SIMP_TAC real_ss [FORALL_IN_GSPEC, EXISTS_IN_GSPEC] THEN 20552 SIMP_TAC real_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN 20553 SIMP_TAC real_ss [REAL_ARITH ``(a:real = b + x) <=> (a - b = x)``, 20554 ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN 20555 REWRITE_TAC[GSYM dist] THEN CONJ_TAC THENL 20556 [REPEAT STRIP_TAC THEN 20557 MATCH_MP_TAC REAL_HAUSDIST_LE THEN 20558 METIS_TAC[SETDIST_LE_DIST, DIST_SYM, REAL_LE_TRANS, 20559 IN_SING, REAL_LT_IMP_LE], 20560 REPEAT STRIP_TAC THEN EXISTS_TAC ``hausdist(s:real->bool,t)`` THEN 20561 ASM_REWRITE_TAC[HAUSDIST_POS_LE] THEN 20562 METIS_TAC[DIST_SYM, HAUSDIST_SYM, 20563 HAUSDIST_COMPACT_EXISTS, COMPACT_IMP_BOUNDED]]); 20564 20565Theorem HAUSDIST_BALLS : 20566 (!a b:real r s. 20567 hausdist(ball(a,r),ball(b,s)) = 20568 if r <= &0 \/ s <= &0 then &0 else dist(a,b) + abs(r - s)) /\ 20569 (!a b:real r s. 20570 hausdist(ball(a,r),cball(b,s)) = 20571 if r <= &0 \/ s < &0 then &0 else dist(a,b) + abs(r - s)) /\ 20572 (!a b:real r s. 20573 hausdist(cball(a,r),ball(b,s)) = 20574 if r < &0 \/ s <= &0 then &0 else dist(a,b) + abs(r - s)) /\ 20575 (!a b:real r s. 20576 hausdist(cball(a,r),cball(b,s)) = 20577 if r < &0 \/ s < &0 then &0 else dist(a,b) + abs(r - s)) 20578Proof 20579 REWRITE_TAC[METIS[] 20580 ``(x = if p then y else z) <=> (p ==> (x = y)) /\ (~p ==> (x = z))``] THEN 20581 SIMP_TAC real_ss [TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN 20582 SIMP_TAC real_ss [BALL_EMPTY, CBALL_EMPTY, HAUSDIST_EMPTY, DE_MORGAN_THM] THEN 20583 ONCE_REWRITE_TAC[METIS[HAUSDIST_CLOSURE] 20584 ``hausdist(s,t) = hausdist(closure s,closure t)``] THEN 20585 SIMP_TAC real_ss [REAL_NOT_LE, REAL_NOT_LT, CLOSURE_BALL] THEN 20586 REWRITE_TAC[HAUSDIST_CLOSURE] THEN 20587 MATCH_MP_TAC(TAUT `(s ==> p /\ q /\ r) /\ s ==> p /\ q /\ r /\ s`) THEN 20588 CONJ_TAC THENL [MESON_TAC[REAL_LT_IMP_LE], REPEAT STRIP_TAC] THEN 20589 ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL, BOUNDED_CBALL, CBALL_EQ_EMPTY, 20590 REAL_NOT_LT] THEN 20591 MATCH_MP_TAC SUP_UNIQUE THEN 20592 SIMP_TAC real_ss [FORALL_IN_GSPEC, FORALL_IN_UNION] THEN 20593 REWRITE_TAC[MESON[CBALL_SING] ``{a} = cball(a:real,&0)``] THEN 20594 ASM_REWRITE_TAC[SETDIST_BALLS, REAL_LT_REFL] THEN 20595 X_GEN_TAC ``c:real`` THEN REWRITE_TAC[IN_CBALL] THEN 20596 reverse EQ_TAC 20597 >- (RW_TAC real_ss [dist, max_def] \\ 20598 `~(r < 0)` by PROVE_TAC [real_lte] >> rw [] \\ 20599 REAL_ASM_ARITH_TAC) THEN 20600 ASM_CASES_TAC ``b:real = a`` THENL 20601 [ (* goal 1 (of 2) *) 20602 ONCE_ASM_REWRITE_TAC [DIST_SYM] THEN ASM_REWRITE_TAC[DIST_REFL, REAL_MAX_LE] THEN 20603 DISCH_THEN(CONJUNCTS_THEN2 20604 (MP_TAC o SPEC ``a + r * 1:real``) 20605 (MP_TAC o SPEC ``a + s * 1:real``)) THEN 20606 REWRITE_TAC[dist, REAL_ARITH ``abs(a:real - (a + x)) = abs x``] THEN 20607 SIMP_TAC real_ss [ABS_MUL, LESS_EQ_REFL, max_def] \\ 20608 `~(r < 0)` by PROVE_TAC [real_lte] >> rw [] \\ 20609 ASM_REAL_ARITH_TAC, 20610 (* goal 2 (of 2) *) 20611 DISCH_THEN(CONJUNCTS_THEN2 20612 (MP_TAC o SPEC ``a - r / dist(a,b) * (b - a):real``) 20613 (MP_TAC o SPEC ``b - s / dist(a,b) * (a - b):real``)) THEN 20614 REWRITE_TAC[dist, REAL_ARITH ``abs(a:real - (a - x)) = abs x``] THEN 20615 REWRITE_TAC[dist, ABS_MUL, REAL_ARITH 20616 ``b - e * (a - b) - a:real = (&1 + e) * (b - a)``] THEN 20617 ONCE_REWRITE_TAC [METIS [ABS_ABS] ``abs x * abs (a - b) = 20618 abs x * abs (abs (a - b:real))``] THEN 20619 REWRITE_TAC[GSYM ABS_MUL] THEN REWRITE_TAC[ABS_ABS] THEN 20620 ONCE_REWRITE_TAC [METIS [ABS_SUB] ``r / abs (a - b) * abs (b - a) = 20621 r / abs (a - b) * abs (a - b:real)``] THEN 20622 REWRITE_TAC[REAL_ADD_RDISTRIB, REAL_MUL_LID] THEN 20623 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``(b <> a) = (abs (a - b) <> 0:real)``]) THEN 20624 ONCE_REWRITE_TAC [METIS [ABS_SUB] ``r / abs (a - b) * abs (b - a) = 20625 r / abs (a - b) * abs (a - b:real)``] THEN 20626 ASM_SIMP_TAC real_ss [REAL_DIV_RMUL, ABS_ZERO, REAL_SUB_0, max_def] THEN 20627 `~(r < 0)` by PROVE_TAC [real_lte] >> rw [] \\ 20628 ASM_REAL_ARITH_TAC ] 20629QED 20630 20631val HAUSDIST_ALT = store_thm ("HAUSDIST_ALT", 20632 ``!s t:real->bool. 20633 bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {}) 20634 ==> (hausdist(s,t) = 20635 sup {abs(setdist({x},s) - setdist({x},t)) | x IN univ(:real)})``, 20636 REPEAT GEN_TAC THEN 20637 ONCE_REWRITE_TAC[GSYM COMPACT_CLOSURE, GSYM(CONJUNCT2 SETDIST_CLOSURE), 20638 GSYM CLOSURE_EQ_EMPTY, METIS[HAUSDIST_CLOSURE] 20639 ``hausdist(s:real->bool,t) = hausdist(closure s,closure t)``] THEN 20640 SPEC_TAC(``closure t:real->bool``,``t:real->bool``) THEN 20641 SPEC_TAC(``closure s:real->bool``,``s:real->bool``) THEN 20642 REPEAT STRIP_TAC THEN 20643 ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL, COMPACT_IMP_BOUNDED] THEN 20644 MATCH_MP_TAC SUP_EQ THEN 20645 SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC, IN_UNIV] THEN 20646 REWRITE_TAC[REAL_ARITH ``abs(y - x) <= b <=> x <= y + b /\ y <= x + b:real``] THEN 20647 GEN_TAC THEN SIMP_TAC real_ss [FORALL_AND_THM] THEN BINOP_TAC THEN 20648 (EQ_TAC THENL [ALL_TAC, METIS_TAC[SETDIST_SING_IN_SET, REAL_ADD_LID]]) THEN 20649 DISCH_TAC THEN X_GEN_TAC ``z:real`` THENL 20650 [MP_TAC(ISPECL[``{z:real}``, ``s:real->bool``] SETDIST_CLOSED_COMPACT), 20651 MP_TAC(ISPECL[``{z:real}``, ``t:real->bool``] SETDIST_CLOSED_COMPACT)] THEN 20652 ASM_REWRITE_TAC[CLOSED_SING, NOT_INSERT_EMPTY] THEN 20653 SIMP_TAC real_ss [IN_SING, RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN 20654 DISCH_THEN(X_CHOOSE_THEN ``y:real`` (STRIP_ASSUME_TAC o GSYM)) THEN 20655 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN ASM_REWRITE_TAC[] THENL 20656 [MP_TAC(ISPECL[``{y:real}``, ``t:real->bool``] SETDIST_CLOSED_COMPACT), 20657 MP_TAC(ISPECL[``{y:real}``, ``s:real->bool``] SETDIST_CLOSED_COMPACT)] THEN 20658 ASM_REWRITE_TAC[CLOSED_SING, NOT_INSERT_EMPTY] THEN 20659 SIMP_TAC real_ss [IN_SING, RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN 20660 DISCH_THEN(X_CHOOSE_THEN ``x:real`` (STRIP_ASSUME_TAC o GSYM)) THEN 20661 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 20662 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(z:real,x)`` THEN 20663 ASM_SIMP_TAC real_ss [SETDIST_LE_DIST, IN_SING] THEN 20664 UNDISCH_TAC ``dist(y:real,x) <= b`` THEN REWRITE_TAC [dist] THEN REAL_ARITH_TAC); 20665 20666val CONTINUOUS_DIAMETER = store_thm ("CONTINUOUS_DIAMETER", 20667 ``!s:real->bool e. 20668 bounded s /\ ~(s = {}) /\ &0 < e 20669 ==> ?d. &0 < d /\ 20670 !t. bounded t /\ ~(t = {}) /\ hausdist(s,t) < d 20671 ==> abs(diameter s - diameter t) < e``, 20672 REPEAT STRIP_TAC THEN EXISTS_TAC ``e / &2:real`` THEN 20673 ASM_REWRITE_TAC[REAL_HALF] THEN REPEAT STRIP_TAC THEN 20674 SUBGOAL_THEN ``diameter(s:real->bool) - diameter(t:real->bool) = 20675 diameter(closure s) - diameter(closure t)`` 20676 SUBST1_TAC THENL [ASM_MESON_TAC[DIAMETER_CLOSURE], ALL_TAC] THEN 20677 MATCH_MP_TAC REAL_LET_TRANS THEN 20678 EXISTS_TAC ``&2 * hausdist(s:real->bool,t)`` THEN 20679 CONJ_TAC THENL [ALL_TAC, 20680 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 20681 ASM_REAL_ARITH_TAC] THEN 20682 MP_TAC(ISPECL [``0:real``, ``hausdist(s:real->bool,t)``] 20683 DIAMETER_CBALL) THEN 20684 ASM_SIMP_TAC real_ss [HAUSDIST_POS_LE, GSYM REAL_NOT_LE] THEN 20685 DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC(REAL_ARITH 20686 ``x <= y + e /\ y <= x + e ==> abs(x - y) <= e:real``) THEN 20687 CONJ_TAC THEN 20688 W(MP_TAC o PART_MATCH (rand o rand) DIAMETER_SUMS o rand o snd) THEN 20689 ASM_SIMP_TAC real_ss [BOUNDED_CBALL, BOUNDED_CLOSURE] THEN 20690 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] REAL_LE_TRANS) THEN 20691 MATCH_MP_TAC DIAMETER_SUBSET THEN 20692 ASM_SIMP_TAC real_ss [BOUNDED_SUMS, BOUNDED_CBALL, BOUNDED_CLOSURE] THEN 20693 ONCE_REWRITE_TAC[METIS[HAUSDIST_CLOSURE] 20694 ``hausdist(s:real->bool,t) = hausdist(closure s,closure t)``] 20695 THENL [ALL_TAC, ONCE_REWRITE_TAC[HAUSDIST_SYM]] THEN 20696 MATCH_MP_TAC HAUSDIST_COMPACT_SUMS THEN 20697 ASM_SIMP_TAC real_ss [COMPACT_CLOSURE, BOUNDED_CLOSURE, CLOSURE_EQ_EMPTY]); 20698 20699(* ------------------------------------------------------------------------- *) 20700(* Isometries are embeddings, and even surjective in the compact case. *) 20701(* ------------------------------------------------------------------------- *) 20702 20703val ISOMETRY_IMP_OPEN_MAP = store_thm ("ISOMETRY_IMP_OPEN_MAP", 20704 ``!f:real->real s t u. 20705 (IMAGE f s = t) /\ 20706 (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y))) /\ 20707 open_in (subtopology euclidean s) u 20708 ==> open_in (subtopology euclidean t) (IMAGE f u)``, 20709 SIMP_TAC std_ss [open_in, FORALL_IN_IMAGE] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN 20710 CONJ_TAC THENL [ASM_SET_TAC[], X_GEN_TAC ``x:real`` THEN DISCH_TAC] THEN 20711 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 20712 STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[CONJ_EQ_IMP] THEN 20713 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 20714 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF]) THEN 20715 ASM_SIMP_TAC std_ss [IN_IMAGE] THEN ASM_MESON_TAC[]); 20716 20717val ISOMETRY_IMP_EMBEDDING = store_thm ("ISOMETRY_IMP_EMBEDDING", 20718 ``!f:real->real s t. 20719 (IMAGE f s = t) /\ (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y))) 20720 ==> ?g. homeomorphism (s,t) (f,g)``, 20721 REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN 20722 ASM_SIMP_TAC std_ss [ISOMETRY_ON_IMP_CONTINUOUS_ON] THEN 20723 CONJ_TAC THENL [ASM_MESON_TAC[DIST_EQ_0], REPEAT STRIP_TAC] THEN 20724 MATCH_MP_TAC ISOMETRY_IMP_OPEN_MAP THEN ASM_MESON_TAC[]); 20725 20726val ISOMETRY_IMP_HOMEOMORPHISM_COMPACT = store_thm ("ISOMETRY_IMP_HOMEOMORPHISM_COMPACT", 20727 ``!f s:real->bool. 20728 compact s /\ IMAGE f s SUBSET s /\ 20729 (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y))) 20730 ==> ?g. homeomorphism (s,s) (f,g)``, 20731 REPEAT STRIP_TAC THEN 20732 SUBGOAL_THEN ``IMAGE (f:real->real) s = s`` 20733 (fn th => ASM_MESON_TAC[th, ISOMETRY_IMP_EMBEDDING]) THEN 20734 FIRST_ASSUM(ASSUME_TAC o MATCH_MP ISOMETRY_ON_IMP_CONTINUOUS_ON) THEN 20735 ASM_REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN REWRITE_TAC[SUBSET_DEF] THEN 20736 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 20737 SUBGOAL_THEN ``setdist({x},IMAGE (f:real->real) s) = &0`` MP_TAC THENL 20738 [MATCH_MP_TAC(REAL_ARITH ``&0 <= x /\ ~(&0 < x) ==> (x = &0:real)``) THEN 20739 REWRITE_TAC[SETDIST_POS_LE] THEN DISCH_TAC THEN 20740 KNOW_TAC ``?z. (z 0 = (x:real)) /\ !n. z(SUC n) = f(z n)`` THENL 20741 [RW_TAC std_ss [num_Axiom], STRIP_TAC] THEN 20742 SUBGOAL_THEN ``!n. (z:num->real) n IN s`` ASSUME_TAC THENL 20743 [INDUCT_TAC THEN ASM_SET_TAC[], ALL_TAC] THEN 20744 UNDISCH_TAC ``compact s`` THEN DISCH_TAC THEN 20745 FIRST_ASSUM(MP_TAC o REWRITE_RULE [compact]) THEN 20746 DISCH_THEN(MP_TAC o SPEC ``z:num->real``) THEN 20747 ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN 20748 MAP_EVERY X_GEN_TAC [``l:real``, ``r:num->num``] THEN CCONTR_TAC THEN 20749 FULL_SIMP_TAC std_ss [] THEN 20750 FIRST_ASSUM(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN 20751 REWRITE_TAC[cauchy] THEN 20752 DISCH_THEN(MP_TAC o SPEC ``setdist({x},IMAGE (f:real->real) s)``) THEN 20753 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN ``N:num`` 20754 (MP_TAC o SPECL [``N:num``, ``N + 1:num``])) THEN 20755 KNOW_TAC ``N >= N /\ N + 1 >= N:num`` THENL 20756 [ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 20757 POP_ASSUM K_TAC THEN REWRITE_TAC[REAL_NOT_LT, o_THM]] THEN 20758 SUBGOAL_THEN ``(r:num->num) N < r (N + 1)`` MP_TAC THENL 20759 [RULE_ASSUM_TAC (REWRITE_RULE [METIS [] ``(~a \/ b) = (a ==> b)``]) THEN 20760 FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC, 20761 SIMP_TAC std_ss [LT_EXISTS, LEFT_IMP_EXISTS_THM]] THEN 20762 X_GEN_TAC ``d:num`` THEN DISCH_THEN SUBST1_TAC THEN 20763 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(x:real,z(SUC d))`` THEN CONJ_TAC THENL 20764 [MATCH_MP_TAC SETDIST_LE_DIST THEN ASM_SET_TAC[], ALL_TAC] THEN 20765 MATCH_MP_TAC REAL_EQ_IMP_LE THEN 20766 SPEC_TAC(``(r:num->num) N``,``m:num``) THEN 20767 INDUCT_TAC THEN ASM_MESON_TAC[ADD_CLAUSES], 20768 REWRITE_TAC[SETDIST_EQ_0_SING, IMAGE_EQ_EMPTY] THEN 20769 ASM_MESON_TAC[COMPACT_IMP_CLOSED, NOT_IN_EMPTY, 20770 COMPACT_CONTINUOUS_IMAGE, CLOSURE_CLOSED]]); 20771 20772(* ------------------------------------------------------------------------- *) 20773(* Urysohn's lemma (for real, where the proof is easy using distances). *) 20774(* ------------------------------------------------------------------------- *) 20775 20776val lemma = prove ( 20777 ``!s t u a b. 20778 closed_in (subtopology euclidean u) s /\ 20779 closed_in (subtopology euclidean u) t /\ 20780 (s INTER t = {}) /\ ~(s = {}) /\ ~(t = {}) /\ ~(a = b) 20781 ==> ?f:real->real. 20782 f continuous_on u /\ 20783 (!x. x IN u ==> f(x) IN segment[a,b]) /\ 20784 (!x. x IN u ==> ((f x = a) <=> x IN s)) /\ 20785 (!x. x IN u ==> ((f x = b) <=> x IN t))``, 20786 REPEAT STRIP_TAC THEN EXISTS_TAC 20787 ``\x:real. a + setdist({x},s) / (setdist({x},s) + setdist({x},t)) * 20788 (b - a:real)`` THEN SIMP_TAC std_ss [] THEN 20789 SUBGOAL_THEN 20790 ``(!x:real. x IN u ==> ((setdist({x},s) = &0) <=> x IN s)) /\ 20791 (!x:real. x IN u ==> ((setdist({x},t) = &0) <=> x IN t))`` 20792 STRIP_ASSUME_TAC THENL 20793 [ASM_REWRITE_TAC[SETDIST_EQ_0_SING] THEN CONJ_TAC THENL 20794 [MP_TAC(ISPEC ``s:real->bool`` CLOSED_IN_CLOSED), 20795 MP_TAC(ISPEC ``t:real->bool`` CLOSED_IN_CLOSED)] THEN 20796 DISCH_THEN(MP_TAC o SPEC ``u:real->bool``) THEN 20797 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN ``v:real->bool`` 20798 (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN 20799 ASM_MESON_TAC[CLOSURE_CLOSED, INTER_SUBSET, SUBSET_CLOSURE, SUBSET_DEF, 20800 IN_INTER, CLOSURE_SUBSET], 20801 ALL_TAC] THEN 20802 SUBGOAL_THEN ``!x:real. x IN u ==> &0 < setdist({x},s) + setdist({x},t)`` 20803 ASSUME_TAC THENL 20804 [REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH 20805 ``&0 <= x /\ &0 <= y /\ ~((x = &0) /\ (y = &0)) ==> &0 < x + y:real``) THEN 20806 REWRITE_TAC[SETDIST_POS_LE] THEN ASM_SET_TAC[], 20807 ALL_TAC] THEN 20808 REPEAT CONJ_TAC THENL 20809 [ONCE_REWRITE_TAC [METIS [] ``(\x. a + 20810 setdist ({x},s) / (setdist ({x},s) + setdist ({x},t)) * (b - a)) = 20811 (\x. (\x. a) x + 20812 (\x. setdist ({x},s) / (setdist ({x},s) + setdist ({x},t)) * (b - a)) x)``] THEN 20813 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN 20814 REWRITE_TAC[real_div, GSYM REAL_MUL_ASSOC] THEN 20815 ONCE_REWRITE_TAC [METIS [] ``(\x. setdist ({x},s) * 20816 (inv (setdist ({x},s) + setdist ({x},t)) * (b - a))) = 20817 (\x. (\x. setdist ({x},s)) x * 20818 (\x. (inv (setdist ({x},s) + setdist ({x},t)) * (b - a))) x)``] THEN 20819 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN CONJ_TAC THENL 20820 [REWRITE_TAC[CONTINUOUS_ON_SETDIST], ALL_TAC] THEN 20821 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (setdist ({x},s) + setdist ({x},t)) * (b - a)) = 20822 (\x. (\x. inv (setdist ({x},s) + setdist ({x},t))) x * (\x. (b - a)) x)``] THEN 20823 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_CONST, o_DEF] THEN 20824 REWRITE_TAC[CONTINUOUS_ON_SETDIST] THEN 20825 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (setdist ({x},s) + setdist ({x},t))) = 20826 (\x. inv ((\x. setdist ({x},s) + setdist ({x},t)) x))``] THEN 20827 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN 20828 ASM_SIMP_TAC std_ss [REAL_LT_IMP_NE] THEN 20829 ONCE_REWRITE_TAC [METIS [] ``(\x. setdist ({x},s) + setdist ({x},t)) = 20830 (\x. (\x. setdist ({x},s)) x + (\x. setdist ({x},t)) x)``] THEN 20831 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN 20832 REWRITE_TAC[CONTINUOUS_ON_SETDIST], 20833 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 20834 SIMP_TAC std_ss[segment, GSPECIFICATION] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN 20835 SIMP_TAC real_ss [REAL_ENTIRE, LEFT_AND_OVER_OR, REAL_ARITH 20836 ``(a + x * (b - a):real = (&1 - u) * a + u * b) <=> 20837 ((x - u) * (b - a) = 0)``, EXISTS_OR_THM] THEN 20838 DISJ1_TAC THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN 20839 REWRITE_TAC[REAL_SUB_0, UNWIND_THM1] THEN 20840 ASM_SIMP_TAC std_ss [REAL_LE_DIV, REAL_LE_ADD, SETDIST_POS_LE, REAL_LE_LDIV_EQ, 20841 REAL_ARITH ``a <= &1 * (a + b) <=> &0 <= b:real``], 20842 SIMP_TAC real_ss [REAL_ARITH ``(a + x:real = a) <=> (x = 0)``], 20843 REWRITE_TAC[REAL_ARITH ``(a + x * (b - a):real = b) <=> 20844 ((x - &1) * (b - a) = 0)``]] THEN 20845 ASM_REWRITE_TAC[REAL_ENTIRE, REAL_SUB_0] THEN 20846 ASM_SIMP_TAC std_ss [REAL_SUB_0, REAL_EQ_LDIV_EQ, 20847 REAL_MUL_LZERO, REAL_MUL_LID] THEN 20848 REWRITE_TAC[REAL_ARITH ``(x:real = x + y) <=> (y = &0)``] THEN 20849 ASM_REWRITE_TAC[]); 20850 20851val URYSOHN_LOCAL_STRONG = store_thm ("URYSOHN_LOCAL_STRONG", 20852 ``!s t u a b. 20853 closed_in (subtopology euclidean u) s /\ 20854 closed_in (subtopology euclidean u) t /\ 20855 (s INTER t = {}) /\ ~(a = b) 20856 ==> ?f:real->real. 20857 f continuous_on u /\ 20858 (!x. x IN u ==> f(x) IN segment[a,b]) /\ 20859 (!x. x IN u ==> ((f x = a) <=> x IN s)) /\ 20860 (!x. x IN u ==> ((f x = b) <=> x IN t))``, 20861 KNOW_TAC ``!(s :real -> bool) (t :real -> bool). 20862 (\s t. !(u :real -> bool) (a :real) (b :real). 20863 closed_in (subtopology euclidean u) s /\ 20864 closed_in (subtopology euclidean u) t /\ 20865 (s INTER t = ({} :real -> bool)) /\ a <> b ==> 20866 ?(f :real -> real). 20867 f continuous_on u /\ 20868 (!(x :real). x IN u ==> f x IN segment [(a,b)]) /\ 20869 (!(x :real). x IN u ==> ((f x = a) <=> x IN s)) /\ 20870 !(x :real). x IN u ==> ((f x = b) <=> x IN t)) s t`` THENL 20871 [ALL_TAC, SIMP_TAC std_ss []] THEN 20872 MATCH_MP_TAC(MESON[] 20873 ``(!s t. P s t <=> P t s) /\ 20874 (!s t. ~(s = {}) /\ ~(t = {}) ==> P s t) /\ 20875 P {} {} /\ (!t. ~(t = {}) ==> P {} t) 20876 ==> !s t. P s t``) THEN 20877 SIMP_TAC std_ss [] THEN REPEAT CONJ_TAC THENL 20878 20879 [REPEAT GEN_TAC THEN 20880 KNOW_TAC ``(!(u :real -> bool) (a :real) (b :real). 20881 closed_in (subtopology euclidean u) (s :real -> bool) /\ 20882 closed_in (subtopology euclidean u) (t :real -> bool) /\ 20883 (s INTER t = ({} :real -> bool)) /\ a <> b ==> 20884 ?(f :real -> real). 20885 f continuous_on u /\ 20886 (!(x :real). x IN u ==> f x IN segment [(a,b)]) /\ 20887 (!(x :real). x IN u ==> ((f x = a) <=> x IN s)) /\ 20888 !(x :real). x IN u ==> ((f x = b) <=> x IN t)) <=> 20889 !(u :real -> bool) (b :real) (a :real). 20890 closed_in (subtopology euclidean u) t /\ 20891 closed_in (subtopology euclidean u) s /\ 20892 (t INTER s = ({} :real -> bool)) /\ a <> b ==> 20893 ?(f :real -> real). 20894 f continuous_on u /\ 20895 (!(x :real). x IN u ==> f x IN segment [(a,b)]) /\ 20896 (!(x :real). x IN u ==> ((f x = a) <=> x IN t)) /\ 20897 !(x :real). x IN u ==> ((f x = b) <=> x IN s)`` THENL 20898 [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 20899 EQ_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THENL 20900 [POP_ASSUM (MP_TAC o SPECL [``u:real->bool``,``b:real``,``a:real``]), 20901 POP_ASSUM (MP_TAC o SPECL [``u:real->bool``,``a:real``,``b:real``])] THEN 20902 SIMP_TAC std_ss []] THEN 20903 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN 20904 METIS_TAC[SEGMENT_SYM, INTER_COMM, CONJ_ACI, EQ_SYM_EQ], 20905 SIMP_TAC real_ss [lemma], 20906 REPEAT STRIP_TAC THEN EXISTS_TAC ``(\x. midpoint(a,b)):real->real`` THEN 20907 ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, CONTINUOUS_ON_CONST, MIDPOINT_IN_SEGMENT] THEN 20908 REWRITE_TAC[midpoint] THEN CONJ_TAC THEN GEN_TAC THEN DISCH_TAC THEN 20909 UNDISCH_TAC ``~(a:real = b)`` THEN REWRITE_TAC[GSYM MONO_NOT_EQ] THEN 20910 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN 20911 SIMP_TAC std_ss [REAL_EQ_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 20912 REAL_ARITH_TAC, 20913 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``t:real->bool = u`` THENL 20914 [EXISTS_TAC ``(\x. b):real->real`` THEN 20915 ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, ENDS_IN_SEGMENT, IN_UNIV, 20916 CONTINUOUS_ON_CONST], 20917 SUBGOAL_THEN ``?c:real. c IN u /\ ~(c IN t)`` STRIP_ASSUME_TAC THENL 20918 [REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN 20919 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM_SET_TAC[], 20920 ALL_TAC] THEN 20921 MP_TAC(ISPECL [``{c:real}``, ``t:real->bool``, ``u:real->bool``, 20922 ``midpoint(a,b):real``, ``b:real``] lemma) THEN 20923 ASM_REWRITE_TAC[CLOSED_IN_SING, MIDPOINT_EQ_ENDPOINT] THEN 20924 KNOW_TAC ``({(c :real)} INTER (t :real -> bool) = ({} :real -> bool)) /\ 20925 {c} <> ({} :real -> bool)`` THENL 20926 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 20927 DISCH_THEN (X_CHOOSE_TAC ``f:real->real``) THEN EXISTS_TAC ``f:real->real`` THEN 20928 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IN_EMPTY] THEN 20929 STRIP_TAC THEN CONJ_TAC THENL 20930 [SUBGOAL_THEN 20931 ``segment[midpoint(a,b):real,b] SUBSET segment[a,b]`` MP_TAC 20932 THENL 20933 [REWRITE_TAC[SUBSET_DEF, IN_SEGMENT, midpoint] THEN GEN_TAC THEN 20934 DISCH_THEN(X_CHOOSE_THEN ``u:real`` STRIP_ASSUME_TAC) THEN 20935 EXISTS_TAC ``(&1 + u) / &2:real`` THEN ASM_REWRITE_TAC[] THEN 20936 SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 20937 CONJ_TAC THENL [UNDISCH_TAC ``0 <= u:real`` THEN REAL_ARITH_TAC, ALL_TAC] THEN 20938 CONJ_TAC THENL [UNDISCH_TAC ``u <= 1:real`` THEN REAL_ARITH_TAC, ALL_TAC] THEN 20939 ONCE_REWRITE_TAC [REAL_ARITH ``a * (b * c) = (a * c) * b:real``] THEN 20940 GEN_REWR_TAC (LAND_CONV o RAND_CONV) [GSYM REAL_MUL_RID] THEN 20941 ONCE_REWRITE_TAC [METIS [REAL_DIV_REFL, REAL_ARITH ``2 <> 0:real``] 20942 ``u * b * 1 = u * b * (2 / 2:real)``] THEN REWRITE_TAC [real_div] THEN 20943 ONCE_REWRITE_TAC [REAL_ARITH ``u * b * (2 * inv 2) = (u * b * 2) * inv 2:real``] THEN 20944 REWRITE_TAC [GSYM REAL_ADD_RDISTRIB] THEN REWRITE_TAC [GSYM real_div] THEN 20945 SIMP_TAC real_ss [REAL_EQ_LDIV_EQ] THEN REWRITE_TAC [REAL_ADD_RDISTRIB] THEN 20946 REWRITE_TAC [real_div, REAL_SUB_RDISTRIB] THEN 20947 REWRITE_TAC [REAL_ARITH 20948 ``(1 + u) * inv 2 * a * 2 = (1 + u) * a * (inv 2 * 2:real)``] THEN 20949 SIMP_TAC real_ss [REAL_MUL_LINV] THEN REAL_ARITH_TAC, 20950 ASM_SET_TAC[]], 20951 SUBGOAL_THEN ``~(a IN segment[midpoint(a,b):real,b])`` MP_TAC THENL 20952 [ALL_TAC, ASM_MESON_TAC[]] THEN 20953 DISCH_THEN(MP_TAC o CONJUNCT2 o MATCH_MP DIST_IN_CLOSED_SEGMENT) THEN 20954 REWRITE_TAC[DIST_MIDPOINT] THEN 20955 UNDISCH_TAC ``~(a:real = b)`` THEN REWRITE_TAC [dist] THEN 20956 SIMP_TAC real_ss [REAL_LE_RDIV_EQ] THEN REWRITE_TAC [REAL_NOT_LE] THEN 20957 REWRITE_TAC [abs] THEN COND_CASES_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC]]]); 20958 20959val URYSOHN_LOCAL = store_thm ("URYSOHN_LOCAL", 20960 ``!s t u a b. 20961 closed_in (subtopology euclidean u) s /\ 20962 closed_in (subtopology euclidean u) t /\ 20963 (s INTER t = {}) 20964 ==> ?f:real->real. 20965 f continuous_on u /\ 20966 (!x. x IN u ==> f(x) IN segment[a,b]) /\ 20967 (!x. x IN s ==> (f x = a)) /\ 20968 (!x. x IN t ==> (f x = b))``, 20969 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``a:real = b`` THENL 20970 [EXISTS_TAC ``(\x. b):real->real`` THEN 20971 ASM_REWRITE_TAC[ENDS_IN_SEGMENT, CONTINUOUS_ON_CONST], 20972 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``, ``u:real->bool``, 20973 ``a:real``, ``b:real``] URYSOHN_LOCAL_STRONG) THEN 20974 ASM_REWRITE_TAC[] THEN DISCH_THEN (X_CHOOSE_TAC ``f:real->real``) THEN 20975 EXISTS_TAC ``f:real->real`` THEN POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [] THEN 20976 REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN 20977 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN SET_TAC[]]); 20978 20979val URYSOHN_STRONG = store_thm ("URYSOHN_STRONG", 20980 ``!s t a b. 20981 closed s /\ closed t /\ (s INTER t = {}) /\ ~(a = b) 20982 ==> ?f:real->real. 20983 f continuous_on univ(:real) /\ (!x. f(x) IN segment[a,b]) /\ 20984 (!x. (f x = a) <=> x IN s) /\ (!x. (f x = b) <=> x IN t)``, 20985 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN 20986 ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN 20987 DISCH_THEN(MP_TAC o MATCH_MP URYSOHN_LOCAL_STRONG) THEN 20988 REWRITE_TAC[IN_UNIV]); 20989 20990val URYSOHN = store_thm ("URYSOHN", 20991 ``!s t a b. 20992 closed s /\ closed t /\ (s INTER t = {}) 20993 ==> ?f:real->real. 20994 f continuous_on univ(:real) /\ (!x. f(x) IN segment[a,b]) /\ 20995 (!x. x IN s ==> (f x = a)) /\ (!x. x IN t ==> (f x = b))``, 20996 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN 20997 ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN DISCH_THEN 20998 (MP_TAC o ISPECL [``a:real``, ``b:real``] o MATCH_MP URYSOHN_LOCAL) THEN 20999 REWRITE_TAC[IN_UNIV]); 21000 21001(* ------------------------------------------------------------------------- *) 21002(* Basics about "local" properties in general. *) 21003(* ------------------------------------------------------------------------- *) 21004 21005val locally = new_definition ("locally", 21006 ``locally P (s:real->bool) <=> 21007 !w x. open_in (subtopology euclidean s) w /\ x IN w 21008 ==> ?u v. open_in (subtopology euclidean s) u /\ P v /\ 21009 x IN u /\ u SUBSET v /\ v SUBSET w``); 21010 21011val LOCALLY_MONO = store_thm ("LOCALLY_MONO", 21012 ``!P Q s. (!t. P t ==> Q t) /\ locally P s ==> locally Q s``, 21013 REWRITE_TAC[locally] THEN MESON_TAC[]); 21014 21015val LOCALLY_OPEN_SUBSET = store_thm ("LOCALLY_OPEN_SUBSET", 21016 ``!P s t:real->bool. 21017 locally P s /\ open_in (subtopology euclidean s) t 21018 ==> locally P t``, 21019 REPEAT GEN_TAC THEN REWRITE_TAC[locally] THEN STRIP_TAC THEN 21020 MAP_EVERY X_GEN_TAC [``w:real->bool``, ``x:real``] THEN STRIP_TAC THEN 21021 FIRST_X_ASSUM(MP_TAC o SPECL [``w:real->bool``, ``x:real``]) THEN 21022 KNOW_TAC ``open_in (subtopology euclidean s) w /\ x IN w`` THENL 21023 [ASM_MESON_TAC[OPEN_IN_TRANS], 21024 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 21025 STRIP_TAC THEN EXISTS_TAC ``u:real->bool`` THEN EXISTS_TAC ``v:real->bool`` THEN 21026 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC OPEN_IN_SUBSET_TRANS THEN 21027 EXISTS_TAC ``s:real->bool`` THEN ASM_MESON_TAC[open_in, SUBSET_DEF]); 21028 21029val LOCALLY_DIFF_CLOSED = store_thm ("LOCALLY_DIFF_CLOSED", 21030 ``!P s t:real->bool. 21031 locally P s /\ closed_in (subtopology euclidean s) t 21032 ==> locally P (s DIFF t)``, 21033 REPEAT STRIP_TAC THEN 21034 MATCH_MP_TAC LOCALLY_OPEN_SUBSET THEN 21035 EXISTS_TAC ``s:real->bool`` THEN ASM_REWRITE_TAC[] THEN 21036 MATCH_MP_TAC OPEN_IN_DIFF THEN 21037 ASM_REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL, SUBSET_UNIV, TOPSPACE_EUCLIDEAN]); 21038 21039val LOCALLY_EMPTY = store_thm ("LOCALLY_EMPTY", 21040 ``!P. locally P {}``, 21041 REWRITE_TAC[locally] THEN MESON_TAC[open_in, SUBSET_DEF, NOT_IN_EMPTY]); 21042 21043val LOCALLY_SING = store_thm ("LOCALLY_SING", 21044 ``!P a. locally P {a} <=> P {a}``, 21045 REWRITE_TAC[locally, open_in] THEN 21046 REWRITE_TAC[SET_RULE 21047 ``(w SUBSET {a} /\ P) /\ x IN w <=> (w = {a}) /\ (x = a) /\ P``] THEN 21048 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2, IN_SING] THEN 21049 REWRITE_TAC[SET_RULE 21050 ``(u SUBSET {a} /\ P) /\ Q /\ a IN u /\ u SUBSET v /\ v SUBSET {a} <=> 21051 (u = {a}) /\ (v = {a}) /\ P /\ Q``] THEN 21052 SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM, UNWIND_THM2, IN_SING] THEN 21053 REWRITE_TAC[UNWIND_FORALL_THM2, MESON[REAL_LT_01] ``?x:real. &0 < x``]); 21054 21055val LOCALLY_INTER = store_thm ("LOCALLY_INTER", 21056 ``!P:(real->bool)->bool. 21057 (!s t. P s /\ P t ==> P(s INTER t)) 21058 ==> !s t. locally P s /\ locally P t ==> locally P (s INTER t)``, 21059 GEN_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THEN 21060 REWRITE_TAC[locally, OPEN_IN_OPEN] THEN 21061 SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM] THEN 21062 REWRITE_TAC [GSYM CONJ_ASSOC] THEN 21063 ONCE_REWRITE_TAC [METIS [] ``( ?v t. 21064 open t /\ P v /\ x IN s INTER t /\ s INTER t SUBSET v /\ 21065 v SUBSET w) = (\w x. ?v t. 21066 open t /\ P v /\ x IN s INTER t /\ s INTER t SUBSET v /\ 21067 v SUBSET w) w x``] THEN 21068 ONCE_REWRITE_TAC [METIS [] ``s INTER t = (\t. s INTER t:real->bool) t``] THEN 21069 ONCE_REWRITE_TAC [METIS [] ``x IN w <=> (\w x. x IN w) w x``] THEN 21070 ONCE_REWRITE_TAC [METIS[] 21071 ``(!w x. (?t. P t /\ (w = f t) /\ Q w x) ==> R w x) <=> 21072 (!t x. P t /\ Q (f t) x ==> R (f t) x)``] THEN 21073 SIMP_TAC std_ss [] THEN 21074 SIMP_TAC std_ss [GSYM FORALL_AND_THM, UNWIND_THM2, IN_INTER] THEN 21075 DISCH_TAC THEN X_GEN_TAC ``w:real->bool`` THEN X_GEN_TAC ``x:real`` THEN 21076 POP_ASSUM (MP_TAC o SPECL [``w:real->bool``,``x:real``]) THEN 21077 DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN 21078 ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 21079 (X_CHOOSE_THEN ``u1:real->bool`` (X_CHOOSE_THEN ``v1:real->bool`` 21080 STRIP_ASSUME_TAC)) 21081 (X_CHOOSE_THEN ``u2:real->bool`` (X_CHOOSE_THEN ``v2:real->bool`` 21082 STRIP_ASSUME_TAC))) THEN 21083 EXISTS_TAC ``u1 INTER u2:real->bool`` THEN 21084 EXISTS_TAC ``v1 INTER v2:real->bool`` THEN 21085 ASM_SIMP_TAC std_ss [OPEN_INTER] THEN ASM_SET_TAC[]); 21086 21087val lemma = prove ( 21088 ``!P Q f g. (!s t. P s /\ homeomorphism (s,t) (f,g) ==> Q t) 21089 ==> (!s:real->bool t:real->bool. 21090 locally P s /\ homeomorphism (s,t) (f,g) ==> locally Q t)``, 21091 REPEAT GEN_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THEN 21092 REWRITE_TAC[locally] THEN STRIP_TAC THEN 21093 FIRST_X_ASSUM(STRIP_ASSUME_TAC o REWRITE_RULE [homeomorphism]) THEN 21094 MAP_EVERY X_GEN_TAC [``w:real->bool``, ``y:real``] THEN STRIP_TAC THEN 21095 FIRST_X_ASSUM(MP_TAC o SPECL 21096 [``IMAGE (g:real->real) w``, ``(g:real->real) y``]) THEN 21097 KNOW_TAC ``open_in (subtopology euclidean (s :real -> bool)) 21098 (IMAGE (g :real -> real) (w :real -> bool)) /\ 21099 g (y :real) IN IMAGE g w`` THENL 21100 [CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 21101 SUBGOAL_THEN ``IMAGE (g:real->real) w = 21102 {x | x IN s /\ f(x) IN w}`` 21103 SUBST1_TAC THENL 21104 [RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM_SET_TAC[], 21105 MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]], 21106 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM]] THEN 21107 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21108 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 21109 [``IMAGE (f:real->real) u``, ``IMAGE (f:real->real) v``] THEN 21110 CONJ_TAC THENL 21111 [SUBGOAL_THEN ``IMAGE (f:real->real) u = 21112 {x | x IN t /\ g(x) IN u}`` 21113 SUBST1_TAC THENL 21114 [RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM_SET_TAC[], 21115 MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]], 21116 ALL_TAC] THEN 21117 CONJ_TAC THENL 21118 [FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC ``v:real->bool`` THEN 21119 ASM_REWRITE_TAC[homeomorphism] THEN 21120 REWRITE_TAC[homeomorphism] THEN REPEAT CONJ_TAC THEN 21121 TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 21122 CONTINUOUS_ON_SUBSET))), 21123 ALL_TAC] THEN 21124 RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM_SET_TAC[]); 21125 21126val HOMEOMORPHISM_LOCALLY = store_thm ("HOMEOMORPHISM_LOCALLY", 21127 ``!P Q f:real->real g. 21128 (!s t. homeomorphism (s,t) (f,g) ==> (P s <=> Q t)) 21129 ==> (!s t. homeomorphism (s,t) (f,g) 21130 ==> (locally P s <=> locally Q t))``, 21131 REPEAT STRIP_TAC THEN EQ_TAC THEN 21132 MATCH_MP_TAC(SIMP_RULE std_ss [RIGHT_IMP_FORALL_THM, 21133 TAUT `p ==> q /\ r ==> s <=> p /\ r ==> q ==> s`] lemma) THEN 21134 ASM_MESON_TAC[HOMEOMORPHISM_SYM]); 21135 21136val HOMEOMORPHIC_LOCALLY = store_thm ("HOMEOMORPHIC_LOCALLY", 21137 ``!P Q. (!s:real->bool t:real->bool. s homeomorphic t ==> (P s <=> Q t)) 21138 ==> (!s t. s homeomorphic t ==> (locally P s <=> locally Q t))``, 21139 REPEAT GEN_TAC THEN STRIP_TAC THEN 21140 SIMP_TAC std_ss [homeomorphic, LEFT_IMP_EXISTS_THM] THEN 21141 ONCE_REWRITE_TAC [METIS [] ``(homeomorphism (s,t) (f,g) ==> 21142 (locally P s <=> locally Q t)) = 21143 (\s t f g. homeomorphism (s,t) (f,g) ==> 21144 (locally P s <=> locally Q t)) s t f g``] THEN 21145 ONCE_REWRITE_TAC[METIS[] 21146 ``(!a b c d. P a b c d) <=> (!c d a b. P a b c d)``] THEN 21147 GEN_TAC THEN GEN_TAC THEN BETA_TAC THEN MATCH_MP_TAC HOMEOMORPHISM_LOCALLY THEN 21148 ASM_MESON_TAC[homeomorphic]); 21149 21150val LOCALLY_TRANSLATION = store_thm ("LOCALLY_TRANSLATION", 21151 ``!P:(real->bool)->bool. 21152 (!a s. P (IMAGE (\x. a + x) s) <=> P s) 21153 ==> (!a s. locally P (IMAGE (\x. a + x) s) <=> locally P s)``, 21154 GEN_TAC THEN 21155 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``a:real``) THEN 21156 MP_TAC(ISPECL 21157 [``P:(real->bool)->bool``, ``P:(real->bool)->bool``, 21158 ``\x:real. a + x``, ``\x:real. -a + x``] 21159 HOMEOMORPHISM_LOCALLY) THEN 21160 SIMP_TAC real_ss [homeomorphism] THEN 21161 SIMP_TAC real_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID] THEN 21162 SIMP_TAC real_ss [UNWIND_FORALL_THM1, CONJ_EQ_IMP, GSYM IMAGE_COMPOSE, o_DEF] THEN 21163 REWRITE_TAC [REAL_ARITH ``(-a + (a + x:real) = x) /\ (a + (-a + x) = x:real)``] THEN 21164 REWRITE_TAC [IMAGE_ID] THEN METIS_TAC[]); 21165 21166val LOCALLY_INJECTIVE_LINEAR_IMAGE = store_thm ("LOCALLY_INJECTIVE_LINEAR_IMAGE", 21167 ``!P:(real->bool)->bool Q:(real->bool)->bool. 21168 (!f s. linear f /\ (!x y. (f x = f y) ==> (x = y)) 21169 ==> (P (IMAGE f s) <=> Q s)) 21170 ==> (!f s. linear f /\ (!x y. (f x = f y) ==> (x = y)) 21171 ==> (locally P (IMAGE f s) <=> locally Q s))``, 21172 GEN_TAC THEN GEN_TAC THEN 21173 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``f:real->real``) THEN 21174 ASM_CASES_TAC ``linear(f:real->real) /\ (!x y. (f x = f y) ==> (x = y))`` THEN 21175 ASM_REWRITE_TAC[] THEN 21176 FIRST_ASSUM(MP_TAC o MATCH_MP LINEAR_INJECTIVE_LEFT_INVERSE) THEN 21177 REWRITE_TAC[FUN_EQ_THM, o_THM, I_THM] THEN 21178 DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN 21179 MP_TAC(ISPECL 21180 [``Q:(real->bool)->bool``, ``P:(real->bool)->bool``, 21181 ``f:real->real``, ``g:real->real``] 21182 HOMEOMORPHISM_LOCALLY) THEN 21183 ASM_SIMP_TAC std_ss [homeomorphism, LINEAR_CONTINUOUS_ON] THEN 21184 ASM_SIMP_TAC std_ss [UNWIND_FORALL_THM1, CONJ_EQ_IMP, FORALL_IN_IMAGE] THEN 21185 ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID] THEN MESON_TAC[]); 21186 21187val LOCALLY_OPEN_MAP_IMAGE = store_thm ("LOCALLY_OPEN_MAP_IMAGE", 21188 ``!P Q f:real->real s. 21189 f continuous_on s /\ 21190 (!t. open_in (subtopology euclidean s) t 21191 ==> open_in (subtopology euclidean (IMAGE f s)) (IMAGE f t)) /\ 21192 (!t. t SUBSET s /\ P t ==> Q(IMAGE f t)) /\ 21193 locally P s 21194 ==> locally Q (IMAGE f s)``, 21195 REPEAT GEN_TAC THEN 21196 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 21197 REWRITE_TAC[locally] THEN DISCH_TAC THEN 21198 MAP_EVERY X_GEN_TAC [``w:real->bool``, ``y:real``] THEN 21199 STRIP_TAC THEN 21200 FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o REWRITE_RULE [open_in]) THEN 21201 UNDISCH_TAC ``f continuous_on s`` THEN DISCH_TAC THEN 21202 FIRST_ASSUM(MP_TAC o SPEC ``w:real->bool`` o 21203 REWRITE_RULE [CONTINUOUS_ON_OPEN]) THEN 21204 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 21205 SUBGOAL_THEN ``?x. x IN s /\ ((f:real->real) x = y)`` STRIP_ASSUME_TAC THENL 21206 [ASM_SET_TAC[], ALL_TAC] THEN 21207 FIRST_X_ASSUM(MP_TAC o SPECL 21208 [``{x | x IN s /\ (f:real->real) x IN w}``, ``x:real``]) THEN 21209 ASM_SIMP_TAC real_ss [GSPECIFICATION, LEFT_IMP_EXISTS_THM] THEN 21210 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21211 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 21212 [``IMAGE (f:real->real) u``, ``IMAGE (f:real->real) v``] THEN 21213 ASM_SIMP_TAC real_ss [] THEN CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 21214 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SET_TAC[]); 21215 21216(* ------------------------------------------------------------------------- *) 21217(* F_sigma and G_delta sets. *) 21218(* ------------------------------------------------------------------------- *) 21219 21220val gdelta = new_definition ("gdelta", 21221 ``gdelta(s:real->bool) <=> 21222 ?g. COUNTABLE g /\ (!u. u IN g ==> open u) /\ (BIGINTER g = s)``); 21223 21224val fsigma = new_definition ("fsigma", 21225 ``fsigma(s:real->bool) <=> 21226 ?g. COUNTABLE g /\ (!c. c IN g ==> closed c) /\ (BIGUNION g = s)``); 21227 21228val GDELTA_COMPLEMENT = store_thm ("GDELTA_COMPLEMENT", 21229 ``!s. gdelta(univ(:real) DIFF s) <=> fsigma s``, 21230 GEN_TAC THEN REWRITE_TAC[gdelta, fsigma] THEN EQ_TAC THEN 21231 DISCH_THEN(X_CHOOSE_THEN ``g:(real->bool)->bool`` STRIP_ASSUME_TAC) THEN 21232 EXISTS_TAC ``IMAGE (\s. univ(:real) DIFF s) g`` THEN 21233 ASM_SIMP_TAC real_ss [COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN 21234 ASM_REWRITE_TAC[GSYM OPEN_CLOSED, GSYM closed_def] THEN 21235 ONCE_REWRITE_TAC[BIGINTER_BIGUNION, BIGUNION_BIGINTER] THEN 21236 SIMP_TAC real_ss [SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN 21237 ASM_SIMP_TAC real_ss [SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``, 21238 SET_RULE ``{x | x IN s} = s``]); 21239 21240val FSIGMA_COMPLEMENT = store_thm ("FSIGMA_COMPLEMENT", 21241 ``!s. fsigma(univ(:real) DIFF s) <=> gdelta s``, 21242 ONCE_REWRITE_TAC[GSYM GDELTA_COMPLEMENT] THEN 21243 REWRITE_TAC[SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``]); 21244 21245val CLOSED_AS_GDELTA = store_thm ("CLOSED_AS_GDELTA", 21246 ``!s:real->bool. closed s ==> gdelta s``, 21247 REPEAT STRIP_TAC THEN REWRITE_TAC[gdelta] THEN EXISTS_TAC 21248 ``{ BIGUNION { ball(x:real,inv(&n + &1)) | x IN s} | n IN univ(:num)}`` THEN 21249 SIMP_TAC real_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, NUM_COUNTABLE] THEN 21250 SIMP_TAC real_ss [FORALL_IN_IMAGE, OPEN_BIGUNION, OPEN_BALL] THEN 21251 MATCH_MP_TAC(SET_RULE 21252 ``(closure s = s) /\ s SUBSET t /\ t SUBSET closure s 21253 ==> (t = s)``) THEN 21254 ASM_REWRITE_TAC[CLOSURE_EQ] THEN CONJ_TAC THENL 21255 [SIMP_TAC real_ss [SUBSET_BIGINTER, FORALL_IN_IMAGE, IN_UNIV] THEN 21256 X_GEN_TAC ``n:num`` THEN SIMP_TAC real_ss [BIGUNION_IMAGE, SUBSET_DEF, GSPECIFICATION] THEN 21257 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN EXISTS_TAC ``x:real`` THEN 21258 ASM_REWRITE_TAC[CENTRE_IN_BALL, REAL_LT_INV_EQ] THEN 21259 SIMP_TAC arith_ss [REAL_LT], 21260 REWRITE_TAC[SUBSET_DEF, CLOSURE_APPROACHABLE, BIGINTER_IMAGE, IN_UNIV] THEN 21261 X_GEN_TAC ``x:real`` THEN SIMP_TAC real_ss [GSPECIFICATION, BIGUNION_IMAGE] THEN 21262 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 21263 FIRST_ASSUM(MP_TAC o ONCE_REWRITE_RULE [REAL_ARCH_INV]) THEN 21264 DISCH_THEN(X_CHOOSE_THEN ``n:num`` STRIP_ASSUME_TAC) THEN 21265 FIRST_X_ASSUM(MP_TAC o SPEC ``n:num``) THEN REWRITE_TAC[IN_BALL] THEN 21266 DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN 21267 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN 21268 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LT_TRANS) THEN 21269 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] 21270 REAL_LT_TRANS)) THEN 21271 MATCH_MP_TAC REAL_LT_INV2 THEN 21272 SIMP_TAC arith_ss [REAL_OF_NUM_ADD, REAL_LT] THEN ASM_ARITH_TAC]); 21273 21274(* ------------------------------------------------------------------------- *) 21275(* Local compactness. *) 21276(* ------------------------------------------------------------------------- *) 21277 21278val LOCALLY_COMPACT = store_thm ("LOCALLY_COMPACT", 21279 ``!s:real->bool. 21280 locally compact s <=> 21281 !x. x IN s ==> ?u v. x IN u /\ u SUBSET v /\ v SUBSET s /\ 21282 open_in (subtopology euclidean s) u /\ 21283 compact v``, 21284 GEN_TAC THEN REWRITE_TAC[locally] THEN EQ_TAC THEN DISCH_TAC THENL 21285 [X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN FIRST_X_ASSUM 21286 (MP_TAC o SPECL [``s INTER ball(x:real,&1)``, ``x:real``]) THEN 21287 ASM_SIMP_TAC real_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN 21288 ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, REAL_LT_01] THEN 21289 MESON_TAC[SUBSET_INTER], 21290 MAP_EVERY X_GEN_TAC [``w:real->bool``, ``x:real``] THEN 21291 REWRITE_TAC[CONJ_EQ_IMP] THEN GEN_REWR_TAC LAND_CONV [OPEN_IN_OPEN] THEN 21292 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 21293 ASM_REWRITE_TAC[IN_INTER] THEN STRIP_TAC THEN 21294 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN 21295 ASM_SIMP_TAC real_ss [LEFT_IMP_EXISTS_THM] THEN 21296 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21297 STRIP_TAC THEN 21298 UNDISCH_TAC ``open t`` THEN DISCH_TAC THEN 21299 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN 21300 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 21301 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 21302 EXISTS_TAC ``(s INTER ball(x:real,e)) INTER u`` THEN 21303 EXISTS_TAC ``cball(x:real,e) INTER v`` THEN 21304 ASM_SIMP_TAC real_ss [OPEN_IN_INTER, OPEN_IN_OPEN_INTER, OPEN_BALL, CENTRE_IN_BALL, 21305 COMPACT_INTER, COMPACT_CBALL, IN_INTER] THEN 21306 MP_TAC(ISPECL [``x:real``, ``e:real``] BALL_SUBSET_CBALL) THEN 21307 ASM_SET_TAC[]]); 21308 21309val LOCALLY_COMPACT_ALT = store_thm ("LOCALLY_COMPACT_ALT", 21310 ``!s:real->bool. 21311 locally compact s <=> 21312 !x. x IN s 21313 ==> ?u. x IN u /\ 21314 open_in (subtopology euclidean s) u /\ 21315 compact(closure u) /\ closure u SUBSET s``, 21316 GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN EQ_TAC THEN 21317 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 21318 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 21319 DISCH_THEN (X_CHOOSE_TAC ``u:real->bool``) THEN EXISTS_TAC ``u:real->bool`` THEN 21320 POP_ASSUM MP_TAC THEN 21321 METIS_TAC[CLOSURE_SUBSET, SUBSET_TRANS, CLOSURE_MINIMAL, 21322 COMPACT_CLOSURE, BOUNDED_SUBSET, COMPACT_EQ_BOUNDED_CLOSED]); 21323 21324val LOCALLY_COMPACT_INTER_CBALL = store_thm ("LOCALLY_COMPACT_INTER_CBALL", 21325 ``!s:real->bool. 21326 locally compact s <=> 21327 !x. x IN s ==> ?e. &0 < e /\ closed(cball(x,e) INTER s)``, 21328 GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT, OPEN_IN_CONTAINS_CBALL] THEN 21329 EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``x:real``) THEN 21330 ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_SIMP_TAC real_ss [LEFT_IMP_EXISTS_THM] THENL 21331 [ MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21332 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN 21333 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN 21334 ASM_REWRITE_TAC[] THEN 21335 SUBGOAL_THEN ``cball(x:real,e) INTER s = cball (x,e) INTER v`` 21336 SUBST1_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 21337 ASM_SIMP_TAC real_ss [COMPACT_CBALL, COMPACT_INTER, COMPACT_IMP_CLOSED], 21338 21339 X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN 21340 EXISTS_TAC ``ball(x:real,e) INTER s`` THEN 21341 EXISTS_TAC ``cball(x:real,e) INTER s`` THEN 21342 REWRITE_TAC[GSYM OPEN_IN_CONTAINS_CBALL] THEN 21343 ASM_SIMP_TAC real_ss [IN_INTER, CENTRE_IN_BALL, INTER_SUBSET] THEN 21344 ASM_SIMP_TAC real_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTER, BOUNDED_CBALL] THEN 21345 ONCE_REWRITE_TAC[INTER_COMM] THEN 21346 SIMP_TAC real_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN 21347 REWRITE_TAC [SUBSET_DEF, IN_INTER] THEN GEN_TAC THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 21348 METIS_TAC[SUBSET_DEF, BALL_SUBSET_CBALL]]); 21349 21350val LOCALLY_COMPACT_INTER_CBALLS = store_thm ("LOCALLY_COMPACT_INTER_CBALLS", 21351 ``!s:real->bool. 21352 locally compact s <=> 21353 !x. x IN s ==> ?e. &0 < e /\ !d. d <= e ==> closed(cball(x,d) INTER s)``, 21354 GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_INTER_CBALL] THEN 21355 EQ_TAC THENL [ALL_TAC, METIS_TAC[REAL_LE_REFL]] THEN 21356 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN POP_ASSUM (MP_TAC o SPEC ``x:real``) THEN 21357 ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_REWRITE_TAC[] THEN 21358 STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN 21359 GEN_TAC THEN DISCH_TAC THEN 21360 SUBGOAL_THEN 21361 ``cball(x:real,d) INTER s = cball(x,d) INTER cball(x,e) INTER s`` 21362 SUBST1_TAC THENL 21363 [ REWRITE_TAC[INTER_ASSOC, GSYM CBALL_MIN_INTER] THEN 21364 AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN 21365 BINOP_TAC THEN REWRITE_TAC[min_def] THEN PROVE_TAC [], 21366 ASM_SIMP_TAC real_ss [GSYM INTER_ASSOC, CLOSED_INTER, CLOSED_CBALL] ]); 21367 21368val LOCALLY_COMPACT_COMPACT = store_thm ("LOCALLY_COMPACT_COMPACT", 21369 ``!s:real->bool. 21370 locally compact s <=> 21371 !k. k SUBSET s /\ compact k 21372 ==> ?u v. k SUBSET u /\ 21373 u SUBSET v /\ 21374 v SUBSET s /\ 21375 open_in (subtopology euclidean s) u /\ 21376 compact v``, 21377 GEN_TAC THEN GEN_REWR_TAC LAND_CONV [LOCALLY_COMPACT] THEN EQ_TAC THEN 21378 REPEAT STRIP_TAC THENL 21379 [ALL_TAC, METIS_TAC[SING_SUBSET, COMPACT_SING]] THEN 21380 UNDISCH_TAC ``!x. x IN s ==> 21381 ?u v. x IN u /\ u SUBSET v /\ v SUBSET s /\ 21382 open_in (subtopology euclidean s) u /\ compact v`` THEN DISCH_TAC THEN 21383 FIRST_X_ASSUM(MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 21384 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 21385 MAP_EVERY X_GEN_TAC [``u:real->real->bool``, ``v:real->real->bool``] THEN 21386 DISCH_TAC THEN UNDISCH_TAC ``compact k`` THEN DISCH_TAC THEN 21387 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE 21388 [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN 21389 DISCH_THEN(MP_TAC o SPEC ``IMAGE (\x:real. k INTER u x) k``) THEN 21390 ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE, BIGUNION_IMAGE] THEN 21391 KNOW_TAC ``(!(x :real). 21392 x IN (k :real -> bool) ==> 21393 open_in (subtopology euclidean k) 21394 (k INTER (u :real -> real -> bool) x)) /\ 21395 k SUBSET {y | ?(x :real). x IN k /\ y IN k INTER u x}`` THENL 21396 [CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 21397 REPEAT STRIP_TAC THEN MATCH_MP_TAC OPEN_IN_SUBTOPOLOGY_INTER_SUBSET THEN 21398 EXISTS_TAC ``s:real->bool`` THEN ASM_REWRITE_TAC[] THEN 21399 MATCH_MP_TAC OPEN_IN_INTER THEN REWRITE_TAC[OPEN_IN_REFL] THEN 21400 ASM_SET_TAC[], 21401 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 21402 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN 21403 SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE, BIGUNION_IMAGE] THEN 21404 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 21405 EXISTS_TAC ``BIGUNION(IMAGE (u:real->real->bool) t)`` THEN 21406 EXISTS_TAC ``BIGUNION(IMAGE (v:real->real->bool) t)`` THEN 21407 REPEAT CONJ_TAC THENL 21408 [ALL_TAC, ALL_TAC, ALL_TAC, MATCH_MP_TAC OPEN_IN_BIGUNION, 21409 MATCH_MP_TAC COMPACT_BIGUNION THEN ASM_SIMP_TAC std_ss [IMAGE_FINITE]] THEN 21410 ASM_SET_TAC[]]); 21411 21412val LOCALLY_COMPACT_COMPACT_ALT = store_thm ("LOCALLY_COMPACT_COMPACT_ALT", 21413 ``!s:real->bool. 21414 locally compact s <=> 21415 !k. k SUBSET s /\ compact k 21416 ==> ?u. k SUBSET u /\ 21417 open_in (subtopology euclidean s) u /\ 21418 compact(closure u) /\ closure u SUBSET s``, 21419 GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_COMPACT] THEN EQ_TAC THEN 21420 DISCH_TAC THEN X_GEN_TAC ``k:real->bool`` THEN DISCH_TAC THEN 21421 FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN ASM_REWRITE_TAC[] THEN 21422 DISCH_THEN (X_CHOOSE_TAC ``u:real->bool``) THEN EXISTS_TAC ``u:real->bool`` THEN 21423 POP_ASSUM MP_TAC THEN 21424 METIS_TAC[CLOSURE_SUBSET, SUBSET_TRANS, CLOSURE_MINIMAL, 21425 COMPACT_CLOSURE, BOUNDED_SUBSET, COMPACT_EQ_BOUNDED_CLOSED]); 21426 21427val LOCALLY_COMPACT_COMPACT_SUBOPEN = store_thm ("LOCALLY_COMPACT_COMPACT_SUBOPEN", 21428 ``!s:real->bool. 21429 locally compact s <=> 21430 !k t. k SUBSET s /\ compact k /\ open t /\ k SUBSET t 21431 ==> ?u v. k SUBSET u /\ u SUBSET v /\ u SUBSET t /\ v SUBSET s /\ 21432 open_in (subtopology euclidean s) u /\ 21433 compact v``, 21434 GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_COMPACT] THEN 21435 EQ_TAC THEN DISCH_TAC THEN REPEAT STRIP_TAC THENL 21436 [FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN 21437 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 21438 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21439 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 21440 [``u INTER t:real->bool``, ``closure(u INTER t:real->bool)``] THEN 21441 REWRITE_TAC[CLOSURE_SUBSET, INTER_SUBSET] THEN REPEAT CONJ_TAC THENL 21442 [ASM_SET_TAC[], 21443 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC ``closure(u:real->bool)`` THEN 21444 SIMP_TAC std_ss [SUBSET_CLOSURE, INTER_SUBSET] THEN 21445 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC ``v:real->bool`` THEN ASM_REWRITE_TAC[] THEN 21446 MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED], 21447 ASM_SIMP_TAC std_ss [OPEN_IN_INTER_OPEN], 21448 REWRITE_TAC[COMPACT_CLOSURE] THEN 21449 ASM_MESON_TAC[BOUNDED_SUBSET, INTER_SUBSET, SUBSET_TRANS, 21450 COMPACT_IMP_BOUNDED]], 21451 FIRST_X_ASSUM(MP_TAC o SPECL [``k:real->bool``, ``univ(:real)``]) THEN 21452 ASM_REWRITE_TAC[OPEN_UNIV, SUBSET_UNIV]]); 21453 21454val OPEN_IMP_LOCALLY_COMPACT = store_thm ("OPEN_IMP_LOCALLY_COMPACT", 21455 ``!s:real->bool. open s ==> locally compact s``, 21456 REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN 21457 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 21458 UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN FIRST_ASSUM 21459 (MP_TAC o REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN 21460 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 21461 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 21462 MAP_EVERY EXISTS_TAC [``ball(x:real,e)``, ``cball(x:real,e)``] THEN 21463 ASM_REWRITE_TAC[BALL_SUBSET_CBALL, CENTRE_IN_BALL, COMPACT_CBALL] THEN 21464 MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN ASM_REWRITE_TAC[OPEN_BALL] THEN 21465 MATCH_MP_TAC SUBSET_TRANS THEN METIS_TAC [BALL_SUBSET_CBALL]); 21466 21467val CLOSED_IMP_LOCALLY_COMPACT = store_thm ("CLOSED_IMP_LOCALLY_COMPACT", 21468 ``!s:real->bool. closed s ==> locally compact s``, 21469 REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN 21470 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN MAP_EVERY EXISTS_TAC 21471 [``s INTER ball(x:real,&1)``, ``s INTER cball(x:real,&1)``] THEN 21472 ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, INTER_SUBSET, REAL_LT_01] THEN 21473 ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN 21474 ASM_SIMP_TAC std_ss [CLOSED_INTER_COMPACT, COMPACT_CBALL] THEN 21475 MP_TAC(ISPECL [``x:real``, ``&1:real``] BALL_SUBSET_CBALL) THEN ASM_SET_TAC[]); 21476 21477val IS_INTERVAL_IMP_LOCALLY_COMPACT = store_thm ("IS_INTERVAL_IMP_LOCALLY_COMPACT", 21478 ``!s:real->bool. is_interval s ==> locally compact s``, 21479 REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN 21480 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 21481 MP_TAC(ISPECL [``s:real->bool``, ``x:real``] 21482 INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD) THEN 21483 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 21484 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``, ``d:real``] THEN STRIP_TAC THEN 21485 MAP_EVERY EXISTS_TAC 21486 [``s INTER ball(x:real,d)``, ``interval[a:real,b]``] THEN 21487 ASM_SIMP_TAC std_ss [COMPACT_INTERVAL, OPEN_IN_OPEN_INTER, OPEN_BALL] THEN 21488 ASM_REWRITE_TAC[CENTRE_IN_BALL, IN_INTER] THEN ASM_SET_TAC[]); 21489 21490val LOCALLY_COMPACT_UNIV = store_thm ("LOCALLY_COMPACT_UNIV", 21491 ``locally compact univ(:real)``, 21492 SIMP_TAC std_ss [OPEN_IMP_LOCALLY_COMPACT, OPEN_UNIV]); 21493 21494val LOCALLY_COMPACT_INTER = store_thm ("LOCALLY_COMPACT_INTER", 21495 ``!s t:real->bool. 21496 locally compact s /\ locally compact t 21497 ==> locally compact (s INTER t)``, 21498 MATCH_MP_TAC LOCALLY_INTER THEN REWRITE_TAC[COMPACT_INTER]); 21499 21500val LOCALLY_COMPACT_OPEN_IN = store_thm ("LOCALLY_COMPACT_OPEN_IN", 21501 ``!s t:real->bool. 21502 open_in (subtopology euclidean s) t /\ locally compact s 21503 ==> locally compact t``, 21504 REWRITE_TAC[OPEN_IN_OPEN] THEN REPEAT STRIP_TAC THEN 21505 ASM_SIMP_TAC std_ss [LOCALLY_COMPACT_INTER, OPEN_IMP_LOCALLY_COMPACT]); 21506 21507val LOCALLY_COMPACT_CLOSED_IN = store_thm ("LOCALLY_COMPACT_CLOSED_IN", 21508 ``!s t:real->bool. 21509 closed_in (subtopology euclidean s) t /\ locally compact s 21510 ==> locally compact t``, 21511 REWRITE_TAC[CLOSED_IN_CLOSED] THEN REPEAT STRIP_TAC THEN 21512 ASM_SIMP_TAC std_ss [LOCALLY_COMPACT_INTER, CLOSED_IMP_LOCALLY_COMPACT]); 21513 21514val LOCALLY_COMPACT_DELETE = store_thm ("LOCALLY_COMPACT_DELETE", 21515 ``!s a:real. locally compact s ==> locally compact (s DELETE a)``, 21516 REPEAT STRIP_TAC THEN MATCH_MP_TAC LOCALLY_COMPACT_OPEN_IN THEN 21517 EXISTS_TAC ``s:real->bool`` THEN 21518 ASM_SIMP_TAC std_ss [OPEN_IN_DELETE, OPEN_IN_REFL]); 21519 21520val HOMEOMORPHIC_LOCAL_COMPACTNESS = store_thm ("HOMEOMORPHIC_LOCAL_COMPACTNESS", 21521 ``!s t:real->bool. 21522 s homeomorphic t ==> (locally compact s <=> locally compact t)``, 21523 MATCH_MP_TAC HOMEOMORPHIC_LOCALLY THEN 21524 REWRITE_TAC[HOMEOMORPHIC_COMPACTNESS]); 21525 21526val LOCALLY_COMPACT_TRANSLATION_EQ = store_thm ("LOCALLY_COMPACT_TRANSLATION_EQ", 21527 ``!a:real s. locally compact (IMAGE (\x. a + x) s) <=> 21528 locally compact s``, 21529 MATCH_MP_TAC LOCALLY_TRANSLATION THEN 21530 REWRITE_TAC[COMPACT_TRANSLATION_EQ]); 21531 21532val LOCALLY_CLOSED = store_thm ("LOCALLY_CLOSED", 21533 ``!s:real->bool. locally closed s <=> locally compact s``, 21534 GEN_TAC THEN EQ_TAC THENL 21535 [ALL_TAC, MESON_TAC[LOCALLY_MONO, COMPACT_IMP_CLOSED]] THEN 21536 REWRITE_TAC[locally] THEN DISCH_TAC THEN 21537 MAP_EVERY X_GEN_TAC [``w:real->bool``, ``x:real``] THEN STRIP_TAC THEN 21538 FIRST_X_ASSUM(MP_TAC o SPECL [``w:real->bool``, ``x:real``]) THEN 21539 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 21540 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21541 STRIP_TAC THEN 21542 EXISTS_TAC ``u INTER ball(x:real,&1)`` THEN 21543 EXISTS_TAC ``v INTER cball(x:real,&1)`` THEN 21544 ASM_SIMP_TAC std_ss [OPEN_IN_INTER_OPEN, OPEN_BALL] THEN 21545 ASM_SIMP_TAC std_ss [CLOSED_INTER_COMPACT, COMPACT_CBALL] THEN 21546 ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, REAL_LT_01] THEN 21547 MP_TAC(ISPEC ``x:real`` BALL_SUBSET_CBALL) THEN ASM_SET_TAC[]); 21548 21549val LOCALLY_COMPACT_OPEN_UNION = store_thm ("LOCALLY_COMPACT_OPEN_UNION", 21550 ``!s t:real->bool. 21551 locally compact s /\ locally compact t /\ 21552 open_in (subtopology euclidean (s UNION t)) s /\ 21553 open_in (subtopology euclidean (s UNION t)) t 21554 ==> locally compact (s UNION t)``, 21555 REPEAT GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_INTER_CBALL, IN_UNION] THEN 21556 STRIP_TAC THEN X_GEN_TAC ``x:real`` THEN STRIP_TAC THENL 21557 [UNDISCH_TAC ``!x. x IN s ==> ?e. 0 < e /\ closed (cball (x,e) INTER s)`` THEN 21558 DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``x:real``) THEN 21559 UNDISCH_TAC ``open_in (subtopology euclidean (s UNION t)) s`` THEN DISCH_TAC THEN 21560 FIRST_ASSUM (MP_TAC o REWRITE_RULE [OPEN_IN_CONTAINS_CBALL]), 21561 UNDISCH_TAC ``!x. x IN t ==> ?e. 0 < e /\ closed (cball (x,e) INTER t)`` THEN 21562 DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``x:real``) THEN 21563 UNDISCH_TAC ``open_in (subtopology euclidean (s UNION t)) t`` THEN DISCH_TAC THEN 21564 FIRST_ASSUM (MP_TAC o REWRITE_RULE [OPEN_IN_CONTAINS_CBALL])] THEN 21565 DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN 21566 UNDISCH_TAC ``!x. x IN s ==> ?e. 0 < e /\ closed (cball (x,e) INTER s)`` THEN 21567 DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN 21568 UNDISCH_TAC `` !x. x IN t ==> ?e. 0 < e /\ closed (cball (x,e) INTER t)`` THEN 21569 DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC [] THENL 21570 [DISCH_TAC THEN DISCH_THEN (X_CHOOSE_TAC ``e:real``), 21571 DISCH_THEN (X_CHOOSE_TAC ``e:real``) THEN DISCH_TAC] THEN 21572 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 21573 EXISTS_TAC ``min d e:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 21574 REWRITE_TAC[CBALL_MIN_INTER, INTER_ASSOC] THEN 21575 FIRST_ASSUM(MP_TAC o MATCH_MP (SET_RULE 21576 ``u INTER st SUBSET s ==> s SUBSET st ==> (u INTER st = u INTER s)``)) THEN 21577 REWRITE_TAC[SUBSET_UNION] THEN 21578 ONCE_REWRITE_TAC [SET_RULE ``a INTER b INTER c = b INTER (a INTER c)``] THEN 21579 DISCH_THEN SUBST1_TAC THEN 21580 ONCE_REWRITE_TAC [SET_RULE ``a INTER (b INTER c) = b INTER (a INTER c)``] THEN 21581 METIS_TAC[CLOSED_INTER, CLOSED_CBALL, INTER_ACI]); 21582 21583val LOCALLY_COMPACT_CLOSED_UNION = store_thm ("LOCALLY_COMPACT_CLOSED_UNION", 21584 ``!s t:real->bool. 21585 locally compact s /\ locally compact t /\ 21586 closed_in (subtopology euclidean (s UNION t)) s /\ 21587 closed_in (subtopology euclidean (s UNION t)) t 21588 ==> locally compact (s UNION t)``, 21589 REPEAT GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_INTER_CBALL, IN_UNION] THEN 21590 STRIP_TAC THEN X_GEN_TAC ``x:real`` THEN 21591 DISCH_THEN(STRIP_ASSUME_TAC o MATCH_MP (TAUT 21592 `p \/ q ==> p /\ q \/ p /\ ~q \/ q /\ ~p`)) 21593 THENL 21594 [FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN 21595 FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN 21596 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 21597 X_GEN_TAC ``d:real`` THEN STRIP_TAC THEN 21598 X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN 21599 EXISTS_TAC ``min d e:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 21600 SIMP_TAC std_ss [SET_RULE ``u INTER (s UNION t) = u INTER s UNION u INTER t``] THEN 21601 MATCH_MP_TAC CLOSED_UNION THEN REWRITE_TAC[CBALL_MIN_INTER] THEN CONJ_TAC THENL 21602 [ONCE_REWRITE_TAC [SET_RULE ``a INTER b INTER c = b INTER (a INTER c)``], 21603 REWRITE_TAC [GSYM INTER_ASSOC]] THEN 21604 METIS_TAC[CLOSED_CBALL, CLOSED_INTER, INTER_ACI], 21605 UNDISCH_TAC ``!x. x IN s ==> ?e. 0 < e /\ closed (cball (x,e) INTER s)`` THEN 21606 DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 21607 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 21608 UNDISCH_TAC ``closed_in (subtopology euclidean (s UNION t)) t`` THEN DISCH_TAC THEN 21609 FIRST_X_ASSUM (STRIP_ASSUME_TAC o REWRITE_RULE [closed_in]), 21610 FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 21611 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 21612 UNDISCH_TAC ``closed_in (subtopology euclidean (s UNION t)) s`` THEN DISCH_TAC THEN 21613 FIRST_X_ASSUM (STRIP_ASSUME_TAC o REWRITE_RULE [closed_in])] THEN 21614 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_CONTAINS_CBALL]) THEN 21615 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, IN_DIFF, IN_UNION] THEN 21616 DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN ASM_SIMP_TAC std_ss [] THEN 21617 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 21618 EXISTS_TAC ``min d e:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THENL 21619 [SUBGOAL_THEN ``cball (x:real,min d e) INTER (s UNION t) = 21620 cball(x,d) INTER cball (x,e) INTER s`` SUBST1_TAC 21621 THENL [REWRITE_TAC[CBALL_MIN_INTER] THEN ASM_SET_TAC[], ALL_TAC], 21622 SUBGOAL_THEN ``cball (x:real,min d e) INTER (s UNION t) = 21623 cball(x,d) INTER cball (x,e) INTER t`` SUBST1_TAC 21624 THENL [REWRITE_TAC[CBALL_MIN_INTER] THEN ASM_SET_TAC[], ALL_TAC]] THEN 21625 ASM_MESON_TAC[GSYM INTER_ASSOC, CLOSED_INTER, CLOSED_CBALL]); 21626 21627val OPEN_IN_LOCALLY_COMPACT = store_thm ("OPEN_IN_LOCALLY_COMPACT", 21628 ``!s t:real->bool. 21629 locally compact s 21630 ==> (open_in (subtopology euclidean s) t <=> 21631 t SUBSET s /\ 21632 !k. compact k /\ k SUBSET s 21633 ==> open_in (subtopology euclidean k) (k INTER t))``, 21634 REPEAT(STRIP_TAC ORELSE EQ_TAC) THENL 21635 [ASM_MESON_TAC[OPEN_IN_IMP_SUBSET], 21636 UNDISCH_TAC ``open_in (subtopology euclidean s) t`` THEN DISCH_TAC THEN 21637 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN]) THEN 21638 REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN (X_CHOOSE_TAC ``t':real->bool``) THEN 21639 EXISTS_TAC ``t':real->bool`` THEN ASM_SET_TAC[], 21640 ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN 21641 X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN 21642 UNDISCH_TAC ``locally compact s`` THEN DISCH_TAC THEN 21643 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LOCALLY_COMPACT]) THEN 21644 DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN 21645 KNOW_TAC ``a IN s:real->bool`` THENL 21646 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 21647 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM]] THEN 21648 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21649 STRIP_TAC THEN EXISTS_TAC ``t INTER u:real->bool`` THEN 21650 ASM_REWRITE_TAC[IN_INTER, INTER_SUBSET] THEN 21651 MATCH_MP_TAC OPEN_IN_TRANS THEN EXISTS_TAC ``u:real->bool`` THEN 21652 ASM_REWRITE_TAC[] THEN 21653 FIRST_X_ASSUM(MP_TAC o SPEC ``closure u:real->bool``) THEN 21654 KNOW_TAC ``compact (closure u) /\ closure u SUBSET s`` THENL 21655 [SUBGOAL_THEN ``(closure u:real->bool) SUBSET v`` MP_TAC THENL 21656 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED], 21657 REWRITE_TAC[COMPACT_CLOSURE] THEN 21658 ASM_MESON_TAC[SUBSET_TRANS, BOUNDED_SUBSET, COMPACT_IMP_BOUNDED]], 21659 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 21660 REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN (X_CHOOSE_TAC ``t':real->bool``) THEN 21661 EXISTS_TAC ``t':real->bool`` THEN ASM_REWRITE_TAC [] THEN 21662 MP_TAC(ISPEC ``u:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[]]]); 21663 21664val LOCALLY_COMPACT_PROPER_IMAGE_EQ = store_thm ("LOCALLY_COMPACT_PROPER_IMAGE_EQ", 21665 ``!f:real->real s. 21666 f continuous_on s /\ 21667 (!k. k SUBSET (IMAGE f s) /\ compact k 21668 ==> compact {x | x IN s /\ f x IN k}) 21669 ==> (locally compact s <=> locally compact (IMAGE f s))``, 21670 REPEAT STRIP_TAC THEN 21671 MP_TAC(ISPECL [``f:real->real``, ``s:real->bool``, 21672 ``IMAGE (f:real->real) s``] PROPER_MAP) THEN 21673 ASM_REWRITE_TAC[SUBSET_REFL] THEN STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 21674 [REWRITE_TAC[LOCALLY_COMPACT_ALT] THEN X_GEN_TAC ``y:real`` THEN 21675 DISCH_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``y:real``) THEN 21676 ASM_REWRITE_TAC[] THEN UNDISCH_TAC ``locally compact s`` THEN DISCH_TAC THEN 21677 FIRST_ASSUM(MP_TAC o REWRITE_RULE [LOCALLY_COMPACT_COMPACT_ALT]) THEN 21678 DISCH_THEN(MP_TAC o SPEC ``{x | x IN s /\ ((f:real->real) x = y)}``) THEN 21679 ONCE_REWRITE_TAC [METIS [] ``(f x = y) = (\x. (f x = y)) x``] THEN 21680 ASM_SIMP_TAC std_ss [SUBSET_RESTRICT] THEN 21681 DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 21682 SUBGOAL_THEN 21683 ``?v. open_in (subtopology euclidean (IMAGE f s)) v /\ 21684 y IN v /\ 21685 {x | x IN s /\ (f:real->real) x IN v} SUBSET u`` 21686 MP_TAC THENL 21687 [GEN_REWR_TAC (BINDER_CONV o RAND_CONV o LAND_CONV) 21688 [GSYM SING_SUBSET] THEN 21689 MATCH_MP_TAC CLOSED_MAP_OPEN_SUPERSET_PREIMAGE THEN 21690 ASM_REWRITE_TAC[SING_SUBSET, IN_SING], 21691 DISCH_THEN (X_CHOOSE_TAC ``v:real->bool``) THEN EXISTS_TAC ``v:real->bool`` THEN 21692 POP_ASSUM MP_TAC THEN 21693 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 21694 SUBGOAL_THEN ``closure v SUBSET IMAGE (f:real->real) (closure u)`` 21695 ASSUME_TAC THENL 21696 [MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC ``closure(IMAGE (f:real->real) u)`` THEN 21697 CONJ_TAC THENL 21698 [MATCH_MP_TAC SUBSET_CLOSURE THEN 21699 REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET)) THEN 21700 ASM_SET_TAC[], 21701 MATCH_MP_TAC CLOSURE_MINIMAL THEN 21702 SIMP_TAC std_ss [CLOSURE_SUBSET, IMAGE_SUBSET] THEN 21703 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 21704 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 21705 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]], 21706 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 21707 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE] THEN 21708 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] 21709 BOUNDED_SUBSET)) THEN 21710 MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN 21711 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 21712 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]], 21713 REWRITE_TAC[LOCALLY_COMPACT_ALT] THEN 21714 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 21715 UNDISCH_TAC ``locally compact (IMAGE (f :real -> real) (s :real -> bool))`` THEN 21716 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LOCALLY_COMPACT_ALT]) THEN 21717 DISCH_THEN(MP_TAC o SPEC ``(f:real->real) x``) THEN 21718 ASM_SIMP_TAC std_ss [FUN_IN_IMAGE] THEN 21719 DISCH_THEN(X_CHOOSE_THEN ``v:real->bool`` STRIP_ASSUME_TAC) THEN 21720 FIRST_X_ASSUM(MP_TAC o SPEC ``closure v:real->bool``) THEN 21721 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN 21722 EXISTS_TAC ``{x | x IN s /\ (f:real->real) x IN v}`` THEN 21723 ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN CONJ_TAC THENL 21724 [MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN 21725 ASM_MESON_TAC[SUBSET_REFL], 21726 ALL_TAC] THEN 21727 SUBGOAL_THEN 21728 ``closure {x | x IN s /\ f x IN v} SUBSET 21729 {x | x IN s /\ (f:real->real) x IN closure v}`` 21730 ASSUME_TAC THENL 21731 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED] THEN 21732 MP_TAC(ISPEC ``v:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[], 21733 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 21734 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE] THEN 21735 METIS_TAC[COMPACT_IMP_BOUNDED, BOUNDED_SUBSET]]]); 21736 21737val LOCALLY_COMPACT_PROPER_IMAGE = store_thm ("LOCALLY_COMPACT_PROPER_IMAGE", 21738 ``!f:real->real s. 21739 f continuous_on s /\ 21740 (!k. k SUBSET (IMAGE f s) /\ compact k 21741 ==> compact {x | x IN s /\ f x IN k}) /\ 21742 locally compact s 21743 ==> locally compact (IMAGE f s)``, 21744 METIS_TAC[LOCALLY_COMPACT_PROPER_IMAGE_EQ]); 21745 21746val MUMFORD_LEMMA = store_thm ("MUMFORD_LEMMA", 21747 ``!f:real->real s t y. 21748 f continuous_on s /\ IMAGE f s SUBSET t /\ locally compact s /\ 21749 y IN t /\ compact {x | x IN s /\ (f x = y)} 21750 ==> ?u v. open_in (subtopology euclidean s) u /\ 21751 open_in (subtopology euclidean t) v /\ 21752 {x | x IN s /\ (f x = y)} SUBSET u /\ y IN v /\ 21753 IMAGE f u SUBSET v /\ 21754 (!k. k SUBSET v /\ compact k 21755 ==> compact {x | x IN u /\ f x IN k})``, 21756 REPEAT STRIP_TAC THEN 21757 FIRST_ASSUM(MP_TAC o SPEC ``{x | x IN s /\ ((f:real->real) x = y)}`` o 21758 REWRITE_RULE [LOCALLY_COMPACT_COMPACT]) THEN 21759 ASM_SIMP_TAC std_ss [SUBSET_RESTRICT, LEFT_IMP_EXISTS_THM] THEN 21760 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21761 STRIP_TAC THEN 21762 SUBGOAL_THEN ``(closure u:real->bool) SUBSET v`` ASSUME_TAC THENL 21763 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED], 21764 ALL_TAC] THEN 21765 SUBGOAL_THEN ``compact(closure u:real->bool)`` ASSUME_TAC THENL 21766 [ASM_REWRITE_TAC[COMPACT_CLOSURE] THEN 21767 ASM_MESON_TAC[BOUNDED_SUBSET, COMPACT_IMP_BOUNDED], 21768 ALL_TAC] THEN 21769 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN 21770 SUBGOAL_THEN 21771 ``!b. open_in (subtopology euclidean t) b /\ y IN b 21772 ==> u INTER {x | x IN s /\ (f:real->real) x IN b} PSUBSET 21773 closure u INTER {x | x IN s /\ (f:real->real) x IN b}`` 21774 MP_TAC THENL 21775 [REPEAT STRIP_TAC THEN REWRITE_TAC[PSUBSET_DEF] THEN 21776 SIMP_TAC std_ss [CLOSURE_SUBSET, 21777 SET_RULE ``s SUBSET t ==> s INTER u SUBSET t INTER u``] THEN 21778 MATCH_MP_TAC(MESON[] ``!P. ~P s /\ P t ==> ~(s = t)``) THEN 21779 EXISTS_TAC 21780 ``\a. !k. k SUBSET b /\ compact k 21781 ==> compact {x | x IN a /\ (f:real->real) x IN k}`` THEN 21782 SIMP_TAC std_ss [] THEN CONJ_TAC THENL 21783 [KNOW_TAC ``(open_in (subtopology euclidean s) (u INTER {x | x IN s /\ f x IN b}) 21784 ==> {x | x IN s /\ (f x = y)} SUBSET u INTER {x | x IN s /\ f x IN b} 21785 ==> IMAGE f (u INTER {x | x IN s /\ f x IN b}) SUBSET b 21786 ==> ~(!k. k SUBSET b /\ compact k 21787 ==> compact 21788 {x | x IN u INTER {x | x IN s /\ f x IN b} /\ f x IN k})) 21789 ==> ~(!k. k SUBSET b /\ compact k 21790 ==> compact 21791 {x | x IN u INTER {x | x IN s /\ f x IN b} /\ f x IN k})`` THENL 21792 [ALL_TAC, METIS_TAC []] THEN 21793 KNOW_TAC ``open_in (subtopology euclidean s) 21794 (u INTER {x | x IN s /\ (f:real->real) x IN b})`` THENL 21795 [MATCH_MP_TAC OPEN_IN_INTER THEN ASM_SIMP_TAC std_ss [] THEN 21796 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN ASM_SET_TAC[], 21797 ASM_SET_TAC[]], 21798 X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN 21799 SUBGOAL_THEN 21800 ``{x | x IN closure u INTER {x | x IN s /\ f x IN b} /\ f x IN k} = 21801 v INTER {x | x IN closure u /\ (f:real->real) x IN k}`` 21802 SUBST1_TAC THENL [ASM_SET_TAC[], MATCH_MP_TAC COMPACT_INTER_CLOSED] THEN 21803 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN 21804 ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED, CLOSED_CLOSURE] THEN 21805 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, SUBSET_TRANS]], 21806 DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC 21807 ``t INTER ball(y:real,inv(&n + &1))``) THEN 21808 SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL, IN_INTER, CENTRE_IN_BALL] THEN 21809 ASM_REWRITE_TAC[REAL_LT_INV_EQ, 21810 METIS [REAL_LT, REAL_OF_NUM_ADD, GSYM ADD1, LESS_0] ``&0 < &n + &1:real``] THEN 21811 KNOW_TAC ``~(!n. ?x. x IN closure u /\ 21812 ~(x IN u) /\ 21813 x IN {x | x IN s /\ f x IN t /\ f x IN ball (y,inv (&n + &1))})`` THENL 21814 [ALL_TAC, 21815 METIS_TAC [CLOSURE_SUBSET, REAL_OF_NUM_ADD, SET_RULE 21816 ``u SUBSET u' 21817 ==> (u INTER t PSUBSET u' INTER t <=> 21818 ?x. x IN u' /\ ~(x IN u) /\ x IN t)``]] THEN 21819 KNOW_TAC ``~(?x. (!n. x n IN closure u) /\ 21820 (!n. ~(x n IN u)) /\ 21821 (!n. x n IN s) /\ 21822 (!n. f (x n) IN t) /\ 21823 (!n. dist (y,f (x n)) < inv (&n + &1)))`` THENL 21824 [ALL_TAC, 21825 SIMP_TAC std_ss [SKOLEM_THM, GSPECIFICATION, IN_BALL, FORALL_AND_THM] THEN 21826 METIS_TAC [SKOLEM_THM]] THEN 21827 DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN 21828 MP_TAC(ISPEC ``closure u:real->bool`` compact) THEN 21829 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``x:num->real``) THEN 21830 ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN 21831 MAP_EVERY X_GEN_TAC [``l:real``, ``r:num->num``] THEN 21832 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 21833 SUBGOAL_THEN ``(f:real->real) l = y`` ASSUME_TAC THENL 21834 [MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN 21835 EXISTS_TAC ``(f:real->real) o x o (r:num->num)`` THEN 21836 ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN CONJ_TAC THENL 21837 [SUBGOAL_THEN ``(f:real->real) continuous_on closure u`` MP_TAC THENL 21838 [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, SUBSET_TRANS], ALL_TAC] THEN 21839 REWRITE_TAC[CONTINUOUS_ON_SEQUENTIALLY] THEN 21840 DISCH_THEN MATCH_MP_TAC THEN ASM_SIMP_TAC std_ss [o_THM], 21841 REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC LIM_SUBSEQUENCE THEN 21842 ASM_SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN 21843 CONJ_TAC THENL [METIS_TAC [], ALL_TAC] THEN 21844 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 21845 MP_TAC(SPEC ``e:real`` REAL_ARCH_INV) THEN 21846 ASM_REWRITE_TAC[] THEN DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN 21847 EXISTS_TAC ``N:num`` THEN X_GEN_TAC ``n:num`` THEN 21848 DISCH_TAC THEN ONCE_REWRITE_TAC[DIST_SYM] THEN 21849 MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC ``inv(&n + &1:real)`` THEN 21850 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_TRANS THEN 21851 EXISTS_TAC ``inv(&N:real)`` THEN ASM_REWRITE_TAC[] THEN 21852 MATCH_MP_TAC REAL_LT_INV2 THEN 21853 ASM_SIMP_TAC arith_ss [REAL_OF_NUM_ADD, REAL_LT]], 21854 UNDISCH_TAC ``open_in (subtopology euclidean s) u`` THEN DISCH_TAC THEN 21855 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [open_in]) THEN 21856 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC ``l:real``)) THEN 21857 SIMP_TAC std_ss [NOT_IMP, NOT_EXISTS_THM] THEN 21858 CONJ_TAC THENL [ASM_SET_TAC[], X_GEN_TAC ``e:real`` THEN 21859 CCONTR_TAC THEN FULL_SIMP_TAC std_ss []] THEN 21860 UNDISCH_TAC ``(((x :num -> real) o (r :num -> num) --> (l :real)) 21861 sequentially :bool)`` THEN DISCH_TAC THEN 21862 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LIM_SEQUENTIALLY]) THEN 21863 DISCH_THEN(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN 21864 DISCH_THEN(X_CHOOSE_THEN ``n:num`` (MP_TAC o SPEC ``n:num``)) THEN 21865 ASM_SIMP_TAC std_ss [LESS_EQ_REFL, o_THM] THEN ASM_SET_TAC[]]]); 21866 21867(* ------------------------------------------------------------------------- *) 21868(* Locally compact sets are closed in an open set and are homeomorphic *) 21869(* to an absolutely closed set if we have one more dimension to play with. *) 21870(* ------------------------------------------------------------------------- *) 21871 21872val LOCALLY_COMPACT_OPEN_INTER_CLOSURE = store_thm ("LOCALLY_COMPACT_OPEN_INTER_CLOSURE", 21873 ``!s:real->bool. locally compact s ==> ?t. open t /\ (s = t INTER closure s)``, 21874 GEN_TAC THEN SIMP_TAC std_ss [LOCALLY_COMPACT, OPEN_IN_OPEN, CLOSED_IN_CLOSED] THEN 21875 SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM] THEN 21876 ONCE_REWRITE_TAC [METIS [] ``(x IN s INTER t /\ s INTER t SUBSET v /\ 21877 v SUBSET s /\ open t /\ compact v) = 21878 (\v t. x IN s INTER t /\ s INTER t SUBSET v /\ 21879 v SUBSET s /\ open t /\ compact v) v t``] THEN 21880 REWRITE_TAC[GSYM CONJ_ASSOC, TAUT `p /\ (x = y) /\ q <=> (x = y) /\ p /\ q`] THEN 21881 ONCE_REWRITE_TAC[MESON[] ``(?v t. P v t) <=> (?t v. P v t)``] THEN 21882 DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 21883 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 21884 MAP_EVERY X_GEN_TAC [``u:real->real->bool``, ``v:real->real->bool``] THEN 21885 DISCH_TAC THEN EXISTS_TAC ``BIGUNION (IMAGE (u:real->real->bool) s)`` THEN 21886 ASM_SIMP_TAC std_ss [CLOSED_CLOSURE, OPEN_BIGUNION, FORALL_IN_IMAGE] THEN 21887 REWRITE_TAC[INTER_BIGUNION] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC 21888 ``BIGUNION {v INTER s | v | v IN IMAGE (u:real->real->bool) s}`` THEN 21889 CONJ_TAC THENL 21890 [SIMP_TAC std_ss [BIGUNION_GSPEC, EXISTS_IN_IMAGE] THEN ASM_SET_TAC[], ALL_TAC] THEN 21891 AP_TERM_TAC THEN 21892 ONCE_REWRITE_TAC [METIS [] ``v INTER s = (\v. v INTER s:real->bool) v``] THEN 21893 MATCH_MP_TAC(SET_RULE ``(!x. x IN s ==> (f(g x) = f'(g x))) 21894 ==> ({f x | x IN IMAGE g s} = {f' x | x IN IMAGE g s})``) THEN 21895 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 21896 SIMP_TAC std_ss [GSYM SUBSET_ANTISYM_EQ] THEN CONJ_TAC THENL 21897 [MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[], 21898 REWRITE_TAC[SUBSET_INTER, INTER_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN 21899 EXISTS_TAC ``closure((u:real->real->bool) x INTER s)`` THEN 21900 ASM_SIMP_TAC std_ss [OPEN_INTER_CLOSURE_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN 21901 EXISTS_TAC ``(v:real->real->bool) x`` THEN 21902 ASM_SIMP_TAC std_ss [] THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN 21903 ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED] THEN ASM_SET_TAC[]]); 21904 21905val LOCALLY_COMPACT_CLOSED_IN_OPEN = store_thm ("LOCALLY_COMPACT_CLOSED_IN_OPEN", 21906 ``!s:real->bool. 21907 locally compact s ==> ?t. open t /\ closed_in (subtopology euclidean t) s``, 21908 GEN_TAC THEN 21909 DISCH_THEN(MP_TAC o MATCH_MP LOCALLY_COMPACT_OPEN_INTER_CLOSURE) THEN 21910 STRIP_TAC THEN EXISTS_TAC ``t:real->bool`` THEN ASM_SIMP_TAC std_ss [] THEN 21911 FIRST_X_ASSUM SUBST1_TAC THEN 21912 SIMP_TAC std_ss [CLOSED_IN_CLOSED_INTER, CLOSED_CLOSURE]); 21913 21914val LOCALLY_COMPACT_CLOSED_INTER_OPEN = store_thm ("LOCALLY_COMPACT_CLOSED_INTER_OPEN", 21915 ``!s:real->bool. 21916 locally compact s <=> ?t u. closed t /\ open u /\ (s = t INTER u)``, 21917 MESON_TAC[CLOSED_IMP_LOCALLY_COMPACT, OPEN_IMP_LOCALLY_COMPACT, 21918 LOCALLY_COMPACT_INTER, INTER_COMM, CLOSED_CLOSURE, 21919 LOCALLY_COMPACT_OPEN_INTER_CLOSURE]); 21920 21921(* ------------------------------------------------------------------------- *) 21922(* Forms of the Baire propery of dense sets. *) 21923(* ------------------------------------------------------------------------- *) 21924 21925val BAIRE = store_thm ("BAIRE", 21926 ``!g s:real->bool. 21927 locally compact s /\ COUNTABLE g /\ 21928 (!t. t IN g 21929 ==> open_in (subtopology euclidean s) t /\ s SUBSET closure t) 21930 ==> s SUBSET closure(BIGINTER g)``, 21931 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``g:(real->bool)->bool = {}`` THEN 21932 ASM_REWRITE_TAC[BIGINTER_EMPTY, CLOSURE_UNIV, SUBSET_UNIV] THEN 21933 MP_TAC(ISPEC ``g:(real->bool)->bool`` COUNTABLE_AS_IMAGE) THEN 21934 ASM_REWRITE_TAC[] THEN 21935 MAP_EVERY (C UNDISCH_THEN (K ALL_TAC)) 21936 [``COUNTABLE(g:(real->bool)->bool)``, 21937 ``~(g:(real->bool)->bool = {})``] THEN 21938 DISCH_THEN(X_CHOOSE_THEN ``g:num->real->bool`` SUBST_ALL_TAC) THEN 21939 RULE_ASSUM_TAC(SIMP_RULE std_ss [FORALL_IN_IMAGE, IN_UNIV]) THEN 21940 REWRITE_TAC[SUBSET_DEF, CLOSURE_NONEMPTY_OPEN_INTER] THEN 21941 X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN 21942 X_GEN_TAC ``v:real->bool`` THEN STRIP_TAC THEN 21943 MP_TAC(ISPECL 21944 [``\n:num u:real->bool. 21945 open_in (subtopology euclidean s) u /\ ~(u = {}) /\ u SUBSET v``, 21946 ``\n:num u v:real->bool. 21947 ?c. compact c /\ v SUBSET c /\ c SUBSET u /\ c SUBSET (g n)``] 21948 DEPENDENT_CHOICE) THEN 21949 SIMP_TAC std_ss [] THEN 21950 KNOW_TAC ``(?(a :real -> bool). 21951 open_in (subtopology euclidean (s :real -> bool)) a /\ 21952 a <> ({} :real -> bool) /\ a SUBSET (v :real -> bool)) /\ 21953 (!(n :num) (x :real -> bool). 21954 open_in (subtopology euclidean s) x /\ x <> ({} :real -> bool) /\ 21955 x SUBSET v ==> 21956 ?(y :real -> bool). 21957 (open_in (subtopology euclidean s) y /\ y <> ({} :real -> bool) /\ 21958 y SUBSET v) /\ 21959 ?(c :real -> bool). 21960 compact c /\ y SUBSET c /\ c SUBSET x /\ 21961 c SUBSET (g :num -> real -> bool) n)`` THENL 21962 [CONJ_TAC THENL 21963 [EXISTS_TAC ``s INTER v:real->bool`` THEN 21964 ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER] THEN ASM_SET_TAC[], 21965 ALL_TAC] THEN 21966 MAP_EVERY X_GEN_TAC [``n:num``, ``w:real->bool``] THEN STRIP_TAC THEN 21967 FIRST_X_ASSUM(STRIP_ASSUME_TAC o SPEC ``n:num``) THEN 21968 SUBGOAL_THEN ``?b:real. b IN w /\ b IN g(n:num)`` 21969 STRIP_ASSUME_TAC THENL 21970 [UNDISCH_TAC ``open_in (subtopology euclidean s) (w:real->bool)`` THEN 21971 SIMP_TAC std_ss [OPEN_IN_OPEN, LEFT_IMP_EXISTS_THM] THEN 21972 X_GEN_TAC ``t:real->bool`` THEN 21973 STRIP_TAC THEN ASM_REWRITE_TAC[IN_INTER] THEN 21974 UNDISCH_TAC ``s SUBSET closure((g:num->real->bool) n)`` THEN 21975 REWRITE_TAC[SUBSET_DEF, CLOSURE_NONEMPTY_OPEN_INTER] THEN 21976 FIRST_X_ASSUM(X_CHOOSE_TAC ``x:real`` o 21977 REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 21978 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 21979 KNOW_TAC ``x:real IN s`` THENL [ASM_SET_TAC[], DISCH_TAC THEN 21980 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 21981 DISCH_THEN(MP_TAC o SPEC ``t:real->bool``) THEN 21982 KNOW_TAC ``x:real IN t /\ open t`` THENL 21983 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 21984 FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN SET_TAC[], 21985 UNDISCH_TAC ``locally compact s`` THEN DISCH_TAC THEN 21986 FIRST_ASSUM(MP_TAC o REWRITE_RULE [locally]) THEN 21987 DISCH_THEN(MP_TAC o SPECL 21988 [``w INTER (g:num->real->bool) n``, ``b:real``]) THEN 21989 ASM_SIMP_TAC std_ss [OPEN_IN_INTER, OPEN_IN_REFL, IN_INTER] THEN 21990 SIMP_TAC std_ss [GSYM RIGHT_EXISTS_AND_THM] THEN 21991 STRIP_TAC THEN MAP_EVERY EXISTS_TAC [``u:real->bool``,``v':real->bool``] THEN 21992 ASM_SET_TAC[]], 21993 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 21994 SIMP_TAC std_ss [SKOLEM_THM, GSYM RIGHT_EXISTS_AND_THM, LEFT_IMP_EXISTS_THM] THEN 21995 MAP_EVERY X_GEN_TAC [``u:num->real->bool``, ``c:num->real->bool``] THEN 21996 SIMP_TAC std_ss [FORALL_AND_THM] THEN STRIP_TAC THEN 21997 MATCH_MP_TAC(SET_RULE ``!s. s SUBSET t /\ ~(s = {}) ==> ~(t = {})``) THEN 21998 EXISTS_TAC ``BIGINTER {c n:real->bool | n IN univ(:num)}`` THEN 21999 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 22000 MATCH_MP_TAC COMPACT_NEST THEN ASM_REWRITE_TAC[] THEN 22001 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 22002 ONCE_REWRITE_TAC [METIS [] ``(c n SUBSET c m) = (\m n. c n SUBSET c m) m n``] THEN 22003 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SET_TAC[]]); 22004 22005val BAIRE_ALT = store_thm ("BAIRE_ALT", 22006 ``!g s:real->bool. 22007 locally compact s /\ ~(s = {}) /\ COUNTABLE g /\ (BIGUNION g = s) 22008 ==> ?t u. t IN g /\ open_in (subtopology euclidean s) u /\ 22009 u SUBSET (closure t)``, 22010 REPEAT STRIP_TAC THEN MP_TAC(ISPECL 22011 [``IMAGE (\t:real->bool. s DIFF closure t) g``, ``s:real->bool``] BAIRE) THEN 22012 ASM_SIMP_TAC std_ss [COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN 22013 MATCH_MP_TAC(TAUT `~q /\ (~r ==> p) ==> (p ==> q) ==> r`) THEN 22014 CONJ_TAC THENL 22015 [MATCH_MP_TAC(SET_RULE 22016 ``~(s = {}) /\ ((t = {}) ==> (closure t = {})) /\ (t = {}) 22017 ==> ~(s SUBSET closure t)``) THEN 22018 ASM_SIMP_TAC std_ss [CLOSURE_EMPTY] THEN 22019 MATCH_MP_TAC(SET_RULE ``i SUBSET s /\ (s DIFF i = s) ==> (i = {})``) THEN 22020 CONJ_TAC THENL [SIMP_TAC std_ss [BIGINTER_IMAGE] THEN ASM_SET_TAC[], ALL_TAC] THEN 22021 REWRITE_TAC[DIFF_BIGINTER] THEN 22022 REWRITE_TAC[SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN 22023 SIMP_TAC std_ss [SET_RULE ``s DIFF (s DIFF t) = s INTER t``] THEN 22024 REWRITE_TAC[SET_RULE ``{s INTER closure t | t IN g} = 22025 {s INTER t | t IN IMAGE closure g}``] THEN 22026 SIMP_TAC std_ss [GSYM INTER_BIGUNION, SET_RULE ``(s INTER t = s) <=> s SUBSET t``] THEN 22027 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN 22028 GEN_REWR_TAC (LAND_CONV o RAND_CONV) [GSYM IMAGE_ID] THEN 22029 MATCH_MP_TAC BIGUNION_MONO_IMAGE THEN SIMP_TAC std_ss [CLOSURE_SUBSET], 22030 SIMP_TAC std_ss [NOT_EXISTS_THM] THEN STRIP_TAC THEN 22031 X_GEN_TAC ``t:real->bool`` THEN REPEAT STRIP_TAC THENL 22032 [ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s DIFF (s INTER t)``] THEN 22033 MATCH_MP_TAC OPEN_IN_DIFF THEN 22034 ASM_SIMP_TAC std_ss [CLOSED_IN_CLOSED_INTER, CLOSED_CLOSURE, OPEN_IN_REFL], 22035 REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22036 REWRITE_TAC[CLOSURE_APPROACHABLE] THEN 22037 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL 22038 [``t:real->bool``, ``s INTER ball(x:real,e)``]) THEN 22039 ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL, SUBSET_DEF, IN_INTER, IN_BALL, 22040 IN_DIFF] THEN 22041 METIS_TAC[DIST_SYM]]]); 22042 22043val NOWHERE_DENSE_COUNTABLE_BIGUNION_CLOSED = store_thm ("NOWHERE_DENSE_COUNTABLE_BIGUNION_CLOSED", 22044 ``!g:(real->bool)->bool. 22045 COUNTABLE g /\ (!s. s IN g ==> closed s /\ (interior s = {})) 22046 ==> (interior(BIGUNION g) = {})``, 22047 REPEAT STRIP_TAC THEN 22048 MP_TAC(ISPECL [``{univ(:real) DIFF s | s IN g}``, ``univ(:real)``] 22049 BAIRE) THEN 22050 SIMP_TAC std_ss [LOCALLY_COMPACT_UNIV, GSYM OPEN_IN, SUBTOPOLOGY_UNIV] THEN 22051 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN 22052 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN 22053 ASM_SIMP_TAC std_ss [GSYM closed_def, SET_RULE 22054 ``UNIV SUBSET s <=> (UNIV DIFF s = {})``] THEN 22055 SIMP_TAC std_ss[GSYM INTERIOR_COMPLEMENT] THEN 22056 SIMP_TAC std_ss [IMAGE_DEF, GSYM BIGUNION_BIGINTER] THEN 22057 ASM_SIMP_TAC std_ss [SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``]); 22058 22059val NOWHERE_DENSE_COUNTABLE_BIGUNION = store_thm ("NOWHERE_DENSE_COUNTABLE_BIGUNION", 22060 ``!g:(real->bool)->bool. 22061 COUNTABLE g /\ (!s. s IN g ==> (interior(closure s) = {})) 22062 ==> (interior(BIGUNION g) = {})``, 22063 REPEAT STRIP_TAC THEN 22064 MP_TAC(ISPEC ``IMAGE closure (g:(real->bool)->bool)`` 22065 NOWHERE_DENSE_COUNTABLE_BIGUNION_CLOSED) THEN 22066 ASM_SIMP_TAC std_ss [COUNTABLE_IMAGE, FORALL_IN_IMAGE, CLOSED_CLOSURE] THEN 22067 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (t = {}) ==> (s = {})``) THEN 22068 MATCH_MP_TAC SUBSET_INTERIOR THEN MATCH_MP_TAC BIGUNION_MONO THEN 22069 SIMP_TAC std_ss [EXISTS_IN_IMAGE] THEN MESON_TAC[CLOSURE_SUBSET]); 22070 22071(* ------------------------------------------------------------------------- *) 22072(* Partitions of unity subordinate to locally finite open coverings. *) 22073(* ------------------------------------------------------------------------- *) 22074 22075val SUBORDINATE_PARTITION_OF_UNITY = store_thm ("SUBORDINATE_PARTITION_OF_UNITY", 22076 ``!c s. s SUBSET BIGUNION c /\ (!u. u IN c ==> open u) /\ 22077 (!x. x IN s 22078 ==> ?v. open v /\ x IN v /\ 22079 FINITE {u | u IN c /\ ~(u INTER v = {})}) 22080 ==> ?f:(real->bool)->real->real. 22081 (!u. u IN c 22082 ==> f u continuous_on s /\ 22083 !x. x IN s ==> &0 <= f u x) /\ 22084 (!x u. u IN c /\ x IN s /\ ~(x IN u) ==> (f u x = &0)) /\ 22085 (!x. x IN s ==> (sum c (\u. f u x) = &1)) /\ 22086 (!x. x IN s 22087 ==> ?n. open n /\ x IN n /\ 22088 FINITE {u | u IN c /\ 22089 ~(!x. x IN n ==> (f u x = &0))})``, 22090 REPEAT STRIP_TAC THEN 22091 ASM_CASES_TAC ``?u:real->bool. u IN c /\ s SUBSET u`` THENL 22092 [FIRST_X_ASSUM(CHOOSE_THEN STRIP_ASSUME_TAC) THEN 22093 EXISTS_TAC ``\v:real->bool x:real. if v = u then &1 else &0:real`` THEN 22094 SIMP_TAC arith_ss [COND_RAND, COND_RATOR, o_DEF, REAL_POS, REAL_OF_NUM_EQ, 22095 METIS [] ``(if p then q else T) <=> p ==> q``] THEN 22096 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CONST, COND_ID, SUM_DELTA] THEN 22097 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 22098 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22099 EXISTS_TAC ``ball(x:real,&1)`` THEN 22100 REWRITE_TAC[OPEN_BALL, CENTRE_IN_BALL, REAL_LT_01] THEN 22101 MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``{u:real->bool}`` THEN 22102 SIMP_TAC std_ss [FINITE_SING, SUBSET_DEF, GSPECIFICATION, IN_SING] THEN 22103 X_GEN_TAC ``v:real->bool`` THEN 22104 ASM_CASES_TAC ``v:real->bool = u`` THEN ASM_REWRITE_TAC[], 22105 ALL_TAC] THEN 22106 EXISTS_TAC ``\u:real->bool x:real. 22107 if x IN s 22108 then setdist({x},s DIFF u) / sum c (\v. setdist({x},s DIFF v)) 22109 else &0`` THEN 22110 SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE] THEN 22111 SIMP_TAC std_ss [SUM_POS_LE, SETDIST_POS_LE, REAL_LE_DIV] THEN 22112 SIMP_TAC std_ss [SETDIST_SING_IN_SET, IN_DIFF, real_div, REAL_MUL_LZERO] THEN 22113 SIMP_TAC std_ss [SUM_RMUL] THEN REWRITE_TAC[GSYM real_div] THEN 22114 MATCH_MP_TAC(TAUT `r /\ p /\ q ==> p /\ q /\ r`) THEN CONJ_TAC THENL 22115 [X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22116 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 22117 DISCH_THEN (X_CHOOSE_TAC ``n:real->bool``) THEN EXISTS_TAC ``n:real->bool`` THEN 22118 POP_ASSUM MP_TAC THEN 22119 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 22120 ASM_REWRITE_TAC[] THEN 22121 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_FINITE_I) THEN 22122 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN X_GEN_TAC ``u:real->bool`` THEN 22123 ASM_CASES_TAC ``(u:real->bool) IN c`` THENL [ALL_TAC, METIS_TAC []] THEN 22124 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 22125 FULL_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN X_GEN_TAC ``y:real`` THEN CCONTR_TAC THEN 22126 FULL_SIMP_TAC std_ss [] THEN POP_ASSUM MP_TAC THEN 22127 REWRITE_TAC[real_div, REAL_ENTIRE] THEN 22128 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN 22129 ASM_CASES_TAC ``(y:real) IN u`` THEN 22130 ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, IN_DIFF, REAL_MUL_LZERO] THEN 22131 ASM_SET_TAC[], ALL_TAC] THEN 22132 SUBGOAL_THEN 22133 ``!v x:real. v IN c /\ x IN s /\ x IN v ==> &0 < setdist({x},s DIFF v)`` 22134 ASSUME_TAC THENL 22135 [REPEAT STRIP_TAC THEN 22136 SIMP_TAC std_ss [SETDIST_POS_LE, REAL_ARITH ``&0 < x <=> &0 <= x /\ ~(x = &0:real)``] THEN 22137 MP_TAC(ISPECL [``s:real->bool``, ``s DIFF v:real->bool``, ``x:real``] 22138 SETDIST_EQ_0_CLOSED_IN) THEN 22139 ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN 22140 ASM_SIMP_TAC std_ss [CLOSED_IN_CLOSED_INTER, GSYM OPEN_CLOSED] THEN 22141 DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[] THEN 22142 ASM_REWRITE_TAC[IN_INTER, IN_DIFF, IN_UNION] THEN ASM_SET_TAC[], 22143 ALL_TAC] THEN 22144 SUBGOAL_THEN 22145 ``!x:real. x IN s ==> &0 < sum c (\v. setdist ({x},s DIFF v))`` 22146 ASSUME_TAC THENL 22147 [X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22148 ONCE_REWRITE_TAC[GSYM SUM_SUPPORT] THEN 22149 REWRITE_TAC[support, NEUTRAL_REAL_ADD] THEN 22150 MATCH_MP_TAC SUM_POS_LT THEN SIMP_TAC std_ss [SETDIST_POS_LE] THEN 22151 CONJ_TAC THENL 22152 [FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 22153 DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 22154 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 22155 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_FINITE_I) THEN 22156 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN X_GEN_TAC ``u:real->bool`` THEN 22157 ASM_CASES_TAC ``(x:real) IN u`` THEN 22158 ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, IN_DIFF] THEN ASM_SET_TAC[], 22159 UNDISCH_TAC `` s SUBSET BIGUNION c:real->bool`` THEN DISCH_TAC THEN 22160 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 22161 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN REWRITE_TAC[IN_BIGUNION] THEN 22162 ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN DISCH_THEN (X_CHOOSE_TAC ``t:real->bool``) THEN 22163 EXISTS_TAC ``t:real->bool`` THEN METIS_TAC[REAL_LT_IMP_NE]], 22164 ALL_TAC] THEN 22165 ASM_SIMP_TAC std_ss [REAL_LT_IMP_NE, REAL_DIV_REFL, o_DEF] THEN 22166 X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 22167 MATCH_MP_TAC CONTINUOUS_ON_EQ THEN 22168 EXISTS_TAC ``\x:real. 22169 setdist({x},s DIFF u) / sum c (\v. setdist({x},s DIFF v))`` THEN 22170 SIMP_TAC std_ss [] THEN REWRITE_TAC[real_div] THEN 22171 ONCE_REWRITE_TAC [METIS [] 22172 ``(\x. setdist ({x},s DIFF u) * 22173 inv (sum c (\v. setdist ({x},s DIFF v)))) = 22174 (\x. (\x. setdist ({x},s DIFF u)) x * 22175 (\x. inv (sum c (\v. setdist ({x},s DIFF v)))) x)``] THEN 22176 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN 22177 SIMP_TAC std_ss [CONTINUOUS_ON_SETDIST, o_DEF] THEN 22178 ONCE_REWRITE_TAC [METIS [] 22179 ``(\x. inv (sum c (\v. setdist ({x},s DIFF v)))) = 22180 (\x. inv ((\x. sum c (\v. setdist ({x},s DIFF v))) x))``] THEN 22181 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN 22182 ASM_SIMP_TAC std_ss [REAL_LT_IMP_NE, CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 22183 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22184 FIRST_X_ASSUM(fn th => 22185 MP_TAC(SPEC ``x:real`` th) THEN ASM_REWRITE_TAC[] THEN 22186 DISCH_THEN(X_CHOOSE_THEN ``n:real->bool`` STRIP_ASSUME_TAC)) THEN 22187 MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN_OPEN_IN THEN 22188 MAP_EVERY EXISTS_TAC 22189 [``\x:real. sum {v | v IN c /\ ~(v INTER n = {})} 22190 (\v. setdist({x},s DIFF v))``, 22191 ``s INTER n:real->bool``] THEN 22192 ASM_SIMP_TAC std_ss [IN_INTER, OPEN_IN_OPEN_INTER] THEN CONJ_TAC THENL 22193 [X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 22194 CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_EQ_SUPERSET THEN 22195 ASM_REWRITE_TAC[SUBSET_RESTRICT] THEN STRIP_TAC THENL 22196 [ASM_SET_TAC [], ALL_TAC] THEN X_GEN_TAC ``v:real->bool`` THEN 22197 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 22198 ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN DISCH_TAC THEN 22199 MATCH_MP_TAC SETDIST_SING_IN_SET THEN ASM_SET_TAC[], 22200 ONCE_REWRITE_TAC [METIS [] 22201 ``(\x. sum {v | v IN c /\ v INTER n <> {}} 22202 (\v. setdist ({x},s DIFF v))) = 22203 (\x. sum {v | v IN c /\ v INTER n <> {}} 22204 (\v. (\v x. setdist ({x},s DIFF v)) v x))``] THEN 22205 MATCH_MP_TAC CONTINUOUS_SUM THEN 22206 ASM_SIMP_TAC std_ss [CONTINUOUS_AT_SETDIST, CONTINUOUS_AT_WITHIN]]); 22207 22208val _ = export_theory(); 22209