1(* ========================================================================= *) 2(* *) 3(* Elementary topology in Euclidean space *) 4(* *) 5(* (c) Copyright 2015, *) 6(* Muhammad Qasim, *) 7(* Osman Hasan, *) 8(* Hardware Verification Group, *) 9(* Concordia University *) 10(* *) 11(* Contact: <m_qasi@ece.concordia.ca> *) 12(* *) 13(* *) 14(* Note: This theory has been ported from hol light *) 15(* *) 16(* (c) Copyright, John Harrison 1998-2015 *) 17(* (c) Copyright, Valentina Bruno 2010 *) 18(* (c) Copyright, Marco Maggesi 2014-2015 *) 19(* ========================================================================= *) 20 21open HolKernel Parse boolLib bossLib numLib unwindLib tautLib Arith prim_recTheory 22combinTheory quotientTheory arithmeticTheory hrealTheory realaxTheory realTheory 23jrhUtils pairTheory boolTheory pred_setTheory optionTheory numTheory 24sumTheory InductiveDefinition ind_typeTheory listTheory mesonLib 25seqTheory limTheory transcTheory realLib topologyTheory; 26 27open wellorderTheory cardinalTheory; 28open util_probTheory iterateTheory productTheory; 29 30val _ = new_theory "real_topology"; 31 32(* ------------------------------------------------------------------------- *) 33(* MESON, METIS, SET_TAC, SET_RULE, ASSERT_TAC, ASM_ARITH_TAC *) 34(* ------------------------------------------------------------------------- *) 35 36val Reverse = Tactical.REVERSE; 37fun K_TAC _ = ALL_TAC; 38fun MESON ths tm = prove(tm,MESON_TAC ths); 39fun METIS ths tm = prove(tm,METIS_TAC ths); 40 41val DISC_RW_KILL = DISCH_TAC THEN ONCE_ASM_REWRITE_TAC [] THEN 42 POP_ASSUM K_TAC; 43 44fun SET_TAC L = 45 POP_ASSUM_LIST(K ALL_TAC) THEN REPEAT COND_CASES_TAC THEN 46 REWRITE_TAC (append [EXTENSION, SUBSET_DEF, PSUBSET_DEF, DISJOINT_DEF, 47 SING_DEF] L) THEN 48 SIMP_TAC std_ss [NOT_IN_EMPTY, IN_UNIV, IN_UNION, IN_INTER, IN_DIFF, 49 IN_INSERT, IN_DELETE, IN_REST, IN_BIGINTER, IN_BIGUNION, IN_IMAGE, 50 GSPECIFICATION, IN_DEF, EXISTS_PROD] THEN METIS_TAC []; 51 52fun ASSERT_TAC tm = SUBGOAL_THEN tm STRIP_ASSUME_TAC; 53fun SET_RULE tm = prove(tm,SET_TAC []); 54fun ASM_SET_TAC L = REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC L; 55 56val ASM_ARITH_TAC = REPEAT (POP_ASSUM MP_TAC) THEN ARITH_TAC; 57val ASM_REAL_ARITH_TAC = REPEAT (POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC; 58 59val KILL_TAC = POP_ASSUM_LIST K_TAC; 60val Know = Q_TAC KNOW_TAC; 61val Suff = Q_TAC SUFF_TAC; 62 63fun wrap a = [a]; 64val Rewr = DISCH_THEN (REWRITE_TAC o wrap); 65val Rewr' = DISCH_THEN (ONCE_REWRITE_TAC o wrap); 66 67fun PRINT_TAC s gl = (* from cardinalTheory *) 68 (print ("** " ^ s ^ "\n"); ALL_TAC gl); 69 70(* ------------------------------------------------------------------------- *) 71(* misc. *) 72(* ------------------------------------------------------------------------- *) 73 74val REAL_LE_SQUARE_ABS = store_thm ("REAL_LE_SQUARE_ABS", 75 ``!x y:real. abs(x) <= abs(y) <=> x pow 2 <= y pow 2``, 76 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN 77 EQ_TAC THEN DISCH_TAC THENL 78 [MATCH_MP_TAC POW_LE THEN ASM_REAL_ARITH_TAC, 79 CCONTR_TAC THEN UNDISCH_TAC ``abs (x:real) pow 2 <= abs y pow 2`` THEN 80 REWRITE_TAC [TWO, REAL_NOT_LE] THEN MATCH_MP_TAC POW_LT THEN 81 ASM_REAL_ARITH_TAC]); 82 83val REAL_EQ_SQUARE_ABS = store_thm ("REAL_EQ_SQUARE_ABS", 84 ``!x y:real. (abs x = abs y) <=> (x pow 2 = y pow 2)``, 85 REWRITE_TAC[GSYM REAL_LE_ANTISYM, REAL_LE_SQUARE_ABS]); 86 87val REAL_HALF = store_thm ("REAL_HALF", 88 ``(!e:real. &0 < e / &2 <=> &0 < e) /\ 89 (!e:real. e / &2 + e / &2 = e) /\ 90 (!e:real. &2 * (e / &2) = e)``, 91 SIMP_TAC std_ss [REAL_LT_HALF1, REAL_HALF_DOUBLE, REAL_DIV_LMUL, 92 REAL_ARITH ``2 <> 0:real``]); 93 94val FINITE_SUBSET_IMAGE = store_thm ("FINITE_SUBSET_IMAGE", 95 ``!f:'a->'b s t. 96 FINITE(t) /\ t SUBSET (IMAGE f s) <=> 97 ?s'. FINITE s' /\ s' SUBSET s /\ (t = IMAGE f s')``, 98 REPEAT GEN_TAC THEN EQ_TAC THENL 99 [ALL_TAC, ASM_MESON_TAC[IMAGE_FINITE, IMAGE_SUBSET]] THEN 100 STRIP_TAC THEN 101 EXISTS_TAC ``IMAGE (\y. @x. x IN s /\ ((f:'a->'b)(x) = y)) t`` THEN 102 ASM_SIMP_TAC std_ss [IMAGE_FINITE] THEN 103 SIMP_TAC std_ss [EXTENSION, SUBSET_DEF, FORALL_IN_IMAGE] THEN CONJ_TAC THENL 104 [METIS_TAC[SUBSET_DEF, IN_IMAGE], ALL_TAC] THEN 105 REWRITE_TAC[IN_IMAGE] THEN X_GEN_TAC ``y:'b`` THEN 106 SIMP_TAC std_ss [GSYM RIGHT_EXISTS_AND_THM] THEN 107 ONCE_REWRITE_TAC[CONJ_SYM] THEN 108 REWRITE_TAC[UNWIND_THM2, GSYM CONJ_ASSOC] THEN 109 METIS_TAC [SUBSET_DEF, IN_IMAGE]); 110 111val EXISTS_FINITE_SUBSET_IMAGE = store_thm ("EXISTS_FINITE_SUBSET_IMAGE", 112 ``!P f s. 113 (?t. FINITE t /\ t SUBSET IMAGE f s /\ P t) <=> 114 (?t. FINITE t /\ t SUBSET s /\ P (IMAGE f t))``, 115 REWRITE_TAC[FINITE_SUBSET_IMAGE, CONJ_ASSOC] THEN MESON_TAC[]); 116 117val FORALL_FINITE_SUBSET_IMAGE = store_thm ("FORALL_FINITE_SUBSET_IMAGE", 118 ``!P f s. (!t. FINITE t /\ t SUBSET IMAGE f s ==> P t) <=> 119 (!t. FINITE t /\ t SUBSET s ==> P(IMAGE f t))``, 120 REPEAT GEN_TAC THEN 121 ONCE_REWRITE_TAC [METIS [] ``(FINITE t /\ t SUBSET IMAGE f s ==> P t) = 122 (\t. FINITE t /\ t SUBSET IMAGE f s ==> P t) t``] THEN 123 ONCE_REWRITE_TAC [METIS [] ``(FINITE t /\ t SUBSET s ==> P (IMAGE f t)) = 124 (\t. FINITE t /\ t SUBSET s ==> P (IMAGE f t)) t``] THEN 125 ONCE_REWRITE_TAC [MESON[] ``(!x. P x) <=> ~(?x. ~P x)``] THEN 126 SIMP_TAC std_ss [NOT_IMP, GSYM CONJ_ASSOC, EXISTS_FINITE_SUBSET_IMAGE]); 127 128val FORALL_IN_GSPEC = store_thm ("FORALL_IN_GSPEC", 129 ``(!P f. (!z. z IN {f x | P x} ==> Q z) <=> (!x. P x ==> Q(f x))) /\ 130 (!P f. (!z. z IN {f x y | P x y} ==> Q z) <=> 131 (!x y. P x y ==> Q(f x y))) /\ 132 (!P f. (!z. z IN {f w x y | P w x y} ==> Q z) <=> 133 (!w x y. P w x y ==> Q(f w x y)))``, 134 SRW_TAC [][] THEN SET_TAC []); 135 136val EXISTS_IN_GSPEC = store_thm ("EXISTS_IN_GSPEC", 137 ``(!P f. (?z. z IN {f x | P x} /\ Q z) <=> (?x. P x /\ Q(f x))) /\ 138 (!P f. (?z. z IN {f x y | P x y} /\ Q z) <=> 139 (?x y. P x y /\ Q(f x y))) /\ 140 (!P f. (?z. z IN {f w x y | P w x y} /\ Q z) <=> 141 (?w x y. P w x y /\ Q(f w x y)))``, 142 SRW_TAC [][] THEN SET_TAC[]); 143 144val EMPTY_BIGUNION = store_thm ("EMPTY_BIGUNION", 145 ``!s. (BIGUNION s = {}) <=> !t. t IN s ==> (t = {})``, 146 SET_TAC[]); 147 148val EMPTY_BIGUNION = store_thm ("EMPTY_BIGUNION", 149 ``!s. (BIGUNION s = {}) <=> !t. t IN s ==> (t = {})``, 150 SET_TAC[]); 151 152val REAL_LT_RNEG = store_thm ("REAL_LT_RNEG", 153 ``!x y. x < -y <=> x + y < &0:real``, 154 SIMP_TAC std_ss [real_lt, REAL_LE_LNEG, REAL_ADD_AC]); 155 156val UPPER_BOUND_FINITE_SET = store_thm ("UPPER_BOUND_FINITE_SET", 157 ``!f:('a->num) s. FINITE(s) ==> ?a. !x. x IN s ==> f(x) <= a``, 158 GEN_TAC THEN 159 KNOW_TAC ``!s. (?a. !x. x IN s ==> (f:('a->num))(x) <= a) = 160 (\s. ?a. !x. x IN s ==> f(x) <= a) s`` THENL 161 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 162 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 163 REWRITE_TAC[IN_INSERT, NOT_IN_EMPTY] THEN 164 MESON_TAC[LESS_EQ_CASES, LESS_EQ_REFL, LESS_EQ_TRANS]); 165 166val REAL_BOUNDS_LT = store_thm ("REAL_BOUNDS_LT", 167 ``!x k:real. -k < x /\ x < k <=> abs(x) < k``, 168 REAL_ARITH_TAC); 169 170val BIGUNION_IMAGE = store_thm ("BIGUNION_IMAGE", 171 ``!f s. BIGUNION (IMAGE f s) = {y | ?x. x IN s /\ y IN f x}``, 172 REPEAT GEN_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 173 SIMP_TAC std_ss [IN_BIGUNION, IN_IMAGE, GSPECIFICATION] THEN MESON_TAC[]); 174 175val BIGINTER_IMAGE = store_thm ("BIGINTER_IMAGE", 176 ``!f s. BIGINTER (IMAGE f s) = {y | !x. x IN s ==> y IN f x}``, 177 REPEAT GEN_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 178 SIMP_TAC std_ss [IN_BIGINTER, IN_IMAGE, GSPECIFICATION] THEN MESON_TAC[]); 179 180val REAL_LE_LMUL1 = store_thm ("REAL_LE_LMUL1", 181 ``!x y z:real. &0 <= x /\ y <= z ==> x * y <= x * z``, 182 METIS_TAC [REAL_LE_LMUL, REAL_MUL_LZERO, REAL_LE_LT]); 183 184val LE_EXISTS = store_thm ("LE_EXISTS", 185 ``!m n:num. (m <= n) <=> (?d. n = m + d)``, 186 GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[LE] THENL 187 [REWRITE_TAC[CONV_RULE(LAND_CONV SYM_CONV) (SPEC_ALL ADD_EQ_0)] THEN 188 SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM, EXISTS_REFL], 189 EQ_TAC THENL 190 [DISCH_THEN(DISJ_CASES_THEN2 SUBST1_TAC MP_TAC) THENL 191 [EXISTS_TAC ``0:num`` THEN REWRITE_TAC[ADD_CLAUSES], 192 DISCH_THEN(X_CHOOSE_THEN ``d:num`` SUBST1_TAC) THEN 193 EXISTS_TAC ``SUC d`` THEN REWRITE_TAC[ADD_CLAUSES]], 194 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 195 INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES, INV_SUC_EQ] THEN 196 DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[] THEN DISJ2_TAC THEN 197 EXISTS_TAC ``d:num`` THEN SIMP_TAC std_ss []]]); 198 199val LT_EXISTS = store_thm ("LT_EXISTS", 200 ``!m n. (m < n) <=> (?d. n = m + SUC d)``, 201 GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[LT, ADD_CLAUSES, SUC_NOT] THEN 202 ASM_REWRITE_TAC[INV_SUC_EQ] THEN EQ_TAC THENL 203 [DISCH_THEN(DISJ_CASES_THEN2 SUBST1_TAC MP_TAC) THENL 204 [EXISTS_TAC ``0:num`` THEN REWRITE_TAC[ADD_CLAUSES], 205 DISCH_THEN(X_CHOOSE_THEN ``d:num`` SUBST1_TAC) THEN 206 EXISTS_TAC ``SUC d`` THEN REWRITE_TAC[ADD_CLAUSES]], 207 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 208 INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES, INV_SUC_EQ] THEN 209 DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[] THEN DISJ2_TAC THEN 210 EXISTS_TAC ``d:num`` THEN SIMP_TAC std_ss []]); 211 212val BOUNDS_LINEAR = store_thm ("BOUNDS_LINEAR", 213 ``!A B C. (!n:num. A * n <= B * n + C) <=> A <= B``, 214 REPEAT GEN_TAC THEN EQ_TAC THENL 215 [CONV_TAC CONTRAPOS_CONV THEN REWRITE_TAC[NOT_LESS_EQUAL] THEN 216 DISCH_THEN(CHOOSE_THEN SUBST1_TAC o REWRITE_RULE[LT_EXISTS]) THEN 217 REWRITE_TAC[RIGHT_ADD_DISTRIB, LE_ADD_LCANCEL] THEN 218 DISCH_THEN(MP_TAC o SPEC ``SUC C``) THEN 219 REWRITE_TAC[NOT_LESS_EQUAL, MULT_CLAUSES, ADD_CLAUSES, LT_SUC_LE] THEN 220 ARITH_TAC, 221 DISCH_THEN(CHOOSE_THEN SUBST1_TAC o REWRITE_RULE[LE_EXISTS]) THEN 222 ARITH_TAC]); 223 224val BOUNDS_LINEAR_0 = store_thm ("BOUNDS_LINEAR_0", 225 ``!A B. (!n:num. A * n <= B) <=> (A = 0)``, 226 REPEAT GEN_TAC THEN 227 MP_TAC (SPECL [``A:num``, ``0:num``, ``B:num``] BOUNDS_LINEAR) THEN 228 REWRITE_TAC[MULT_CLAUSES, ADD_CLAUSES, LE]); 229 230val REAL_LE_BETWEEN = store_thm ("REAL_LE_BETWEEN", 231 ``!a b. a <= b <=> ?x:real. a <= x /\ x <= b``, 232 MESON_TAC[REAL_LE_TRANS, REAL_LE_REFL]); 233 234val WLOG_LE = store_thm ("WLOG_LE", 235 ``(!m n:num. P m n <=> P n m) /\ (!m n:num. m <= n ==> P m n) ==> 236 !m n:num. P m n``, 237 METIS_TAC[LE_CASES]); 238 239val BIGUNION_GSPEC = store_thm ("BIGUNION_GSPEC", 240 ``(!P f. BIGUNION {f x | P x} = {a | ?x. P x /\ a IN (f x)}) /\ 241 (!P f. BIGUNION {f x y | P x y} = {a | ?x y. P x y /\ a IN (f x y)}) /\ 242 (!P f. BIGUNION {f x y z | P x y z} = 243 {a | ?x y z. P x y z /\ a IN (f x y z)})``, 244 REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 245 SIMP_TAC std_ss [IN_BIGUNION, GSPECIFICATION, EXISTS_PROD] THEN MESON_TAC[]); 246 247val BIGINTER_GSPEC = store_thm ("BIGINTER_GSPEC", 248 ``(!P f. BIGINTER {f x | P x} = {a | !x. P x ==> a IN (f x)}) /\ 249 (!P f. BIGINTER {f x y | P x y} = {a | !x y. P x y ==> a IN (f x y)}) /\ 250 (!P f. BIGINTER {f x y z | P x y z} = 251 {a | !x y z. P x y z ==> a IN (f x y z)})``, 252 REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 253 SIMP_TAC std_ss [IN_BIGINTER, GSPECIFICATION, EXISTS_PROD] THEN MESON_TAC[]); 254 255val FINITE_POWERSET = store_thm ("FINITE_POWERSET", 256 ``!s. FINITE s ==> FINITE {t | t SUBSET s}``, 257 METIS_TAC [FINITE_POW, POW_DEF]); 258 259val LE_ADD = store_thm ("LE_ADD", 260 ``!m n:num. m <= m + n``, 261 GEN_TAC THEN INDUCT_TAC THEN 262 ASM_SIMP_TAC arith_ss [LE, ADD_CLAUSES, LESS_EQ_REFL]); 263 264val LE_ADDR = store_thm ("LE_ADDR", 265 ``!m n:num. n <= m + n``, 266 ONCE_REWRITE_TAC[ADD_SYM] THEN MATCH_ACCEPT_TAC LE_ADD); 267 268val ADD_SUB2 = store_thm ("ADD_SUB2", 269 ``!m n:num. (m + n) - m = n``, 270 ONCE_REWRITE_TAC[ADD_SYM] THEN MATCH_ACCEPT_TAC ADD_SUB); 271 272val ADD_SUBR2 = store_thm ("ADD_SUBR2", 273 ``!m n:num. m - (m + n) = 0``, 274 REWRITE_TAC[SUB_EQ_0, LESS_EQ_ADD]); 275 276val ADD_SUBR = store_thm ("ADD_SUBR", 277 ``!m n:num. n - (m + n) = 0``, 278 ONCE_REWRITE_TAC[ADD_SYM] THEN MATCH_ACCEPT_TAC ADD_SUBR2); 279 280val TRANSITIVE_STEPWISE_LE_EQ = store_thm ("TRANSITIVE_STEPWISE_LE_EQ", 281 ``!R. (!x. R x x) /\ (!x y z. R x y /\ R y z ==> R x z) 282 ==> ((!m n. m <= n ==> R m n) <=> (!n. R n (SUC n)))``, 283 REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC std_ss [LE, LESS_EQ_REFL] THEN 284 DISCH_TAC THEN SIMP_TAC std_ss [LE_EXISTS, LEFT_IMP_EXISTS_THM] THEN 285 GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES] THEN ASM_MESON_TAC[]); 286 287val TRANSITIVE_STEPWISE_LE = store_thm ("TRANSITIVE_STEPWISE_LE", 288 ``!R. (!x. R x x) /\ (!x y z. R x y /\ R y z ==> R x z) /\ 289 (!n. R n (SUC n)) 290 ==> !m n. m <= n ==> R m n``, 291 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT 292 `(a /\ a' ==> (c <=> b)) ==> a /\ a' /\ b ==> c`) THEN 293 MATCH_ACCEPT_TAC TRANSITIVE_STEPWISE_LE_EQ); 294 295val LAMBDA_PAIR = store_thm ("LAMBDA_PAIR", 296 ``(\(x,y). P x y) = (\p. P (FST p) (SND p))``, 297 SIMP_TAC std_ss [FUN_EQ_THM, FORALL_PROD] THEN 298 SIMP_TAC std_ss []); 299 300val NOT_EQ = store_thm ("NOT_EQ", 301 ``!a b. (a <> b) = ~(a = b)``, METIS_TAC []); 302 303val ABS_LE_0 = store_thm ("ABS_LE_0", 304 ``!x:real. abs x <= &0 <=> (x = 0)``, 305 MESON_TAC[REAL_LE_ANTISYM, ABS_ZERO, ABS_POS]); 306 307val REAL_OF_NUM_GE = store_thm ("REAL_OF_NUM_GE", 308 ``!m n. &m >= (&n:real) <=> m >= n``, 309 REWRITE_TAC[GE, real_ge, REAL_OF_NUM_LE]); 310 311val POWERSET_CLAUSES = store_thm ("POWERSET_CLAUSES", 312 ``({s | s SUBSET {}} = {{}}) /\ 313 ((!a:'a t. {s | s SUBSET (a INSERT t)} = 314 {s | s SUBSET t} UNION IMAGE (\s. a INSERT s) {s | s SUBSET t}))``, 315 REWRITE_TAC[SUBSET_INSERT_DELETE, SUBSET_EMPTY, SET_RULE 316 ``(!a. {x | x = a} = {a}) /\ (!a. {x | a = x} = {a})``] THEN 317 MAP_EVERY X_GEN_TAC [``a:'a``, ``t:'a->bool``] THEN 318 MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[UNION_SUBSET] THEN 319 ONCE_REWRITE_TAC[SUBSET_DEF] THEN 320 SIMP_TAC std_ss [FORALL_IN_IMAGE, FORALL_IN_GSPEC] THEN 321 SIMP_TAC std_ss [GSPECIFICATION, IN_UNION, IN_IMAGE] THEN 322 CONJ_TAC THENL [ALL_TAC, SET_TAC[]] THEN 323 X_GEN_TAC ``s:'a->bool`` THEN 324 ASM_CASES_TAC ``(a:'a) IN s`` THENL [ALL_TAC, ASM_SET_TAC[]] THEN 325 STRIP_TAC THEN DISJ2_TAC THEN EXISTS_TAC ``s DELETE (a:'a)`` THEN 326 ASM_SET_TAC[]); 327 328val REAL_LT_LCANCEL_IMP = store_thm ("REAL_LT_LCANCEL_IMP", 329 ``!x y z:real. &0 < x /\ x * y < x * z ==> y < z``, 330 METIS_TAC [REAL_LT_LMUL]); 331 332val SIMPLE_IMAGE_GEN = store_thm ("SIMPLE_IMAGE_GEN", 333 ``!f P. {f x | P x} = IMAGE f {x | P x}``, 334 SET_TAC[]); 335 336val FINITE_IMAGE = IMAGE_FINITE; 337 338val SUBSET_BIGUNION = store_thm ("SUBSET_BIGUNION", 339 ``!f g. f SUBSET g ==> BIGUNION f SUBSET BIGUNION g``, 340 SET_TAC[]); 341 342val REAL_LT_POW2 = store_thm ("REAL_LT_POW2", 343 ``!n:num. (&0:real) < &2 pow n``, 344 SIMP_TAC arith_ss [REAL_POW_LT, REAL_LT]); 345 346val FUN_IN_IMAGE = store_thm ("FUN_IN_IMAGE", 347 ``!f s x. x IN s ==> f(x) IN IMAGE f s``, 348 SET_TAC[]); 349 350val SUBSET_ANTISYM_EQ = store_thm ("SUBSET_ANTISYM_EQ", 351 ``!(s:'a->bool) t. s SUBSET t /\ t SUBSET s <=> (s = t)``, 352 SET_TAC[]); 353 354val DIFF_BIGINTER = store_thm ("DIFF_BIGINTER", 355 ``!u s. u DIFF BIGINTER s = BIGUNION {u DIFF t | t IN s}``, 356 SIMP_TAC std_ss [BIGUNION_GSPEC] THEN SET_TAC[]); 357 358val BIGINTER_BIGUNION = store_thm ("BIGINTER_BIGUNION", 359 ``!s. BIGINTER s = UNIV DIFF (BIGUNION {UNIV DIFF t | t IN s})``, 360 REWRITE_TAC[GSYM DIFF_BIGINTER] THEN SET_TAC[]); 361 362val BIGUNION_BIGINTER = store_thm ("BIGUNION_BIGINTER", 363 ``!s. BIGUNION s = UNIV DIFF (BIGINTER {UNIV DIFF t | t IN s})``, 364 GEN_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 365 SIMP_TAC std_ss [IN_BIGUNION, IN_UNIV, IN_DIFF, BIGINTER_GSPEC, 366 GSPECIFICATION] THEN 367 MESON_TAC[]); 368 369val REAL_POW_1_LE = store_thm ("REAL_POW_1_LE", 370 ``!n x:real. &0 <= x /\ x <= &1 ==> x pow n <= &1``, 371 REPEAT STRIP_TAC THEN 372 MP_TAC(SPECL [``n:num``, ``x:real``, ``&1:real``] POW_LE) THEN 373 ASM_REWRITE_TAC[POW_ONE]); 374 375val REAL_POW_LE_1 = store_thm ("REAL_POW_LE_1", 376 ``!n x:real. &1 <= x ==> &1 <= x pow n``, 377 REPEAT STRIP_TAC THEN 378 MP_TAC(SPECL [``n:num``, ``&1:real``, ``x:real``] POW_LE) THEN 379 ASM_SIMP_TAC real_ss [POW_ONE, REAL_POS]); 380 381val REAL_LT_INV2 = store_thm ("REAL_LT_INV2", 382 ``!x y. &0:real < x /\ x < y ==> inv(y) < inv(x)``, 383 REPEAT STRIP_TAC THEN KNOW_TAC ``&0:real < x * y`` THENL 384 [MATCH_MP_TAC REAL_LT_MUL THEN 385 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN REAL_ARITH_TAC, ALL_TAC] THEN 386 DISCH_TAC THEN KNOW_TAC ``inv y * (x * y) < inv x * (x * y:real)`` THENL 387 [ALL_TAC, FULL_SIMP_TAC std_ss [REAL_LT_RMUL]] THEN 388 SUBGOAL_THEN ``(inv x * x = &1:real) /\ (inv y * y = &1:real)`` ASSUME_TAC THENL 389 [CONJ_TAC THEN MATCH_MP_TAC REAL_MUL_LINV THEN 390 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN REAL_ARITH_TAC, 391 ASM_REWRITE_TAC[REAL_MUL_ASSOC, REAL_MUL_LID] THEN 392 GEN_REWR_TAC (LAND_CONV o LAND_CONV) [REAL_MUL_SYM] THEN 393 ASM_REWRITE_TAC[GSYM REAL_MUL_ASSOC, REAL_MUL_RID]]); 394 395val REAL_LE_INV2 = store_thm ("REAL_LE_INV2", 396 ``!x y. &0:real < x /\ x <= y ==> inv(y) <= inv(x)``, 397 REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN 398 ASM_CASES_TAC ``x:real = y`` THEN ASM_REWRITE_TAC[] THEN 399 STRIP_TAC THEN DISJ1_TAC THEN MATCH_MP_TAC REAL_LT_INV2 THEN 400 ASM_REWRITE_TAC[]); 401 402val REAL_INV_1_LE = store_thm ("REAL_INV_1_LE", 403 ``!x:real. &0 < x /\ x <= &1 ==> &1 <= inv(x)``, 404 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_INV1] THEN 405 MATCH_MP_TAC REAL_LE_INV2 THEN ASM_REWRITE_TAC[REAL_LT_01]); 406 407val SUM_GP_BASIC = store_thm ("SUM_GP_BASIC", 408 ``!x:real n:num. (&1 - x) * sum((0:num)..n) (\i. x pow i) = &1 - x pow (SUC n)``, 409 GEN_TAC THEN INDUCT_TAC THEN SIMP_TAC std_ss [SUM_CLAUSES_NUMSEG] THEN 410 SIMP_TAC std_ss [pow, REAL_MUL_RID, ZERO_LESS_EQ, POW_1] THEN 411 ASM_REWRITE_TAC[REAL_ADD_LDISTRIB, pow] THEN REAL_ARITH_TAC); 412 413val SUM_GP_MULTIPLIED = store_thm ("SUM_GP_MULTIPLIED", 414 ``!x m n. m <= n 415 ==> ((&1 - x) * sum(m..n) (\i. x pow i) = x pow m - x pow (SUC n))``, 416 REPEAT STRIP_TAC THEN 417 KNOW_TAC ``((1 :real) - (x :real)) * 418 sum ((0 :num) .. (n :num - m)) (\i. (\(i :num). x pow i) (i + m)) = 419 x pow m - x pow SUC n`` THENL [ALL_TAC, METIS_TAC [SUM_OFFSET_0]] THEN 420 ASM_SIMP_TAC std_ss 421 [REAL_POW_ADD, REAL_MUL_ASSOC, SUM_GP_BASIC, SUM_RMUL] THEN 422 SIMP_TAC std_ss [REAL_SUB_RDISTRIB, GSYM REAL_POW_ADD, REAL_MUL_LID] THEN 423 ASM_SIMP_TAC std_ss [ARITH_PROVE ``m <= n ==> (SUC(n - m) + m = SUC n)``]); 424 425val SUM_GP = store_thm ("SUM_GP", 426 ``!x m n. 427 sum(m..n) (\i. x pow i) = 428 if n < m then &0 429 else if x = &1 then &((n + 1) - m) 430 else (x pow m - x pow (SUC n)) / (&1 - x)``, 431 REPEAT GEN_TAC THEN 432 DISJ_CASES_TAC(ARITH_PROVE ``n < m \/ ~(n < m) /\ m <= n:num``) THEN 433 ASM_SIMP_TAC std_ss [SUM_TRIV_NUMSEG] THEN COND_CASES_TAC THENL 434 [ASM_REWRITE_TAC[POW_ONE, SUM_CONST_NUMSEG, REAL_MUL_RID], ALL_TAC] THEN 435 MATCH_MP_TAC REAL_EQ_LMUL_IMP THEN EXISTS_TAC ``&1 - x:real`` THEN 436 ASM_SIMP_TAC std_ss [REAL_DIV_LMUL, REAL_SUB_0, SUM_GP_MULTIPLIED]); 437 438val SUMS_SYM = store_thm ("SUMS_SYM", 439 ``!s t:real->bool. {x + y | x IN s /\ y IN t} = {y + x | y IN t /\ x IN s}``, 440 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 441 MESON_TAC[REAL_ADD_SYM]); 442 443val SUM_ABS_TRIANGLE = store_thm ("SUM_ABS_TRIANGLE", 444 ``!s f b. FINITE s /\ sum s (\a. abs(f a)) <= b ==> abs(sum s f) <= b``, 445 METIS_TAC[SUM_ABS, REAL_LE_TRANS]); 446 447val IMAGE_SING = store_thm ("IMAGE_SING", 448 ``!f a. IMAGE f {a} = {f a}``, 449 SET_TAC []); 450 451val REAL_WLOG_LE = store_thm ("REAL_WLOG_LE", 452 ``(!x y:real. P x y <=> P y x) /\ (!x y. x <= y ==> P x y) ==> !x y. P x y``, 453 METIS_TAC[REAL_LE_TOTAL]); 454 455(* ------------------------------------------------------------------------- *) 456(* Pairwise property over sets and lists. *) 457(* ------------------------------------------------------------------------- *) 458 459val pairwise = new_definition ("pairwise", 460 ``pairwise r s <=> !x y. x IN s /\ y IN s /\ ~(x = y) ==> r x y``); 461 462val PAIRWISE_EMPTY = store_thm ("PAIRWISE_EMPTY", 463 ``!r. pairwise r {} <=> T``, 464 REWRITE_TAC[pairwise, NOT_IN_EMPTY] THEN MESON_TAC[]); 465 466val PAIRWISE_SING = store_thm ("PAIRWISE_SING", 467 ``!r x. pairwise r {x} <=> T``, 468 REWRITE_TAC[pairwise, IN_SING] THEN MESON_TAC[]); 469 470val PAIRWISE_MONO = store_thm ("PAIRWISE_MONO", 471 ``!r s t. pairwise r s /\ t SUBSET s ==> pairwise r t``, 472 REWRITE_TAC[pairwise] THEN SET_TAC[]); 473 474val PAIRWISE_INSERT = store_thm ("PAIRWISE_INSERT", 475 ``!r x s. 476 pairwise r (x INSERT s) <=> 477 (!y. y IN s /\ ~(y = x) ==> r x y /\ r y x) /\ 478 pairwise r s``, 479 REWRITE_TAC[pairwise, IN_INSERT] THEN MESON_TAC[]); 480 481val PAIRWISE_IMAGE = store_thm ("PAIRWISE_IMAGE", 482 ``!r f. pairwise r (IMAGE f s) <=> 483 pairwise (\x y. ~(f x = f y) ==> r (f x) (f y)) s``, 484 REWRITE_TAC[pairwise, IN_IMAGE] THEN MESON_TAC[]); 485 486(* ------------------------------------------------------------------------- *) 487(* Permutes *) 488(* ------------------------------------------------------------------------- *) 489 490val _ = set_fixity "permutes" (Infix(NONASSOC, 450)); 491 492val permutes = new_definition ("permutes", 493 ``p permutes s <=> (!x. ~(x IN s) ==> (p(x) = x)) /\ (!y. ?!x. (p x = y))``); 494 495val PERMUTES_IMAGE = store_thm ("PERMUTES_IMAGE", 496 ``!p s. p permutes s ==> (IMAGE p s = s)``, 497 REWRITE_TAC[permutes, EXTENSION, IN_IMAGE] THEN MESON_TAC[]); 498 499val PERMUTES_INJECTIVE = store_thm ("PERMUTES_INJECTIVE", 500 ``!p s. p permutes s ==> !x y. (p(x) = p(y)) <=> (x = y)``, 501 REWRITE_TAC[permutes] THEN MESON_TAC[]); 502 503val EXISTS_IN_INSERT = store_thm ("EXISTS_IN_INSERT", 504 ``!P a s. (?x. x IN (a INSERT s) /\ P x) <=> P a \/ ?x. x IN s /\ P x``, 505 REWRITE_TAC[IN_INSERT] THEN MESON_TAC[]); 506 507val DEPENDENT_CHOICE_FIXED = store_thm ("DEPENDENT_CHOICE_FIXED", 508 ``!P R a:'a. P 0 a /\ (!n x. P n x ==> ?y. P (SUC n) y /\ R n x y) ==> 509 ?f. (f 0 = a) /\ (!n. P n (f n)) /\ (!n. R n (f n) (f(SUC n)))``, 510 REPEAT STRIP_TAC THEN KNOW_TAC ``(?f. (f 0 = (a:'a)) /\ 511 (!n. f(SUC n) = (@y. P (SUC n) y /\ R n (f n) y)))`` THENL 512 [RW_TAC std_ss [num_Axiom], ALL_TAC] THEN 513 STRIP_TAC THEN EXISTS_TAC ``f:num->'a`` THEN ASM_REWRITE_TAC [] THEN 514 ONCE_REWRITE_TAC[METIS [] ``(!n. P n (f n)) = (!n. (\n. P n (f n)) n)``] THEN 515 GEN_REWR_TAC LAND_CONV 516 [MESON[num_CASES] ``(!n. P n) <=> P 0 /\ !n. P(SUC n)``] THEN 517 ASM_SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN INDUCT_TAC THEN METIS_TAC[]); 518 519val DEPENDENT_CHOICE = store_thm ("DEPENDENT_CHOICE", 520 ``!P R:num->'a->'a->bool. (?a. P 0 a) /\ 521 (!n x. P n x ==> ?y. P (SUC n) y /\ R n x y) ==> 522 ?f. (!n. P n (f n)) /\ (!n. R n (f n) (f(SUC n)))``, 523 MESON_TAC[DEPENDENT_CHOICE_FIXED]); 524 525val BIGUNION_MONO_IMAGE = store_thm ("BIGUNION_MONO_IMAGE", 526 ``(!x. x IN s ==> f x SUBSET g x) ==> 527 BIGUNION(IMAGE f s) SUBSET BIGUNION(IMAGE g s)``, 528 SET_TAC[]); 529 530val BIGUNION_MONO = store_thm ("BIGUNION_MONO", 531 ``(!x. x IN s ==> ?y. y IN t /\ x SUBSET y) ==> BIGUNION s SUBSET BIGUNION t``, 532 SET_TAC[]); 533 534val th = REWRITE_RULE[IN_UNIV] (ISPECL [``f:'a->'b``, ``UNIV:'a->bool``] INJECTIVE_ON_LEFT_INVERSE); 535 536val REAL_WLOG_LT = store_thm ("REAL_WLOG_LT", 537 ``(!x. P x x) /\ (!x y. P x y <=> P y x) /\ (!x y. x < y ==> P x y) 538 ==> !x y:real. P x y``, 539 METIS_TAC[REAL_LT_TOTAL]); 540 541(* ------------------------------------------------------------------------- *) 542(* Metric function. (TODO: merge with metricTheory) *) 543(* ------------------------------------------------------------------------- *) 544 545val dist = new_definition ("dist", 546 ``Dist(x:real,y:real) = abs(x - y)``); 547 548val _ = overload_on ("dist",``Dist``); 549 550val DIST_REFL = store_thm ("DIST_REFL", 551 ``!x. dist(x,x) = &0``, 552 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 553 554val DIST_SYM = store_thm ("DIST_SYM", 555 ``!x y. dist(x,y) = dist(y,x)``, 556 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 557 558val DIST_TRIANGLE = store_thm ("DIST_TRIANGLE", 559 ``!x:real y z. dist(x,z) <= dist(x,y) + dist(y,z)``, 560 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 561 562val DIST_TRIANGLE_ALT = store_thm ("DIST_TRIANGLE_ALT", 563 ``!x y z. dist(y,z) <= dist(x,y) + dist(x,z)``, 564 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 565 566val DIST_EQ_0 = store_thm ("DIST_EQ_0", 567 ``!x y. (dist(x,y) = 0:real) <=> (x = y)``, 568 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 569 570val DIST_POS_LT = store_thm ("DIST_POS_LT", 571 ``!x y. ~(x = y) ==> &0 < dist(x,y)``, 572 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 573 574val DIST_NZ = store_thm ("DIST_NZ", 575 ``!x y. ~(x = y) <=> &0 < dist(x,y)``, 576 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 577 578val DIST_TRIANGLE_LE = store_thm ("DIST_TRIANGLE_LE", 579 ``!x y z e. dist(x,z) + dist(y,z) <= e ==> dist(x,y) <= e``, 580 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 581 582val DIST_TRIANGLE_LT = store_thm ("DIST_TRIANGLE_LT", 583 ``!x y z e. dist(x,z) + dist(y,z) < e ==> dist(x,y) < e``, 584 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 585 586val DIST_TRIANGLE_HALF_L = store_thm ("DIST_TRIANGLE_HALF_L", 587 ``!x1 x2 y. dist(x1,y) < e / &2 /\ dist(x2,y) < e / &2 ==> dist(x1,x2) < e``, 588 REPEAT STRIP_TAC THEN KNOW_TAC `` dist (x1,y) + dist (x2,y) < e`` THENL 589 [METIS_TAC [REAL_LT_ADD2, REAL_HALF_DOUBLE], 590 DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 591 EXISTS_TAC ``dist (x1,y) + dist (x2,y)`` THEN 592 METIS_TAC [DIST_TRIANGLE, DIST_SYM]]); 593 594val DIST_TRIANGLE_HALF_R = store_thm ("DIST_TRIANGLE_HALF_R", 595 ``!x1 x2 y. dist(y,x1) < e / &2 /\ dist(y,x2) < e / &2 ==> dist(x1,x2) < e``, 596 REPEAT STRIP_TAC THEN KNOW_TAC `` dist (y, x1) + dist (y, x2) < e`` THENL 597 [METIS_TAC [REAL_LT_ADD2, REAL_HALF_DOUBLE], 598 DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 599 EXISTS_TAC ``dist (y, x1) + dist (y, x2)`` THEN 600 METIS_TAC [DIST_TRIANGLE, DIST_SYM]]); 601 602val DIST_TRIANGLE_ADD = store_thm ("DIST_TRIANGLE_ADD", 603 ``!x x' y y'. dist(x + y,x' + y') <= dist(x,x') + dist(y,y')``, 604 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 605 606val DIST_MUL = store_thm ("DIST_MUL", 607 ``!x y c. dist(c * x,c * y) = abs(c) * dist(x,y)``, 608 REWRITE_TAC[dist, GSYM ABS_MUL] THEN REAL_ARITH_TAC); 609 610val DIST_TRIANGLE_ADD_HALF = store_thm ("DIST_TRIANGLE_ADD_HALF", 611 ``!x x' y y':real. 612 dist(x,x') < e / &2 /\ dist(y,y') < e / &2 ==> dist(x + y,x' + y') < e``, 613 REPEAT STRIP_TAC THEN KNOW_TAC `` dist (x, x') + dist (y, y') < e`` THENL 614 [METIS_TAC [REAL_LT_ADD2, REAL_HALF_DOUBLE], 615 DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 616 EXISTS_TAC ``dist (x, x') + dist (y, y')`` THEN 617 METIS_TAC [DIST_TRIANGLE_ADD, DIST_SYM]]); 618 619val DIST_LE_0 = store_thm ("DIST_LE_0", 620 ``!x y. dist(x,y) <= &0 <=> (x = y)``, 621 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 622 623val DIST_POS_LE = store_thm ("DIST_POS_LE", 624 ``!x y. &0 <= dist(x,y)``, 625 METIS_TAC [DIST_EQ_0, DIST_NZ, REAL_LE_LT]); 626 627val DIST_EQ = store_thm ("DIST_EQ", 628 ``!w x y z. (dist(w,x) = dist(y,z)) <=> (dist(w,x) pow 2 = dist(y,z) pow 2)``, 629 REPEAT GEN_TAC THEN EQ_TAC THENL [RW_TAC std_ss [], 630 DISCH_TAC THEN MATCH_MP_TAC POW_EQ THEN EXISTS_TAC ``1:num`` THEN 631 RW_TAC arith_ss [DIST_POS_LE]]); 632 633val DIST_0 = store_thm ("DIST_0", 634 ``!x. (dist(x,0) = abs(x)) /\ (dist(0,x) = abs(x))``, 635 RW_TAC arith_ss [dist, REAL_SUB_RZERO, REAL_SUB_LZERO, ABS_NEG]); 636 637val REAL_CHOOSE_DIST = store_thm ("REAL_CHOOSE_DIST", 638 ``!x e. &0 <= e ==> (?y. dist (x,y) = e)``, 639 REPEAT STRIP_TAC THEN EXISTS_TAC ``x - e:real`` THEN 640 ASM_REWRITE_TAC [dist, REAL_SUB_SUB2, ABS_REFL]); 641 642(* ------------------------------------------------------------------------- *) 643(* Linear functions. *) 644(* ------------------------------------------------------------------------- *) 645 646val linear = new_definition ("linear", 647 ``linear (f:real->real) <=> 648 (!x y. f(x + y) = f(x) + f(y)) /\ 649 (!c x. f(c * x) = c * f(x))``); 650 651val LINEAR_SCALING = store_thm ("LINEAR_SCALING", 652 ``!c. linear(\x:real. c * x)``, 653 SIMP_TAC std_ss [linear] THEN REAL_ARITH_TAC); 654 655val LINEAR_COMPOSE_CMUL = store_thm ("LINEAR_COMPOSE_CMUL", 656 ``!f c. linear f ==> linear (\x. c * f(x))``, 657 SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 658 659val LINEAR_COMPOSE_NEG = store_thm ("LINEAR_COMPOSE_NEG", 660 ``!f. linear f ==> linear (\x. -(f(x)))``, 661 SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 662 663val LINEAR_COMPOSE_ADD = store_thm ("LINEAR_COMPOSE_ADD", 664 ``!f g. linear f /\ linear g ==> linear (\x. f(x) + g(x))``, 665 SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 666 667val LINEAR_COMPOSE_SUB = store_thm ("LINEAR_COMPOSE_SUB", 668 ``!f g. linear f /\ linear g ==> linear (\x. f(x) - g(x))``, 669 SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 670 671val LINEAR_COMPOSE = store_thm ("LINEAR_COMPOSE", 672 ``!f g. linear f /\ linear g ==> linear (g o f)``, 673 SIMP_TAC std_ss [linear, o_THM]); 674 675val LINEAR_ID = store_thm ("LINEAR_ID", 676 ``linear (\x. x)``, 677 SIMP_TAC std_ss [linear]); 678 679val LINEAR_ZERO = store_thm ("LINEAR_ZERO", 680 ``linear (\x. 0)``, 681 SIMP_TAC std_ss [linear] THEN CONJ_TAC THEN REAL_ARITH_TAC); 682 683val LINEAR_NEGATION = store_thm ("LINEAR_NEGATION", 684 ``linear (\x. -x)``, 685 SIMP_TAC std_ss [linear] THEN REAL_ARITH_TAC); 686 687val LINEAR_COMPOSE_SUM = store_thm ("LINEAR_COMPOSE_SUM", 688 ``!f s. FINITE s /\ (!a. a IN s ==> linear(f a)) 689 ==> linear(\x. sum s (\a. f a x))``, 690 GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN GEN_TAC THEN 691 KNOW_TAC ``((!a. a IN s ==> linear (f a)) ==> linear (\x. sum s (\a. f a x))) = 692 (\s. (!a. a IN s ==> linear (f a)) ==> linear (\x. sum s (\a. f a x))) s`` THENL 693 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 694 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 695 SIMP_TAC std_ss [SUM_CLAUSES, LINEAR_ZERO] THEN REPEAT STRIP_TAC THEN 696 KNOW_TAC ``(linear (\x. f e x + sum s (\a. f a x))) = 697 linear (\x. (\x. f e x) x + (\x. sum s (\a. f a x)) x)`` THENL 698 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 699 MATCH_MP_TAC LINEAR_COMPOSE_ADD THEN METIS_TAC [IN_INSERT]); 700 701val LINEAR_MUL_COMPONENT = store_thm ("LINEAR_MUL_COMPONENT", 702 ``!f:real->real v. 703 linear f ==> linear (\x. f(x) * v)``, 704 SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 705 706val LINEAR_0 = store_thm ("LINEAR_0", 707 ``!f. linear f ==> (f(0) = 0)``, 708 METIS_TAC [REAL_MUL_LZERO, linear]); 709 710val LINEAR_CMUL = store_thm ("LINEAR_CMUL", 711 ``!f c x. linear f ==> (f(c * x) = c * f(x))``, 712 SIMP_TAC std_ss [linear]); 713 714val LINEAR_NEG = store_thm ("LINEAR_NEG", 715 ``!f x. linear f ==> (f(-x) = -(f x))``, 716 ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN SIMP_TAC std_ss [LINEAR_CMUL]); 717 718val LINEAR_ADD = store_thm ("LINEAR_ADD", 719 ``!f x y. linear f ==> (f(x + y) = f(x) + f(y))``, 720 SIMP_TAC std_ss [linear]); 721 722val LINEAR_SUB = store_thm ("LINEAR_SUB", 723 ``!f x y. linear f ==> (f(x - y) = f(x) - f(y))``, 724 SIMP_TAC std_ss [real_sub, LINEAR_ADD, LINEAR_NEG]); 725 726val LINEAR_SUM = store_thm ("LINEAR_SUM", 727 ``!f g s. linear f /\ FINITE s ==> (f(sum s g) = sum s (f o g))``, 728 GEN_TAC THEN GEN_TAC THEN SIMP_TAC std_ss [GSYM AND_IMP_INTRO, RIGHT_FORALL_IMP_THM] THEN 729 DISCH_TAC THEN GEN_TAC THEN 730 KNOW_TAC ``(f (sum s g) = sum s (f o g)) = 731 (\s. (f (sum s g) = sum s (f o g))) s`` THENL 732 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 733 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 734 SIMP_TAC std_ss [SUM_CLAUSES] THEN FIRST_ASSUM(fn th => 735 SIMP_TAC std_ss [MATCH_MP LINEAR_0 th, MATCH_MP LINEAR_ADD th, o_THM])); 736 737val LINEAR_SUM_MUL = store_thm ("LINEAR_SUM_MUL", 738 ``!f s c v. 739 linear f /\ FINITE s 740 ==> (f(sum s (\i. c i * v i)) = sum s (\i. c(i) * f(v i)))``, 741 SIMP_TAC std_ss [LINEAR_SUM, o_DEF, LINEAR_CMUL]); 742 743val lemma = prove ( 744 ``x = sum (1:num..1:num) (\i. x * &i)``, 745 REWRITE_TAC [SUM_SING_NUMSEG] THEN BETA_TAC THEN REAL_ARITH_TAC); 746 747val LINEAR_BOUNDED = store_thm ("LINEAR_BOUNDED", 748 ``!f:real->real. linear f ==> ?B. !x. abs(f x) <= B * abs(x)``, 749 REPEAT STRIP_TAC THEN EXISTS_TAC 750 ``sum(1:num..1:num) (\i. abs((f:real->real)(&i)))`` THEN 751 GEN_TAC THEN 752 GEN_REWR_TAC (LAND_CONV o funpow 2 RAND_CONV) [lemma] THEN 753 ASM_SIMP_TAC std_ss [LINEAR_SUM, FINITE_NUMSEG] THEN 754 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN 755 MATCH_MP_TAC SUM_ABS_LE THEN REWRITE_TAC [FINITE_NUMSEG, IN_NUMSEG] THEN 756 BETA_TAC THEN ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN 757 ASM_SIMP_TAC std_ss [o_DEF, ABS_MUL, LINEAR_CMUL] THEN 758 METIS_TAC [REAL_LE_RMUL, ABS_POS, REAL_LE_LT, REAL_MUL_COMM]); 759 760val LINEAR_BOUNDED_POS = store_thm ("LINEAR_BOUNDED_POS", 761 ``!f:real->real. linear f ==> ?B. &0 < B /\ !x. abs(f x) <= B * abs(x)``, 762 REPEAT STRIP_TAC THEN 763 FIRST_ASSUM(X_CHOOSE_TAC ``B:real`` o MATCH_MP LINEAR_BOUNDED) THEN 764 EXISTS_TAC ``abs(B) + &1:real`` THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN 765 GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x:real`) THEN 766 MATCH_MP_TAC(REAL_ARITH ``a <= b ==> x <= a ==> x <= b:real``) THEN 767 MATCH_MP_TAC REAL_LE_RMUL_IMP THEN REWRITE_TAC[ABS_POS] THEN 768 REAL_ARITH_TAC); 769 770val SYMMETRIC_LINEAR_IMAGE = store_thm ("SYMMETRIC_LINEAR_IMAGE", 771 ``!f s. (!x. x IN s ==> -x IN s) /\ linear f 772 ==> !x. x IN (IMAGE f s) ==> -x IN (IMAGE f s)``, 773 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 774 SIMP_TAC std_ss [GSYM LINEAR_NEG] THEN SET_TAC[]); 775 776(* ------------------------------------------------------------------------- *) 777(* Bilinear functions. *) 778(* ------------------------------------------------------------------------- *) 779 780val bilinear = new_definition ("bilinear", 781 ``bilinear f <=> (!x. linear(\y. f x y)) /\ (!y. linear(\x. f x y))``); 782 783val BILINEAR_SWAP = store_thm ("BILINEAR_SWAP", 784 ``!op:real->real->real. 785 bilinear(\x y. op y x) <=> bilinear op``, 786 SIMP_TAC std_ss [bilinear, ETA_AX] THEN METIS_TAC[]); 787 788val BILINEAR_LADD = store_thm ("BILINEAR_LADD", 789 ``!h x y z. bilinear h ==> (h (x + y) z = (h x z) + (h y z))``, 790 SIMP_TAC std_ss [bilinear, linear]); 791 792val BILINEAR_RADD = store_thm ("BILINEAR_RADD", 793 ``!h x y z. bilinear h ==> (h x (y + z) = (h x y) + (h x z))``, 794 SIMP_TAC std_ss [bilinear, linear]); 795 796val BILINEAR_LMUL = store_thm ("BILINEAR_LMUL", 797 ``!h c x y. bilinear h ==> (h (c * x) y = c * (h x y))``, 798 SIMP_TAC std_ss [bilinear, linear]); 799 800val BILINEAR_RMUL = store_thm ("BILINEAR_RMUL", 801 ``!h c x y. bilinear h ==> (h x (c * y) = c * (h x y))``, 802 SIMP_TAC std_ss [bilinear, linear]); 803 804val BILINEAR_LNEG = store_thm ("BILINEAR_LNEG", 805 ``!h x y. bilinear h ==> (h (-x) y = -(h x y))``, 806 ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN SIMP_TAC std_ss [BILINEAR_LMUL]); 807 808val BILINEAR_RNEG = store_thm ("BILINEAR_RNEG", 809 ``!h x y. bilinear h ==> (h x (-y) = -(h x y))``, 810 ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN SIMP_TAC std_ss [BILINEAR_RMUL]); 811 812val BILINEAR_LZERO = store_thm ("BILINEAR_LZERO", 813 ``!h x. bilinear h ==> (h (0) x = 0)``, 814 ONCE_REWRITE_TAC[REAL_ARITH ``(x = 0:real) <=> (x + x = x)``] THEN 815 SIMP_TAC std_ss [GSYM BILINEAR_LADD, REAL_ADD_LID]); 816 817val BILINEAR_RZERO = store_thm ("BILINEAR_RZERO", 818 ``!h x. bilinear h ==> (h x (0) = 0)``, 819 ONCE_REWRITE_TAC[REAL_ARITH ``(x = 0:real) <=> (x + x = x)``] THEN 820 SIMP_TAC std_ss [GSYM BILINEAR_RADD, REAL_ADD_LID]); 821 822val BILINEAR_LSUB = store_thm ("BILINEAR_LSUB", 823 ``!h x y z. bilinear h ==> (h (x - y) z = (h x z) - (h y z))``, 824 SIMP_TAC std_ss [real_sub, BILINEAR_LNEG, BILINEAR_LADD]); 825 826val BILINEAR_RSUB = store_thm ("BILINEAR_RSUB", 827 ``!h x y z. bilinear h ==> (h x (y - z) = (h x y) - (h x z))``, 828 SIMP_TAC std_ss [real_sub, BILINEAR_RNEG, BILINEAR_RADD]); 829 830val lemma = prove ( 831 ``!s t. s CROSS t = {(x,y) | x IN s /\ y IN t}``, 832 REWRITE_TAC [CROSS_DEF] THEN 833 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD]); 834 835val BILINEAR_SUM = store_thm ("BILINEAR_SUM", 836 ``!h:real->real->real. 837 bilinear h /\ FINITE s /\ FINITE t 838 ==> (h (sum s f) (sum t g) = sum (s CROSS t) (\(i,j). h (f i) (g j)))``, 839 REPEAT GEN_TAC THEN REWRITE_TAC [bilinear] THEN 840 KNOW_TAC ``(!x. linear (\y. h:real->real->real x y)) = (!x. linear (h x))`` THENL 841 [METIS_TAC [ETA_AX], ALL_TAC] THEN DISC_RW_KILL THEN 842 ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> (a /\ d) /\ (b /\ c)`] THEN 843 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN 844 KNOW_TAC ``((!y. linear (\x. h:real->real->real x y)) /\ FINITE s) = 845 ((!y. linear (\x. h x y) /\ FINITE s))`` THENL 846 [SIMP_TAC std_ss [LEFT_AND_FORALL_THM], ALL_TAC] THEN 847 DISC_RW_KILL THEN DISCH_TAC THEN 848 FIRST_ASSUM(MP_TAC o GEN_ALL o MATCH_MP LINEAR_SUM o SPEC_ALL) THEN 849 SIMP_TAC std_ss [] THEN 850 ASM_SIMP_TAC std_ss [LINEAR_SUM, o_DEF, SUM_SUM_PRODUCT] THEN 851 SIMP_TAC std_ss [lemma]); 852 853val lemma = prove ( 854 ``!x. x = sum (1:num..1:num) (\i. x * &i)``, 855 REWRITE_TAC [SUM_SING_NUMSEG] THEN BETA_TAC THEN REAL_ARITH_TAC); 856 857val BILINEAR_BOUNDED = store_thm ("BILINEAR_BOUNDED", 858 ``!h:real->real->real. 859 bilinear h ==> ?B. !x y. abs(h x y) <= B * abs(x) * abs(y)``, 860 REPEAT STRIP_TAC THEN 861 EXISTS_TAC ``sum ((1:num..1:num) CROSS (1:num..1:num)) 862 (\ (i,j). abs((h:real->real->real) 863 (&i) (&j)))`` THEN 864 REPEAT GEN_TAC THEN GEN_REWR_TAC 865 (LAND_CONV o RAND_CONV o BINOP_CONV) [lemma] THEN 866 ASM_SIMP_TAC std_ss [BILINEAR_SUM, FINITE_NUMSEG] THEN 867 ONCE_REWRITE_TAC [REAL_ARITH ``a * b * c = b * c * a:real``] THEN 868 REWRITE_TAC[GSYM SUM_LMUL] THEN MATCH_MP_TAC SUM_ABS_LE THEN 869 SIMP_TAC std_ss [FINITE_CROSS, FINITE_NUMSEG, FORALL_PROD, IN_CROSS] THEN 870 REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THEN 871 ASM_SIMP_TAC std_ss [BILINEAR_LMUL, ABS_MUL] THEN 872 ASM_SIMP_TAC std_ss [BILINEAR_RMUL, ABS_MUL, REAL_MUL_ASSOC] THEN 873 METIS_TAC [REAL_LE_LT]); 874 875val BILINEAR_BOUNDED_POS = store_thm ("BILINEAR_BOUNDED_POS", 876 ``!h. bilinear h 877 ==> ?B. &0 < B /\ !x y. abs(h x y) <= B * abs(x) * abs(y)``, 878 REPEAT STRIP_TAC THEN 879 FIRST_ASSUM(X_CHOOSE_TAC ``B:real`` o MATCH_MP BILINEAR_BOUNDED) THEN 880 EXISTS_TAC ``abs(B) + &1:real`` THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN 881 REPEAT GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPECL [`x:real`, `y:real`]) THEN 882 MATCH_MP_TAC(REAL_ARITH ``a <= b ==> x <= a ==> x <= b:real``) THEN 883 REPEAT(MATCH_MP_TAC REAL_LE_RMUL_IMP THEN 884 SIMP_TAC std_ss [ABS_POS, REAL_LE_MUL]) THEN 885 REAL_ARITH_TAC); 886 887val BILINEAR_SUM_PARTIAL_SUC = store_thm ("BILINEAR_SUM_PARTIAL_SUC", 888 ``!f g h:real->real->real m n. 889 bilinear h 890 ==> (sum (m..n) (\k. h (f k) (g(k + 1) - g(k))) = 891 if m <= n then h (f(n + 1)) (g(n + 1)) - h (f m) (g m) - 892 sum (m..n) (\k. h (f(k + 1) - f(k)) (g(k + 1))) 893 else 0)``, 894 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN 895 GEN_TAC THEN INDUCT_TAC THEN 896 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [SUM_TRIV_NUMSEG, NOT_LESS_EQ] THEN 897 ASM_REWRITE_TAC[SUM_CLAUSES_NUMSEG] THENL 898 [COND_CASES_TAC THEN ASM_SIMP_TAC arith_ss [] THENL 899 [ASM_SIMP_TAC std_ss [BILINEAR_RSUB, BILINEAR_LSUB] THEN REAL_ARITH_TAC, 900 FULL_SIMP_TAC std_ss [bilinear, linear]], FULL_SIMP_TAC std_ss [bilinear, linear], 901 POP_ASSUM MP_TAC THEN REWRITE_TAC [LE] THEN 902 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THENL [ALL_TAC, ASM_REWRITE_TAC []] THEN 903 ASM_SIMP_TAC std_ss [GSYM NOT_LESS, SUM_TRIV_NUMSEG, ARITH_PROVE ``n < SUC n``] THEN 904 ASM_SIMP_TAC std_ss [GSYM ADD1, ADD_CLAUSES] THEN 905 ASM_SIMP_TAC std_ss [BILINEAR_RSUB, BILINEAR_LSUB] THEN REAL_ARITH_TAC, 906 ALL_TAC] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC [LE] THEN 907 REWRITE_TAC [DE_MORGAN_THM] THEN 908 ASM_SIMP_TAC std_ss [GSYM NOT_LESS, SUM_TRIV_NUMSEG, ARITH_PROVE ``n < SUC n``] THEN 909 ASM_SIMP_TAC std_ss [GSYM ADD1, ADD_CLAUSES] THEN 910 ASM_SIMP_TAC std_ss [BILINEAR_RSUB, BILINEAR_LSUB] THEN REAL_ARITH_TAC); 911 912val BILINEAR_SUM_PARTIAL_PRE = store_thm ("BILINEAR_SUM_PARTIAL_PRE", 913 ``!f g h:real->real->real m n. 914 bilinear h 915 ==> (sum (m..n) (\k. h (f k) (g(k) - g(k - 1))) = 916 if m <= n then h (f(n + 1)) (g(n)) - h (f m) (g(m - 1)) - 917 sum (m..n) (\k. h (f(k + 1) - f(k)) (g(k))) 918 else 0)``, 919 REPEAT STRIP_TAC THEN 920 FIRST_ASSUM(MP_TAC o ISPECL [``f:num->real``, ``\k. (g:num->real)(k - 1)``, 921 ``m:num``, ``n:num``] o MATCH_MP BILINEAR_SUM_PARTIAL_SUC) THEN 922 BETA_TAC THEN REWRITE_TAC[ADD_SUB] THEN DISCH_THEN SUBST1_TAC THEN 923 COND_CASES_TAC THEN REWRITE_TAC[]); 924 925(* ------------------------------------------------------------------------- *) 926(* A bit of linear algebra. *) 927(* ------------------------------------------------------------------------- *) 928 929val subspace = new_definition ("subspace", 930 ``subspace s <=> 931 (0:real) IN s /\ 932 (!x y. x IN s /\ y IN s ==> (x + y) IN s) /\ 933 (!c x. x IN s ==> (c * x) IN s)``); 934 935val span = new_definition ("span", 936 ``span s = subspace hull s``); 937 938val dependent = new_definition ("dependent", 939 ``dependent s <=> ?a. a IN s /\ a IN span(s DELETE a)``); 940 941val independent = new_definition ("independent", 942 ``independent s <=> ~(dependent s)``); 943 944(* ------------------------------------------------------------------------- *) 945(* Closure properties of subspaces. *) 946(* ------------------------------------------------------------------------- *) 947 948val SUBSPACE_UNIV = store_thm ("SUBSPACE_UNIV", 949 ``subspace(UNIV:real->bool)``, 950 REWRITE_TAC[subspace, IN_UNIV]); 951 952val SUBSPACE_IMP_NONEMPTY = store_thm ("SUBSPACE_IMP_NONEMPTY", 953 ``!s. subspace s ==> ~(s = {})``, 954 REWRITE_TAC[subspace] THEN SET_TAC[]); 955 956val SUBSPACE_0 = store_thm ("SUBSPACE_0", 957 ``subspace s ==> (0:real) IN s``, 958 SIMP_TAC std_ss [subspace]); 959 960val SUBSPACE_ADD = store_thm ("SUBSPACE_ADD", 961 ``!x y s. subspace s /\ x IN s /\ y IN s ==> (x + y) IN s``, 962 SIMP_TAC std_ss [subspace]); 963 964val SUBSPACE_MUL = store_thm ("SUBSPACE_MUL", 965 ``!x c s. subspace s /\ x IN s ==> (c * x) IN s``, 966 SIMP_TAC std_ss [subspace]); 967 968val SUBSPACE_NEG = store_thm ("SUBSPACE_NEG", 969 ``!x s. subspace s /\ x IN s ==> (-x) IN s``, 970 METIS_TAC [REAL_ARITH ``-x = -(&1) * x:real``, SUBSPACE_MUL]); 971 972val SUBSPACE_SUB = store_thm ("SUBSPACE_SUB", 973 ``!x y s. subspace s /\ x IN s /\ y IN s ==> (x - y) IN s``, 974 SIMP_TAC std_ss [real_sub, SUBSPACE_ADD, SUBSPACE_NEG]); 975 976val SUBSPACE_SUM = store_thm ("SUBSPACE_SUM", 977 ``!s f t. subspace s /\ FINITE t /\ (!x. x IN t ==> f(x) IN s) 978 ==> (sum t f) IN s``, 979 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 980 GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN 981 ONCE_REWRITE_TAC [METIS [] ``!t. ((!x. x IN t ==> f x IN s) ==> sum t f IN s) = 982 (\t. (!x. x IN t ==> f x IN s) ==> sum t f IN s) t``] THEN 983 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 984 ASM_SIMP_TAC std_ss [SUM_CLAUSES, SUBSPACE_0, IN_INSERT, SUBSPACE_ADD]); 985 986val SUBSPACE_LINEAR_IMAGE = store_thm ("SUBSPACE_LINEAR_IMAGE", 987 ``!f s. linear f /\ subspace s ==> subspace(IMAGE f s)``, 988 SIMP_TAC std_ss [subspace, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 989 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN 990 METIS_TAC [linear, LINEAR_0]); 991 992val SUBSPACE_LINEAR_PREIMAGE = store_thm ("SUBSPACE_LINEAR_PREIMAGE", 993 ``!f s. linear f /\ subspace s ==> subspace {x | f(x) IN s}``, 994 SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN 995 METIS_TAC [linear, LINEAR_0]); 996 997val SUBSPACE_TRIVIAL = store_thm ("SUBSPACE_TRIVIAL", 998 ``subspace {0}``, 999 SIMP_TAC std_ss [subspace, IN_SING] THEN CONJ_TAC THEN REAL_ARITH_TAC); 1000 1001val SUBSPACE_INTER = store_thm ("SUBSPACE_INTER", 1002 ``!s t. subspace s /\ subspace t ==> subspace (s INTER t)``, 1003 REWRITE_TAC[subspace, IN_INTER] THEN METIS_TAC []); 1004 1005val SUBSPACE_BIGINTER = store_thm ("SUBSPACE_BIGINTER", 1006 ``!f. (!s. s IN f ==> subspace s) ==> subspace(BIGINTER f)``, 1007 SIMP_TAC std_ss [subspace, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, IN_BIGINTER]); 1008 1009val LINEAR_INJECTIVE_0_SUBSPACE = store_thm ("LINEAR_INJECTIVE_0_SUBSPACE", 1010 ``!f:real->real s. 1011 linear f /\ subspace s 1012 ==> ((!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) <=> 1013 (!x. x IN s /\ (f x = 0) ==> (x = 0)))``, 1014 REPEAT STRIP_TAC THEN 1015 GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_SUB_0] THEN 1016 ASM_SIMP_TAC std_ss [GSYM LINEAR_SUB] THEN 1017 METIS_TAC [REAL_SUB_RZERO, SUBSPACE_SUB, SUBSPACE_0]); 1018 1019val SUBSPACE_UNION_CHAIN = store_thm ("SUBSPACE_UNION_CHAIN", 1020 ``!s t:real->bool. 1021 subspace s /\ subspace t /\ subspace(s UNION t) 1022 ==> s SUBSET t \/ t SUBSET s``, 1023 REPEAT STRIP_TAC THEN REWRITE_TAC [SET_RULE 1024 ``s SUBSET t \/ t SUBSET s <=> 1025 ~(?x y. x IN s /\ ~(x IN t) /\ y IN t /\ ~(y IN s))``] THEN 1026 STRIP_TAC THEN SUBGOAL_THEN ``(x + y:real) IN (s UNION t)`` MP_TAC THENL 1027 [MATCH_MP_TAC SUBSPACE_ADD THEN ASM_REWRITE_TAC[] THEN ASM_SET_TAC[], 1028 REWRITE_TAC[IN_UNION, DE_MORGAN_THM] THEN 1029 METIS_TAC [SUBSPACE_SUB, REAL_ARITH 1030 ``((x + y) - x:real = y) /\ ((x + y) - y:real = x)``]]); 1031 1032(* ------------------------------------------------------------------------- *) 1033(* Lemmas. *) 1034(* ------------------------------------------------------------------------- *) 1035 1036val SPAN_SPAN = store_thm ("SPAN_SPAN", 1037 ``!s. span(span s) = span s``, 1038 REWRITE_TAC[span, HULL_HULL]); 1039 1040val SPAN_MONO = store_thm ("SPAN_MONO", 1041 ``!s t. s SUBSET t ==> span s SUBSET span t``, 1042 REWRITE_TAC[span, HULL_MONO]); 1043 1044val SUBSPACE_SPAN = store_thm ("SUBSPACE_SPAN", 1045 ``!s. subspace(span s)``, 1046 GEN_TAC THEN REWRITE_TAC[span] THEN MATCH_MP_TAC P_HULL THEN 1047 SIMP_TAC std_ss [subspace, IN_BIGINTER]); 1048 1049val SPAN_CLAUSES = store_thm ("SPAN_CLAUSES", 1050 ``(!a s. a IN s ==> a IN span s) /\ 1051 ((0) IN span s) /\ 1052 (!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s) /\ 1053 (!x c s. x IN span s ==> (c * x) IN span s)``, 1054 MESON_TAC[span, HULL_SUBSET, SUBSET_DEF, SUBSPACE_SPAN, subspace]); 1055 1056val SPAN_INDUCT = store_thm ("SPAN_INDUCT", 1057 ``!s h. (!x. x IN s ==> x IN h) /\ subspace h ==> !x. x IN span(s) ==> h(x)``, 1058 REWRITE_TAC[span] THEN MESON_TAC[SUBSET_DEF, HULL_MINIMAL, IN_DEF]); 1059 1060val SPAN_EMPTY = store_thm ("SPAN_EMPTY", 1061 ``span {} = {0}``, 1062 REWRITE_TAC[span] THEN MATCH_MP_TAC HULL_UNIQUE THEN 1063 SIMP_TAC std_ss [subspace, SUBSET_DEF, IN_SING, NOT_IN_EMPTY] THEN 1064 REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 1065 1066val INDEPENDENT_EMPTY = store_thm ("INDEPENDENT_EMPTY", 1067 ``independent {}``, 1068 REWRITE_TAC[independent, dependent, NOT_IN_EMPTY]); 1069 1070val INDEPENDENT_NONZERO = store_thm ("INDEPENDENT_NONZERO", 1071 ``!s. independent s ==> ~(0 IN s)``, 1072 REWRITE_TAC[independent, dependent] THEN MESON_TAC[SPAN_CLAUSES]); 1073 1074val INDEPENDENT_MONO = store_thm ("INDEPENDENT_MONO", 1075 ``!s t. independent t /\ s SUBSET t ==> independent s``, 1076 REWRITE_TAC[independent, dependent] THEN 1077 ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_DELETE]); 1078 1079val DEPENDENT_MONO = store_thm ("DEPENDENT_MONO", 1080 ``!s t:real->bool. dependent s /\ s SUBSET t ==> dependent t``, 1081 ONCE_REWRITE_TAC[TAUT `p /\ q ==> r <=> ~r /\ q ==> ~p`] THEN 1082 REWRITE_TAC[GSYM independent, INDEPENDENT_MONO]); 1083 1084val SPAN_SUBSPACE = store_thm ("SPAN_SUBSPACE", 1085 ``!b s. b SUBSET s /\ s SUBSET (span b) /\ subspace s ==> (span b = s)``, 1086 MESON_TAC[SUBSET_ANTISYM, span, HULL_MINIMAL]); 1087 1088val SPAN_INDUCT_ALT = store_thm ("SPAN_INDUCT_ALT", 1089 ``!s h. h(0) /\ 1090 (!c x y. x IN s /\ h(y) ==> h(c * x + y)) 1091 ==> !x:real. x IN span(s) ==> h(x)``, 1092 REPEAT GEN_TAC THEN DISCH_TAC THEN 1093 FIRST_ASSUM(MP_TAC o prove_nonschematic_inductive_relations_exist bool_monoset o concl) THEN 1094 DISCH_THEN(X_CHOOSE_THEN ``g:real->bool`` STRIP_ASSUME_TAC) THEN 1095 SUBGOAL_THEN ``!x:real. x IN span(s) ==> g(x)`` 1096 (fn th => METIS_TAC [th]) THEN 1097 MATCH_MP_TAC SPAN_INDUCT THEN SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN 1098 SIMP_TAC std_ss [IN_DEF, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 1099 ONCE_REWRITE_TAC [METIS [] ``(g x ==> g (c * x)) = (\c x:real. g x ==> g (c * x)) c x``] THEN 1100 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN 1101 REPEAT CONJ_TAC THENL 1102 [METIS_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM, 1103 REAL_MUL_LID, REAL_MUL_RZERO], 1104 METIS_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM, 1105 REAL_MUL_LID, REAL_MUL_RZERO], 1106 ONCE_REWRITE_TAC [METIS [] ``!x. (!y. g y ==> g (x + y)) = 1107 (\x. !y. g y ==> g (x + y)) (x:real)``] THEN 1108 FIRST_X_ASSUM MATCH_MP_TAC THEN 1109 SIMP_TAC std_ss [REAL_ADD_LDISTRIB, REAL_MUL_ASSOC] THEN 1110 ASM_MESON_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM, 1111 REAL_MUL_LID, REAL_MUL_RZERO], 1112 ONCE_REWRITE_TAC [METIS [] ``(!x. g (x * y)) = 1113 (\y.!x. g (x * y)) (y:real)``] THEN 1114 FIRST_X_ASSUM MATCH_MP_TAC THEN 1115 SIMP_TAC std_ss [REAL_ADD_LDISTRIB, REAL_MUL_ASSOC] THEN 1116 ASM_MESON_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM, 1117 REAL_MUL_LID, REAL_MUL_RZERO]]); 1118 1119(* ------------------------------------------------------------------------- *) 1120(* Individual closure properties. *) 1121(* ------------------------------------------------------------------------- *) 1122 1123val SPAN_SUPERSET = store_thm ("SPAN_SUPERSET", 1124 ``!x. x IN s ==> x IN span s``, 1125 MESON_TAC[SPAN_CLAUSES]); 1126 1127val SPAN_INC = store_thm ("SPAN_INC", 1128 ``!s. s SUBSET span s``, 1129 REWRITE_TAC[SUBSET_DEF, SPAN_SUPERSET]); 1130 1131val SPAN_UNION_SUBSET = store_thm ("SPAN_UNION_SUBSET", 1132 ``!s t. span s UNION span t SUBSET span(s UNION t)``, 1133 REWRITE_TAC[span, HULL_UNION_SUBSET]); 1134 1135val SPAN_UNIV = store_thm ("SPAN_UNIV", 1136 ``span univ(:real) = univ(:real)``, 1137 SIMP_TAC std_ss [SPAN_INC, SET_RULE ``UNIV SUBSET s ==> (s = UNIV)``]); 1138 1139val SPAN_0 = store_thm ("SPAN_0", 1140 ``(0) IN span s``, 1141 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_0]); 1142 1143val SPAN_ADD = store_thm ("SPAN_ADD", 1144 ``!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s``, 1145 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_ADD]); 1146 1147val SPAN_MUL = store_thm ("SPAN_MUL", 1148 ``!x c s. x IN span s ==> (c * x) IN span s``, 1149 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_MUL]); 1150 1151val SPAN_MUL_EQ = store_thm ("SPAN_MUL_EQ", 1152 ``!x:real c s. ~(c = &0) ==> ((c * x) IN span s <=> x IN span s)``, 1153 REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN ASM_SIMP_TAC std_ss [SPAN_MUL] THEN 1154 SUBGOAL_THEN ``(inv(c) * c * x:real) IN span s`` MP_TAC THENL 1155 [REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC std_ss [SPAN_MUL], 1156 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID]]); 1157 1158val SPAN_NEG = store_thm ("SPAN_NEG", 1159 ``!x s. x IN span s ==> (-x) IN span s``, 1160 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_NEG]); 1161 1162val SPAN_NEG_EQ = store_thm ("SPAN_NEG_EQ", 1163 ``!x s. -x IN span s <=> x IN span s``, 1164 MESON_TAC[SPAN_NEG, REAL_NEG_NEG]); 1165 1166val SPAN_SUB = store_thm ("SPAN_SUB", 1167 ``!x y s. x IN span s /\ y IN span s ==> (x - y) IN span s``, 1168 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_SUB]); 1169 1170val SPAN_SUM = store_thm ("SPAN_SUM", 1171 ``!s f t. FINITE t /\ (!x. x IN t ==> f(x) IN span(s)) 1172 ==> (sum t f) IN span(s)``, 1173 MESON_TAC[SUBSPACE_SPAN, SUBSPACE_SUM]); 1174 1175val SPAN_ADD_EQ = store_thm ("SPAN_ADD_EQ", 1176 ``!s x y. x IN span s ==> ((x + y) IN span s <=> y IN span s)``, 1177 MESON_TAC[SPAN_ADD, SPAN_SUB, REAL_ARITH ``(x + y) - x:real = y``]); 1178 1179val SPAN_EQ_SELF = store_thm ("SPAN_EQ_SELF", 1180 ``!s. (span s = s) <=> subspace s``, 1181 GEN_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSPACE_SPAN], ALL_TAC] THEN 1182 DISCH_TAC THEN MATCH_MP_TAC SPAN_SUBSPACE THEN 1183 ASM_REWRITE_TAC[SUBSET_REFL, SPAN_INC]); 1184 1185val SPAN_SUBSET_SUBSPACE = store_thm ("SPAN_SUBSET_SUBSPACE", 1186 ``!s t:real->bool. s SUBSET t /\ subspace t ==> span s SUBSET t``, 1187 MESON_TAC[SPAN_MONO, SPAN_EQ_SELF]); 1188 1189val SURJECTIVE_IMAGE_EQ = store_thm ("SURJECTIVE_IMAGE_EQ", 1190 ``!s t. (!y. y IN t ==> ?x. f x = y) /\ (!x. (f x) IN t <=> x IN s) 1191 ==> (IMAGE f s = t)``, 1192 SET_TAC[]); 1193 1194val SUBSPACE_TRANSLATION_SELF = store_thm ("SUBSPACE_TRANSLATION_SELF", 1195 ``!s a. subspace s /\ a IN s ==> (IMAGE (\x. a + x) s = s)``, 1196 REPEAT STRIP_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN 1197 FIRST_ASSUM(SUBST1_TAC o SYM o REWRITE_RULE [GSYM SPAN_EQ_SELF]) THEN 1198 ASM_SIMP_TAC std_ss [SPAN_ADD_EQ, SPAN_CLAUSES] THEN 1199 REWRITE_TAC[REAL_ARITH ``(a + x:real = y) <=> (x = y - a)``, EXISTS_REFL]); 1200 1201val SUBSPACE_TRANSLATION_SELF_EQ = store_thm ("SUBSPACE_TRANSLATION_SELF_EQ", 1202 ``!s a:real. subspace s ==> ((IMAGE (\x. a + x) s = s) <=> a IN s)``, 1203 REPEAT STRIP_TAC THEN EQ_TAC THEN 1204 ASM_SIMP_TAC std_ss [SUBSPACE_TRANSLATION_SELF] THEN 1205 DISCH_THEN(MP_TAC o AP_TERM ``\s. (a:real) IN s``) THEN 1206 SIMP_TAC std_ss [] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN 1207 REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC ``0:real`` THEN 1208 ASM_MESON_TAC[subspace, REAL_ADD_RID]); 1209 1210val SUBSPACE_SUMS = store_thm ("SUBSPACE_SUMS", 1211 ``!s t. subspace s /\ subspace t 1212 ==> subspace {x + y | x IN s /\ y IN t}``, 1213 SIMP_TAC std_ss [subspace, FORALL_IN_GSPEC, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 1214 SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN REPEAT STRIP_TAC THENL 1215 [ASM_MESON_TAC[REAL_ADD_LID], 1216 ONCE_REWRITE_TAC[REAL_ARITH 1217 ``(x + y) + (x' + y'):real = (x + x') + (y + y')``] THEN 1218 ASM_MESON_TAC[], 1219 REWRITE_TAC[REAL_ADD_LDISTRIB] THEN ASM_MESON_TAC[]]); 1220 1221val SPAN_UNION = store_thm ("SPAN_UNION", 1222 ``!s t. span(s UNION t) = {x + y:real | x IN span s /\ y IN span t}``, 1223 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 1224 [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN 1225 SIMP_TAC std_ss [SUBSPACE_SUMS, SUBSPACE_SPAN] THEN 1226 SIMP_TAC std_ss [SUBSET_DEF, IN_UNION, GSPECIFICATION, EXISTS_PROD] THEN 1227 X_GEN_TAC ``x:real`` THEN STRIP_TAC THENL 1228 [MAP_EVERY EXISTS_TAC [``x:real``, ``0:real``] THEN 1229 ASM_SIMP_TAC std_ss [SPAN_SUPERSET, SPAN_0, REAL_ADD_RID], 1230 MAP_EVERY EXISTS_TAC [``0:real``, ``x:real``] THEN 1231 ASM_SIMP_TAC std_ss [SPAN_SUPERSET, SPAN_0, REAL_ADD_LID]], 1232 SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_GSPEC] THEN 1233 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_ADD THEN 1234 ASM_MESON_TAC[SPAN_MONO, SUBSET_UNION, SUBSET_DEF]]); 1235 1236(* ------------------------------------------------------------------------- *) 1237(* Equality in Cauchy-Schwarz and triangle inequalities. *) 1238(* ------------------------------------------------------------------------- *) 1239 1240val ABS_CAUCHY_SCHWARZ_EQ = store_thm 1241 ("ABS_CAUCHY_SCHWARZ_EQ", 1242 ``!x:real y. (x * y = abs(x) * abs(y)) <=> (abs(x) * y = abs(y) * x)``, 1243 REPEAT GEN_TAC THEN ASM_CASES_TAC ``0 <= x:real`` THEN 1244 (ASM_CASES_TAC ``0 <= y:real``) THEN ASM_REWRITE_TAC [abs] THENL 1245 [ASM_REAL_ARITH_TAC, ALL_TAC, ALL_TAC, ASM_REAL_ARITH_TAC] THEN 1246 ((MP_TAC o SPECL [``x:real``,``y:real``]) REAL_LT_TOTAL THEN STRIP_TAC THEN 1247 TRY (ASM_REAL_ARITH_TAC)) THEN COND_CASES_TAC THEN EQ_TAC THEN 1248 TRY (ASM_REAL_ARITH_TAC)); 1249 1250val ABS_CAUCHY_SCHWARZ_ABS_EQ = store_thm 1251 ("ABS_CAUCHY_SCHWARZ_ABS_EQ", 1252 ``!x:real y. (abs(x * y) = abs(x) * abs(y)) <=> 1253 (abs(x) * y = abs(y) * x) \/ (abs(x) * y = -abs(y) * x)``, 1254 SIMP_TAC std_ss [REAL_ARITH ``&0 <= a ==> ((abs x = a) <=> (x = a) \/ (-x = a:real))``, 1255 REAL_LE_MUL, ABS_POS, REAL_MUL_RNEG] THEN 1256 REAL_ARITH_TAC); 1257 1258val REAL_EQ_LINV = store_thm 1259 ("REAL_EQ_LINV", ``!x. (-x = (x :real)) <=> (x = 0)``, 1260 GEN_TAC 1261 >> REWRITE_TAC [SYM (Q.SPECL [`x`, `-x`, `x`] REAL_EQ_LADD)] 1262 >> REWRITE_TAC [REAL_ADD_RINV, REAL_DOUBLE] 1263 >> RW_TAC real_ss [REAL_ENTIRE]); 1264 1265val REAL_EQ_RINV = store_thm 1266 ("REAL_EQ_RINV", ``!x. ((x :real) = -x) <=> (x = 0)``, 1267 GEN_TAC 1268 >> REWRITE_TAC [SYM (Q.SPECL [`x`, `x`, `-x`] REAL_EQ_LADD)] 1269 >> REWRITE_TAC [REAL_ADD_RINV, REAL_DOUBLE] 1270 >> RW_TAC real_ss [REAL_ENTIRE]); 1271 1272(* this proof is too advanced in realScript *) 1273val ABS_TRIANGLE_EQ = store_thm ("ABS_TRIANGLE_EQ", 1274 ``!x y:real. (abs(x + y) = abs(x) + abs(y)) <=> (abs(x) * y = abs(y) * x)``, 1275 rpt GEN_TAC 1276 >> ASM_CASES_TAC ``0 <= x:real`` 1277 >> ASM_CASES_TAC ``0 <= y:real`` 1278 >> ASM_REWRITE_TAC [abs] 1279 >- ( `0 <= x + y` by PROVE_TAC [REAL_LE_ADD] \\ 1280 ASM_SIMP_TAC bool_ss [] >> REAL_ARITH_TAC ) 1281 >| [ (* goal 1 (of 3) *) 1282 Cases_on `0 <= x + y` 1283 >- ( ASM_SIMP_TAC bool_ss [REAL_EQ_LADD, Once REAL_MUL_SYM] \\ 1284 EQ_TAC >- PROVE_TAC [] \\ 1285 REWRITE_TAC [REAL_EQ_RMUL] \\ 1286 STRIP_TAC >> FULL_SIMP_TAC bool_ss [REAL_ADD_LID] ) \\ 1287 ASM_SIMP_TAC bool_ss [REAL_NEG_ADD, REAL_EQ_RADD, Once REAL_MUL_SYM] \\ 1288 `(-x = x) = (x = 0)` by PROVE_TAC [REAL_EQ_LINV] \\ 1289 POP_ASSUM (REWRITE_TAC o wrap) \\ 1290 REWRITE_TAC [REAL_EQ_RMUL] \\ 1291 EQ_TAC >- PROVE_TAC [] \\ 1292 STRIP_TAC \\ 1293 `y = 0` by PROVE_TAC [REAL_EQ_RINV] \\ 1294 FULL_SIMP_TAC bool_ss [REAL_ADD_RID], 1295 (* goal 2 (of 3) *) 1296 Cases_on `0 <= x + y` 1297 >- ( ASM_SIMP_TAC bool_ss [REAL_EQ_RADD, Once REAL_MUL_SYM] \\ 1298 EQ_TAC >- PROVE_TAC [] \\ 1299 REWRITE_TAC [REAL_EQ_LMUL] \\ 1300 Reverse STRIP_TAC >- ( MATCH_MP_TAC EQ_SYM >> ASM_REWRITE_TAC [] ) \\ 1301 REWRITE_TAC [REAL_EQ_RINV] \\ 1302 FULL_SIMP_TAC bool_ss [REAL_ADD_RID] ) \\ 1303 FULL_SIMP_TAC bool_ss [REAL_NEG_ADD] \\ 1304 REWRITE_TAC [REAL_EQ_LADD, REAL_EQ_LINV, Once REAL_MUL_SYM] \\ 1305 EQ_TAC >- RW_TAC real_ss [] \\ 1306 REWRITE_TAC [REAL_EQ_LMUL, REAL_EQ_LINV] >> STRIP_TAC \\ 1307 FULL_SIMP_TAC bool_ss [REAL_ADD_LID], 1308 (* goal 3 (of 3) *) 1309 Know `~(0 <= x + y)` 1310 >- ( FULL_SIMP_TAC bool_ss [REAL_NOT_LE] \\ 1311 PROVE_TAC [REAL_LT_ADD2, REAL_ADD_RID] ) \\ 1312 DISCH_TAC >> ASM_SIMP_TAC bool_ss [] \\ 1313 REWRITE_TAC [REAL_NEG_ADD] \\ 1314 PROVE_TAC [REAL_NEG_RMUL, REAL_MUL_SYM] ]); 1315 1316val DIST_TRIANGLE_EQ = store_thm ("DIST_TRIANGLE_EQ", 1317 ``!x y z:real. (dist(x,z) = dist(x,y) + dist(y,z)) <=> 1318 (abs (x - y) * (y - z) = abs (y - z) * (x - y))``, 1319 REWRITE_TAC[GSYM ABS_TRIANGLE_EQ, dist] THEN REAL_ARITH_TAC); 1320 1321(* ------------------------------------------------------------------------- *) 1322(* Collinearity. *) 1323(* ------------------------------------------------------------------------- *) 1324 1325val _ = hide "collinear"; 1326 1327val collinear = new_definition ("collinear", 1328 ``collinear s <=> ?u. !x y:real. x IN s /\ y IN s ==> ?c. x - y = c * u``); 1329 1330val COLLINEAR_SUBSET = store_thm ("COLLINEAR_SUBSET", 1331 ``!s t. collinear t /\ s SUBSET t ==> collinear s``, 1332 REWRITE_TAC[collinear] THEN SET_TAC[]); 1333 1334val COLLINEAR_EMPTY = store_thm ("COLLINEAR_EMPTY", 1335 ``collinear {}``, 1336 REWRITE_TAC[collinear, NOT_IN_EMPTY]); 1337 1338val COLLINEAR_SING = store_thm ("COLLINEAR_SING", 1339 ``!x:real. collinear {x}``, 1340 SIMP_TAC std_ss [collinear, IN_SING, REAL_SUB_REFL] THEN 1341 METIS_TAC [REAL_MUL_LZERO]); 1342 1343val COLLINEAR_2 = store_thm ("COLLINEAR_2", 1344 ``!x y:real. collinear {x;y}``, 1345 REPEAT GEN_TAC THEN REWRITE_TAC[collinear, IN_INSERT, NOT_IN_EMPTY] THEN 1346 EXISTS_TAC ``x - y:real`` THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THENL 1347 [EXISTS_TAC ``&0:real``, EXISTS_TAC ``&1:real``, 1348 EXISTS_TAC ``- &1:real``, EXISTS_TAC ``&0:real``] THEN 1349 REAL_ARITH_TAC); 1350 1351val COLLINEAR_SMALL = store_thm ("COLLINEAR_SMALL", 1352 ``!s. FINITE s /\ CARD s <= 2 ==> collinear s``, 1353 REWRITE_TAC[ARITH_PROVE ``s <= 2 <=> (s = 0) \/ (s = 1) \/ (s = 2:num)``] THEN 1354 REWRITE_TAC[LEFT_AND_OVER_OR, GSYM HAS_SIZE] THEN 1355 REWRITE_TAC [ONE, TWO, HAS_SIZE_CLAUSES] THEN 1356 REPEAT STRIP_TAC THEN 1357 ASM_REWRITE_TAC[COLLINEAR_EMPTY, COLLINEAR_SING, COLLINEAR_2]); 1358 1359val COLLINEAR_3 = store_thm ("COLLINEAR_3", 1360 ``!x y z. collinear {x;y;z} <=> collinear {0;x - y;z - y}``, 1361 REPEAT GEN_TAC THEN 1362 SIMP_TAC std_ss [collinear, FORALL_IN_INSERT, CONJ_EQ_IMP, 1363 RIGHT_FORALL_IMP_THM, NOT_IN_EMPTY] THEN 1364 AP_TERM_TAC THEN ABS_TAC THEN 1365 METIS_TAC [REAL_ARITH ``x - y = (x - y) - 0:real``, 1366 REAL_ARITH ``y - x = 0 - (x - y:real)``, 1367 REAL_ARITH ``x - z:real = (x - y) - (z - y)``]); 1368 1369val COLLINEAR_LEMMA = store_thm ("COLLINEAR_LEMMA", 1370 ``!x y:real. collinear {0;x;y} <=> 1371 (x = 0) \/ (y = 0) \/ ?c. y = c * x``, 1372 REPEAT GEN_TAC THEN 1373 MAP_EVERY ASM_CASES_TAC [``x:real = 0``, ``y:real = 0``] THEN 1374 TRY(ONCE_REWRITE_TAC [INSERT_COMM] THEN 1375 ASM_REWRITE_TAC[INSERT_INSERT, COLLINEAR_SING, COLLINEAR_2] THEN NO_TAC) THEN 1376 ASM_REWRITE_TAC[collinear] THEN EQ_TAC THENL 1377 [DISCH_THEN(X_CHOOSE_THEN ``u:real`` 1378 (fn th => MP_TAC(SPECL [``x:real``, ``0:real``] th) THEN 1379 MP_TAC(SPECL [``y:real``, ``0:real``] th))) THEN 1380 REWRITE_TAC[IN_INSERT, REAL_SUB_RZERO] THEN 1381 DISCH_THEN(X_CHOOSE_THEN ``e:real`` SUBST_ALL_TAC) THEN 1382 DISCH_THEN(X_CHOOSE_THEN ``d:real`` SUBST_ALL_TAC) THEN 1383 EXISTS_TAC ``e / d:real`` THEN REWRITE_TAC[REAL_MUL_ASSOC] THEN 1384 RULE_ASSUM_TAC(REWRITE_RULE[REAL_ENTIRE, DE_MORGAN_THM]) THEN 1385 ASM_SIMP_TAC real_ss [REAL_DIV_RMUL], 1386 STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN ASM_REWRITE_TAC[] THEN 1387 REWRITE_TAC[IN_INSERT, NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN 1388 ASM_REWRITE_TAC[] THENL 1389 [EXISTS_TAC ``&0:real``, EXISTS_TAC ``- &1:real``, EXISTS_TAC ``-c:real``, 1390 EXISTS_TAC ``&1:real``, EXISTS_TAC ``&0:real``, EXISTS_TAC ``&1 - c:real``, 1391 EXISTS_TAC ``c:real``, EXISTS_TAC ``c - &1:real``, EXISTS_TAC ``&0:real``] THEN 1392 REAL_ARITH_TAC]); 1393 1394val COLLINEAR_LEMMA_ALT = store_thm ("COLLINEAR_LEMMA_ALT", 1395 ``!x y. collinear {0;x;y} <=> (x = 0) \/ ?c. y = c * x``, 1396 REWRITE_TAC[COLLINEAR_LEMMA] THEN METIS_TAC [REAL_MUL_LZERO]); 1397 1398val ABS_CAUCHY_SCHWARZ_EQUAL = store_thm ("ABS_CAUCHY_SCHWARZ_EQUAL", 1399 ``!x y:real. (abs(x * y) = abs(x) * abs(y)) <=> collinear {0;x;y}``, 1400 REPEAT GEN_TAC THEN REWRITE_TAC[ABS_CAUCHY_SCHWARZ_ABS_EQ] THEN 1401 MAP_EVERY ASM_CASES_TAC [``x:real = 0``, ``y:real = 0``] THEN 1402 TRY(ONCE_ASM_REWRITE_TAC [INSERT_COMM] THEN 1403 ASM_REWRITE_TAC[INSERT_INSERT, COLLINEAR_SING, COLLINEAR_2, ABS_0, 1404 REAL_MUL_LZERO, REAL_MUL_RZERO] THEN NO_TAC) THEN 1405 ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN EQ_TAC THENL 1406 [STRIP_TAC THENL 1407 [EXISTS_TAC ``y / x:real``, EXISTS_TAC ``y / x:real``] THEN 1408 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL], 1409 ASM_REAL_ARITH_TAC]); 1410 1411val MUL_CAUCHY_SCHWARZ_EQUAL = store_thm ("MUL_CAUCHY_SCHWARZ_EQUAL", 1412 ``!x y:real. 1413 ((x * y) pow 2 = (x * x) * (y * y)) <=> 1414 collinear {0;x;y}``, 1415 REWRITE_TAC[GSYM ABS_CAUCHY_SCHWARZ_EQUAL] THEN 1416 REPEAT GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH 1417 ``&0 <= y /\ ((u:real = v) <=> (x = abs y)) ==> ((u = v) <=> (x = y:real))``) THEN 1418 SIMP_TAC std_ss [ABS_POS, REAL_LE_MUL] THEN 1419 REWRITE_TAC[REAL_EQ_SQUARE_ABS] THEN REWRITE_TAC[POW_MUL, GSYM POW_2] THEN 1420 REWRITE_TAC [POW_2] THEN REAL_ARITH_TAC); 1421 1422val COLLINEAR_3_EXPAND = store_thm ("COLLINEAR_3_EXPAND", 1423 ``!a b c:real. collinear{a;b;c} <=> ((a = c) \/ ?u. b = u * a + (&1 - u) * c)``, 1424 REPEAT GEN_TAC THEN 1425 ONCE_REWRITE_TAC[SET_RULE ``{a;b;c} = {a;c;b}``] THEN 1426 ONCE_REWRITE_TAC[COLLINEAR_3] THEN 1427 REWRITE_TAC[COLLINEAR_LEMMA, REAL_SUB_0] THEN 1428 ASM_CASES_TAC ``a:real = c`` THEN ASM_REWRITE_TAC[] THEN 1429 ASM_CASES_TAC ``b:real = c`` THEN 1430 ASM_REWRITE_TAC[REAL_ARITH ``u * c + (&1 - u) * c = c:real``] THENL 1431 [EXISTS_TAC ``&0:real`` THEN REAL_ARITH_TAC, 1432 AP_TERM_TAC THEN ABS_TAC THEN REAL_ARITH_TAC]); 1433 1434val COLLINEAR_TRIPLES = store_thm ("COLLINEAR_TRIPLES", 1435 ``!s a b:real. 1436 ~(a = b) 1437 ==> (collinear(a INSERT b INSERT s) <=> 1438 !x. x IN s ==> collinear{a;b;x})``, 1439 REPEAT STRIP_TAC THEN EQ_TAC THENL 1440 [REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP 1441 (REWRITE_RULE[CONJ_EQ_IMP] COLLINEAR_SUBSET)) THEN 1442 ASM_SET_TAC[], 1443 ONCE_REWRITE_TAC[SET_RULE ``{a;b;x} = {a;x;b}``] THEN 1444 ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN DISCH_TAC THEN 1445 SUBGOAL_THEN 1446 ``!x:real. x IN (a INSERT b INSERT s) ==> ?u. x = u * a + (&1 - u) * b`` 1447 MP_TAC THENL 1448 [ASM_SIMP_TAC real_ss [FORALL_IN_INSERT] THEN CONJ_TAC THENL 1449 [EXISTS_TAC ``&1:real`` THEN REAL_ARITH_TAC, 1450 EXISTS_TAC ``&0:real`` THEN REAL_ARITH_TAC], 1451 POP_ASSUM_LIST(K ALL_TAC) THEN DISCH_TAC THEN 1452 REWRITE_TAC[collinear] THEN EXISTS_TAC ``b - a:real`` THEN 1453 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 1454 FIRST_X_ASSUM(fn th => MP_TAC(SPEC ``x:real`` th) THEN MP_TAC(SPEC 1455 ``y:real`` th)) THEN 1456 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN 1457 ASM_REWRITE_TAC[REAL_ARITH 1458 ``(u * a + (&1 - u) * b) - (v * a + (&1 - v) * b):real = 1459 (v - u) * (b - a)``] THEN 1460 METIS_TAC []]]); 1461 1462val COLLINEAR_4_3 = store_thm ("COLLINEAR_4_3", 1463 ``!a b c d:real. 1464 ~(a = b) 1465 ==> (collinear {a;b;c;d} <=> collinear{a;b;c} /\ collinear{a;b;d})``, 1466 REPEAT STRIP_TAC THEN 1467 MP_TAC(ISPECL [``{c:real;d}``, ``a:real``, ``b:real``] 1468 COLLINEAR_TRIPLES) THEN 1469 ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN 1470 SIMP_TAC real_ss [FORALL_IN_INSERT, NOT_IN_EMPTY]); 1471 1472val COLLINEAR_3_TRANS = store_thm ("COLLINEAR_3_TRANS", 1473 ``!a b c d:real. 1474 collinear{a;b;c} /\ collinear{b;c;d} /\ ~(b = c) ==> collinear{a;b;d}``, 1475 REPEAT STRIP_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN 1476 EXISTS_TAC ``{b:real;c;a;d}`` THEN ASM_SIMP_TAC std_ss [COLLINEAR_4_3] THEN 1477 CONJ_TAC THENL [ALL_TAC, SET_TAC[]] THEN 1478 ONCE_ASM_REWRITE_TAC [SET_RULE ``{b;c;a} = {a;b;c}``] THEN METIS_TAC []); 1479 1480(* ------------------------------------------------------------------------- *) 1481(* Between-ness. *) 1482(* ------------------------------------------------------------------------- *) 1483 1484val between = new_definition ("between", 1485 ``between x (a,b) <=> (dist(a,b) = dist(a,x) + dist(x,b))``); 1486 1487val BETWEEN_REFL = store_thm ("BETWEEN_REFL", 1488 ``!a b. between a (a,b) /\ between b (a,b) /\ between a (a,a)``, 1489 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1490 1491val BETWEEN_REFL_EQ = store_thm ("BETWEEN_REFL_EQ", 1492 ``!a x. between x (a,a) <=> (x = a)``, 1493 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1494 1495val BETWEEN_SYM = store_thm ("BETWEEN_SYM", 1496 ``!a b x. between x (a,b) <=> between x (b,a)``, 1497 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1498 1499val BETWEEN_ANTISYM = store_thm ("BETWEEN_ANTISYM", 1500 ``!a b c. between a (b,c) /\ between b (a,c) ==> (a = b)``, 1501 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1502 1503val BETWEEN_TRANS = store_thm ("BETWEEN_TRANS", 1504 ``!a b c d. between a (b,c) /\ between d (a,c) ==> between d (b,c)``, 1505 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1506 1507val BETWEEN_TRANS_2 = store_thm ("BETWEEN_TRANS_2", 1508 ``!a b c d. between a (b,c) /\ between d (a,b) ==> between a (c,d)``, 1509 REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC); 1510 1511val BETWEEN_ABS = store_thm ("BETWEEN_ABS", 1512 ``!a b x:real. 1513 between x (a,b) <=> (abs(x - a) * (b - x) = abs(b - x) * (x - a))``, 1514 REPEAT GEN_TAC THEN REWRITE_TAC[between, DIST_TRIANGLE_EQ] THEN 1515 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [ABS_SUB] THEN REAL_ARITH_TAC); 1516 1517val BETWEEN_IMP_COLLINEAR = store_thm ("BETWEEN_IMP_COLLINEAR", 1518 ``!a b x:real. between x (a,b) ==> collinear {a;x;b}``, 1519 REPEAT GEN_TAC THEN ASM_CASES_TAC ``x:real = a`` THENL 1520 [ONCE_REWRITE_TAC[COLLINEAR_3, BETWEEN_ABS] THEN 1521 DISCH_TAC THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA, REAL_SUB_REFL] THEN 1522 ASM_REAL_ARITH_TAC, 1523 ONCE_REWRITE_TAC[COLLINEAR_3, BETWEEN_ABS] THEN 1524 DISCH_TAC THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN 1525 DISJ2_TAC THEN DISJ2_TAC THEN EXISTS_TAC ``(b - x) / (a - x:real)`` THEN 1526 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH 1527 ``(x <> a) = ((a - x) <> 0:real)``]) THEN 1528 ASM_SIMP_TAC real_ss [REAL_DIV_RMUL]]); 1529 1530val COLLINEAR_BETWEEN_CASES = store_thm ("COLLINEAR_BETWEEN_CASES", 1531 ``!a b c:real. 1532 collinear {a;b;c} <=> 1533 between a (b,c) \/ between b (c,a) \/ between c (a,b)``, 1534 REPEAT STRIP_TAC THEN EQ_TAC THENL 1535 [REWRITE_TAC[COLLINEAR_3_EXPAND] THEN 1536 ASM_CASES_TAC ``c:real = a`` THEN ASM_REWRITE_TAC[BETWEEN_REFL] THEN 1537 STRIP_TAC THEN ASM_REWRITE_TAC[between, dist] THEN 1538 ASM_REAL_ARITH_TAC, 1539 DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN (MP_TAC o MATCH_MP 1540 BETWEEN_IMP_COLLINEAR)) THEN 1541 METIS_TAC[INSERT_COMM]]); 1542 1543val COLLINEAR_DIST_BETWEEN = store_thm ("COLLINEAR_DIST_BETWEEN", 1544 ``!a b x. collinear {x;a;b} /\ 1545 dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b) 1546 ==> between x (a,b)``, 1547 SIMP_TAC std_ss [COLLINEAR_BETWEEN_CASES, between, dist] THEN REAL_ARITH_TAC); 1548 1549val COLLINEAR_1 = store_thm ("COLLINEAR_1", 1550 ``!s:real->bool. collinear s``, 1551 GEN_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN 1552 EXISTS_TAC ``(0:real) INSERT (1:real) INSERT s`` THEN 1553 CONJ_TAC THENL [ALL_TAC, SET_TAC[]] THEN 1554 W(MP_TAC o PART_MATCH (lhs o rand) COLLINEAR_TRIPLES o snd) THEN 1555 REWRITE_TAC[REAL_ARITH ``0 <> 1:real``] THEN DISCH_THEN SUBST1_TAC THEN 1556 REWRITE_TAC[COLLINEAR_BETWEEN_CASES] THEN 1557 REWRITE_TAC[between, dist, ABS_N] THEN 1558 REAL_ARITH_TAC); 1559 1560(* ------------------------------------------------------------------------- *) 1561(* Midpoint between two points. *) 1562(* ------------------------------------------------------------------------- *) 1563 1564val midpoint = new_definition ("midpoint", 1565 ``midpoint(a,b) = inv(&2:real) * (a + b)``); 1566 1567val MIDPOINT_REFL = store_thm ("MIDPOINT_REFL", 1568 ``!x. midpoint(x,x) = x``, 1569 REWRITE_TAC[midpoint, REAL_DOUBLE, REAL_MUL_ASSOC] THEN 1570 SIMP_TAC std_ss [REAL_MUL_LINV, REAL_ARITH ``2 <> 0:real``] THEN REAL_ARITH_TAC); 1571 1572val MIDPOINT_SYM = store_thm ("MIDPOINT_SYM", 1573 ``!a b. midpoint(a,b) = midpoint(b,a)``, 1574 METIS_TAC[midpoint, REAL_ADD_SYM]); 1575 1576val DIST_MIDPOINT = store_thm ("DIST_MIDPOINT", 1577 ``!a b. (dist(a,midpoint(a,b)) = dist(a,b) / &2) /\ 1578 (dist(b,midpoint(a,b)) = dist(a,b) / &2) /\ 1579 (dist(midpoint(a,b),a) = dist(a,b) / &2) /\ 1580 (dist(midpoint(a,b),b) = dist(a,b) / &2)``, 1581 REWRITE_TAC[midpoint, dist] THEN 1582 SIMP_TAC std_ss [REAL_EQ_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 1583 ONCE_REWRITE_TAC [GSYM ABS_N] THEN 1584 REWRITE_TAC [GSYM ABS_MUL, REAL_SUB_RDISTRIB] THEN REWRITE_TAC [ABS_N] THEN 1585 ONCE_REWRITE_TAC [REAL_ARITH ``a * b * c = a * c * b:real``] THEN 1586 SIMP_TAC std_ss [REAL_MUL_LINV, REAL_ARITH ``2 <> 0:real``] THEN REAL_ARITH_TAC); 1587 1588val MIDPOINT_EQ_ENDPOINT = store_thm ("MIDPOINT_EQ_ENDPOINT", 1589 ``!a b. ((midpoint(a,b) = a) <=> (a = b)) /\ 1590 ((midpoint(a,b) = b) <=> (a = b)) /\ 1591 ((a = midpoint(a,b)) <=> (a = b)) /\ 1592 ((b = midpoint(a,b)) <=> (a = b))``, 1593 REWRITE_TAC[midpoint] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 1594 REWRITE_TAC [GSYM real_div] THEN 1595 SIMP_TAC std_ss [REAL_EQ_RDIV_EQ, REAL_EQ_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 1596 REAL_ARITH_TAC); 1597 1598val BETWEEN_MIDPOINT = store_thm ("BETWEEN_MIDPOINT", 1599 ``!a b. between (midpoint(a,b)) (a,b) /\ between (midpoint(a,b)) (b,a)``, 1600 REWRITE_TAC[between, midpoint] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 1601 REWRITE_TAC [dist, GSYM real_div] THEN 1602 ONCE_REWRITE_TAC [REAL_ARITH ``a / 2 - b = a / 2 - b * 1:real``] THEN 1603 ONCE_REWRITE_TAC [REAL_ARITH ``b - a / 2 = b * 1 - a / 2:real``] THEN 1604 REWRITE_TAC [METIS [REAL_DIV_REFL, REAL_ARITH ``2 <> 0:real``] ``1 = 2/2:real``] THEN 1605 REWRITE_TAC [real_div, REAL_MUL_ASSOC, real_sub] THEN 1606 REWRITE_TAC [REAL_ARITH ``-(a * b) = -a * b:real``] THEN 1607 REWRITE_TAC [GSYM real_div] THEN SIMP_TAC std_ss [REAL_DIV_ADD] THEN 1608 REWRITE_TAC [real_div, ABS_MUL] THEN 1609 SIMP_TAC std_ss [ABS_N, ABS_INV, REAL_ARITH ``2 <> 0:real``] THEN 1610 REWRITE_TAC [GSYM REAL_ADD_RDISTRIB] THEN REWRITE_TAC [GSYM real_div] THEN 1611 SIMP_TAC std_ss [REAL_EQ_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 1612 REAL_ARITH_TAC); 1613 1614val MIDPOINT_LINEAR_IMAGE = store_thm ("MIDPOINT_LINEAR_IMAGE", 1615 ``!f a b. linear f ==> (midpoint(f a,f b) = f(midpoint(a,b)))``, 1616 SIMP_TAC std_ss [midpoint, LINEAR_ADD, LINEAR_CMUL]); 1617 1618val COLLINEAR_MIDPOINT = store_thm ("COLLINEAR_MIDPOINT", 1619 ``!a b. collinear{a;midpoint(a,b);b}``, 1620 REPEAT GEN_TAC THEN REWRITE_TAC[COLLINEAR_3_EXPAND, midpoint] THEN 1621 DISJ2_TAC THEN REWRITE_TAC [REAL_ARITH ``u * a + (1 - u) * b = 1622 a * u - b * u + b:real``] THEN 1623 EXISTS_TAC ``inv &2:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_MUL_SYM] THEN 1624 REWRITE_TAC [REAL_ADD_RDISTRIB] THEN 1625 GEN_REWR_TAC (RAND_CONV o RAND_CONV) [GSYM REAL_HALF] THEN 1626 REWRITE_TAC [GSYM real_div] THEN REAL_ARITH_TAC); 1627 1628val MIDPOINT_COLLINEAR = store_thm ("MIDPOINT_COLLINEAR", 1629 ``!a b c:real. 1630 ~(a = c) 1631 ==> ((b = midpoint(a,c)) <=> collinear{a;b;c} /\ (dist(a,b) = dist(b,c)))``, 1632 REPEAT STRIP_TAC THEN 1633 MATCH_MP_TAC(TAUT `(a ==> b) /\ (b ==> (a <=> c)) ==> (a <=> b /\ c)`) THEN 1634 SIMP_TAC std_ss [COLLINEAR_MIDPOINT] THEN ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN 1635 STRIP_TAC THEN ASM_REWRITE_TAC[midpoint, dist] THEN 1636 REWRITE_TAC 1637 [REAL_ARITH ``a - (u * a + (&1 - u) * c) = (&1 - u) * (a - c:real)``, 1638 REAL_ARITH ``(u * a + (&1 - u) * c) - c = u * (a - c:real)``] THEN 1639 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN 1640 SIMP_TAC std_ss [REAL_EQ_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN ASM_REAL_ARITH_TAC); 1641 1642(* ------------------------------------------------------------------------ *) 1643(* MISC *) 1644(* ------------------------------------------------------------------------ *) 1645 1646val INDEPENDENT_MONO = store_thm ("INDEPENDENT_MONO", 1647 ``!s t. independent t /\ s SUBSET t ==> independent s``, 1648 SIMP_TAC std_ss [independent, dependent] THEN 1649 ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_DELETE]); 1650 1651val SPAN_BREAKDOWN = store_thm ("SPAN_BREAKDOWN", 1652 ``!b s a:real. b IN s /\ a IN span s ==> ?k. (a - k * b) IN span(s DELETE b)``, 1653 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 1654 REPEAT GEN_TAC THEN DISCH_TAC THEN 1655 ONCE_REWRITE_TAC [METIS [] 1656 ``(?k:real. a - k * b IN span (s DELETE b)) = 1657 (\a. ?k. a - k * b IN span (s DELETE b)) a``] THEN 1658 MATCH_MP_TAC SPAN_INDUCT THEN 1659 SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN CONJ_TAC THENL 1660 [GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC ``x:real = b``, ALL_TAC] THEN 1661 ASM_SIMP_TAC std_ss [IN_DEF] THENL 1662 [EXISTS_TAC ``1:real`` THEN SIMP_TAC real_ss [] THEN 1663 ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN REWRITE_TAC [SPAN_CLAUSES], 1664 EXISTS_TAC ``0:real`` THEN SIMP_TAC real_ss [] THEN 1665 ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN MATCH_MP_TAC SPAN_SUPERSET THEN 1666 ASM_SET_TAC [], 1667 ALL_TAC] THEN REPEAT CONJ_TAC THENL 1668 [EXISTS_TAC ``0:real`` THEN SIMP_TAC real_ss [] THEN 1669 ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN REWRITE_TAC [SPAN_CLAUSES], 1670 REPEAT STRIP_TAC THEN EXISTS_TAC ``k + k':real`` THEN 1671 ONCE_REWRITE_TAC [REAL_ARITH 1672 ``(x + y - (k + k') * b) = ((x - k * b) + (y - k' * b:real))``] THEN 1673 ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN 1674 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM SPECIFICATION]) THEN 1675 METIS_TAC [SPAN_ADD], 1676 REPEAT STRIP_TAC THEN EXISTS_TAC ``c * k:real`` THEN 1677 ONCE_REWRITE_TAC [REAL_ARITH ``(c * x - (c * k) * y = c * (x - k * y:real))``] THEN 1678 ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN 1679 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM SPECIFICATION]) THEN 1680 METIS_TAC [SPAN_CLAUSES]]); 1681 1682val IN_SPAN_INSERT = store_thm ("IN_SPAN_INSERT", 1683 ``!a b:real s. a IN span(b INSERT s) /\ ~(a IN span s) 1684 ==> b IN span(a INSERT s)``, 1685 REPEAT STRIP_TAC THEN 1686 MP_TAC(ISPECL [``b:real``, ``(b:real) INSERT s``, ``a:real``] 1687 SPAN_BREAKDOWN) THEN ASM_REWRITE_TAC[IN_INSERT] THEN 1688 DISCH_THEN(X_CHOOSE_THEN ``k:real`` MP_TAC) THEN ASM_CASES_TAC ``k = &0:real`` THEN 1689 ASM_REWRITE_TAC[REAL_ARITH ``a - &0 * b = a:real``, DELETE_INSERT] THENL 1690 [ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, DELETE_SUBSET], ALL_TAC] THEN 1691 DISCH_THEN(MP_TAC o SPEC ``inv(k:real)`` o MATCH_MP SPAN_MUL) THEN 1692 ASM_SIMP_TAC real_ss [REAL_SUB_LDISTRIB, REAL_MUL_ASSOC, REAL_MUL_LINV] THEN 1693 DISCH_TAC THEN SUBST1_TAC(REAL_ARITH 1694 ``b:real = inv(k) * a - (inv(k) * a - b)``) THEN 1695 MATCH_MP_TAC SPAN_SUB THEN 1696 FULL_SIMP_TAC std_ss [SPAN_CLAUSES, IN_INSERT, SUBSET_DEF, IN_DELETE, SPAN_MONO] THEN 1697 POP_ASSUM MP_TAC THEN ABBREV_TAC ``y = inv k * a - b:real`` THEN 1698 SPEC_TAC (``y:real``, ``y:real``) THEN REWRITE_TAC [GSYM SUBSET_DEF] THEN 1699 MATCH_MP_TAC SPAN_MONO THEN ASM_SET_TAC []); 1700 1701val INDEPENDENT_INSERT = store_thm ("INDEPENDENT_INSERT", 1702 ``!a:real s. independent(a INSERT s) <=> 1703 if a IN s then independent s else independent s /\ ~(a IN span s)``, 1704 REPEAT GEN_TAC THEN ASM_CASES_TAC ``(a:real) IN s`` THEN 1705 ASM_SIMP_TAC std_ss [SET_RULE ``x IN s ==> (x INSERT s = s)``] THEN 1706 EQ_TAC THENL 1707 [DISCH_TAC THEN CONJ_TAC THENL 1708 [ASM_MESON_TAC[INDEPENDENT_MONO, SUBSET_DEF, IN_INSERT], 1709 POP_ASSUM MP_TAC THEN REWRITE_TAC[independent, dependent] THEN 1710 ASM_MESON_TAC[IN_INSERT, SET_RULE 1711 ``~(a IN s) ==> ((a INSERT s) DELETE a = s)``]], 1712 ALL_TAC] THEN 1713 SIMP_TAC std_ss [independent, dependent, NOT_EXISTS_THM] THEN 1714 STRIP_TAC THEN X_GEN_TAC ``b:real`` THEN 1715 REWRITE_TAC[IN_INSERT] THEN ASM_CASES_TAC ``b:real = a`` THEN 1716 ASM_SIMP_TAC std_ss [SET_RULE ``~(a IN s) ==> ((a INSERT s) DELETE a = s)``] THEN 1717 ASM_SIMP_TAC std_ss [SET_RULE ``~(a IN s) /\ ~(b = a) 1718 ==> ((a INSERT s) DELETE b = a INSERT (s DELETE b))``] THEN 1719 ASM_MESON_TAC[IN_SPAN_INSERT, SET_RULE 1720 ``b IN s ==> (b INSERT (s DELETE b) = s)``]); 1721 1722val INDEPENDENT_EMPTY = store_thm ("INDEPENDENT_EMPTY", 1723 ``independent {}``, 1724 REWRITE_TAC[independent, dependent, NOT_IN_EMPTY]); 1725 1726val INDEPENDENT_SING = store_thm ("INDEPENDENT_SING", 1727 ``!x. independent {x} <=> ~(x = 0)``, 1728 REWRITE_TAC[INDEPENDENT_INSERT, NOT_IN_EMPTY, SPAN_EMPTY] THEN 1729 REWRITE_TAC[INDEPENDENT_EMPTY] THEN SET_TAC[]); 1730 1731val INDEPENDENT_STDBASIS = store_thm ("INDEPENDENT_STDBASIS", 1732 ``independent {i:real | 1 <= i /\ i <= 1}``, 1733 REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2] THEN 1734 REWRITE_TAC [INDEPENDENT_SING] THEN REAL_ARITH_TAC); 1735 1736val SPANNING_SUBSET_INDEPENDENT = store_thm ("SPANNING_SUBSET_INDEPENDENT", 1737 ``!s t:real->bool. 1738 t SUBSET s /\ independent s /\ s SUBSET span(t) ==> (s = t)``, 1739 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 1740 ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET_DEF] THEN 1741 X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN 1742 UNDISCH_TAC ``independent s`` THEN DISCH_TAC THEN 1743 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [independent]) THEN 1744 SIMP_TAC std_ss [dependent, NOT_EXISTS_THM] THEN 1745 DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN ASM_REWRITE_TAC[] THEN 1746 ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_DELETE]); 1747 1748val IN_SPAN_DELETE = store_thm ("IN_SPAN_DELETE", 1749 ``!a b s. 1750 a IN span s /\ ~(a IN span (s DELETE b)) 1751 ==> b IN span (a INSERT (s DELETE b))``, 1752 ASM_MESON_TAC[IN_SPAN_INSERT, SPAN_MONO, SUBSET_DEF, IN_INSERT, IN_DELETE]); 1753 1754val SPAN_TRANS = store_thm ("SPAN_TRANS", 1755 ``!x y:real s. x IN span(s) /\ y IN span(x INSERT s) ==> y IN span(s)``, 1756 REPEAT STRIP_TAC THEN 1757 MP_TAC(SPECL [``x:real``, ``(x:real) INSERT s``, ``y:real``] 1758 SPAN_BREAKDOWN) THEN 1759 ASM_SIMP_TAC std_ss [IN_INSERT] THEN 1760 DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN 1761 SUBST1_TAC(REAL_ARITH ``y:real = (y - k * x) + k * x``) THEN 1762 MATCH_MP_TAC SPAN_ADD THEN ASM_SIMP_TAC std_ss [SPAN_MUL] THEN 1763 ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_INSERT, IN_DELETE]); 1764 1765val EXCHANGE_LEMMA = store_thm ("EXCHANGE_LEMMA", 1766 ``!s t:real->bool. 1767 FINITE t /\ independent s /\ s SUBSET span t 1768 ==> ?t'. t' HAS_SIZE (CARD t) /\ 1769 s SUBSET t' /\ t' SUBSET (s UNION t) /\ s SUBSET (span t')``, 1770 REPEAT GEN_TAC THEN 1771 completeInduct_on `CARD(t DIFF s :real->bool)` THEN 1772 GEN_TAC THEN GEN_TAC THEN DISCH_TAC THEN FULL_SIMP_TAC std_ss [] THEN 1773 POP_ASSUM K_TAC THEN 1774 KNOW_TAC ``(!m. m < CARD (t:real->bool DIFF s) ==> 1775 !t:real->bool s:real->bool. (m = CARD (t DIFF s)) ==> 1776 FINITE t /\ independent s /\ s SUBSET span t ==> 1777 ?t'. t' HAS_SIZE CARD t /\ s SUBSET t' /\ t' SUBSET s UNION t /\ 1778 s SUBSET span t') ==> 1779 (!t'':real->bool s':real->bool'. (CARD (t'' DIFF s') < CARD (t DIFF s)) ==> 1780 FINITE t'' /\ independent s' /\ s' SUBSET span t'' ==> 1781 ?t'. t' HAS_SIZE CARD t'' /\ s' SUBSET t' /\ t' SUBSET s' UNION t'' /\ 1782 s' SUBSET span t')`` THENL 1783 [METIS_TAC [], ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN DISCH_TAC] THEN 1784 ASM_CASES_TAC ``(s:real->bool) SUBSET t`` THENL 1785 [ASM_MESON_TAC[HAS_SIZE, SUBSET_UNION], ALL_TAC] THEN 1786 ASM_CASES_TAC ``t SUBSET (s:real->bool)`` THENL 1787 [ASM_MESON_TAC[SPANNING_SUBSET_INDEPENDENT, HAS_SIZE], ALL_TAC] THEN 1788 STRIP_TAC THEN UNDISCH_TAC ``~(t SUBSET s:real->bool)`` THEN DISCH_TAC THEN 1789 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 1790 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP] THEN 1791 DISCH_THEN(X_CHOOSE_THEN ``b:real`` STRIP_ASSUME_TAC) THEN 1792 ASM_CASES_TAC ``s SUBSET span(t DELETE (b:real))`` THENL 1793 [FIRST_X_ASSUM(MP_TAC o 1794 SPECL [``t DELETE (b:real)``, ``s:real->bool``]) THEN 1795 ASM_REWRITE_TAC[SET_RULE ``s DELETE a DIFF t = (s DIFF t) DELETE a``] THEN 1796 ASM_SIMP_TAC arith_ss [CARD_DELETE, FINITE_DIFF, IN_DIFF, FINITE_DELETE, 1797 CARD_EQ_0, ARITH_PROVE ``n - 1 < n <=> ~(n = 0:num)``] THEN 1798 KNOW_TAC ``t DIFF s <> {}:real->bool`` THENL 1799 [UNDISCH_TAC ``~((s:real->bool) SUBSET t)`` THEN ASM_SET_TAC[], 1800 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 1801 DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 1802 EXISTS_TAC ``(b:real) INSERT u`` THEN 1803 ASM_SIMP_TAC std_ss [SUBSET_INSERT, INSERT_SUBSET, IN_UNION] THEN CONJ_TAC THENL 1804 [UNDISCH_TAC ``(u:real->bool) HAS_SIZE CARD(t:real->bool) - 1`` THEN 1805 SIMP_TAC std_ss [HAS_SIZE, FINITE_EMPTY, FINITE_INSERT, CARD_EMPTY, CARD_INSERT] THEN 1806 STRIP_TAC THEN COND_CASES_TAC THENL 1807 [ASM_MESON_TAC[SUBSET_DEF, IN_UNION, IN_DELETE], ALL_TAC] THEN 1808 ASM_MESON_TAC[ARITH_PROVE ``~(n = 0) ==> (SUC(n - 1) = n)``, 1809 CARD_EQ_0, MEMBER_NOT_EMPTY], ALL_TAC] THEN 1810 CONJ_TAC THENL 1811 [UNDISCH_TAC ``u SUBSET s UNION (t DELETE (b:real))`` THEN SET_TAC[], 1812 ASM_MESON_TAC[SUBSET_DEF, SPAN_MONO, IN_INSERT]], 1813 ALL_TAC] THEN 1814 UNDISCH_TAC ``~(s SUBSET span (t DELETE (b:real)))`` THEN 1815 GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SUBSET_DEF] THEN 1816 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP] THEN 1817 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 1818 SUBGOAL_THEN ``~(a:real = b)`` ASSUME_TAC THENL 1819 [ASM_MESON_TAC[], ALL_TAC] THEN 1820 SUBGOAL_THEN ``~((a:real) IN t)`` ASSUME_TAC THENL 1821 [ASM_MESON_TAC[IN_DELETE, SPAN_CLAUSES], ALL_TAC] THEN 1822 FIRST_X_ASSUM(MP_TAC o SPECL 1823 [``(a:real) INSERT (t DELETE b)``, ``s:real->bool``]) THEN 1824 KNOW_TAC ``CARD ((a INSERT t DELETE b) DIFF s) < CARD (t DIFF s:real->bool)`` THENL 1825 [ASM_SIMP_TAC std_ss [SET_RULE 1826 ``a IN s ==> (((a INSERT (t DELETE b)) DIFF s) = (t DIFF s) DELETE b)``] THEN 1827 KNOW_TAC ``(b:real) IN (t DIFF s)`` THENL [METIS_TAC [IN_DIFF], DISCH_TAC] THEN 1828 KNOW_TAC ``FINITE (t DIFF s:real->bool)`` THENL [METIS_TAC [FINITE_DIFF], ALL_TAC] THEN 1829 SIMP_TAC std_ss [CARD_DELETE] THEN ASM_REWRITE_TAC [] THEN DISCH_TAC THEN 1830 ASM_SIMP_TAC std_ss [ARITH_PROVE ``n - 1 < n <=> ~(n = 0:num)``, CARD_EQ_0, 1831 FINITE_DIFF] THEN 1832 UNDISCH_TAC ``~((s:real->bool) SUBSET t)`` THEN ASM_SET_TAC[], 1833 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 1834 KNOW_TAC ``FINITE ((a:real) INSERT t DELETE b) /\ 1835 s SUBSET span (a INSERT t DELETE b)`` THENL 1836 [ASM_SIMP_TAC std_ss [FINITE_EMPTY, FINITE_INSERT, FINITE_DELETE] THEN 1837 REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN 1838 DISCH_TAC THEN MATCH_MP_TAC SPAN_TRANS THEN EXISTS_TAC ``b:real`` THEN 1839 ASM_MESON_TAC[IN_SPAN_DELETE, SUBSET_DEF, SPAN_MONO, 1840 SET_RULE ``t SUBSET (b INSERT (a INSERT (t DELETE b)))``], 1841 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 1842 DISCH_THEN (X_CHOOSE_TAC ``u:real->bool``) THEN EXISTS_TAC ``u:real->bool`` THEN 1843 POP_ASSUM MP_TAC THEN 1844 ASM_SIMP_TAC std_ss [HAS_SIZE, CARD_EMPTY, CARD_INSERT, CARD_DELETE, FINITE_DELETE, 1845 IN_DELETE, ARITH_PROVE ``(SUC(n - 1) = n) <=> ~(n = 0)``, 1846 CARD_EQ_0] THEN 1847 UNDISCH_TAC ``(b:real) IN t`` THEN ASM_SET_TAC[]); 1848 1849val CARD_STDBASIS = store_thm ("CARD_STDBASIS", 1850 ``CARD {1:real} = 1``, 1851 MESON_TAC[CARD_SING]); 1852 1853val INDEPENDENT_SPAN_BOUND = store_thm ("INDEPENDENT_SPAN_BOUND", 1854 ``!s t. FINITE t /\ independent s /\ s SUBSET span(t) 1855 ==> FINITE s /\ CARD(s) <= CARD(t)``, 1856 REPEAT GEN_TAC THEN DISCH_TAC THEN 1857 FIRST_ASSUM(MP_TAC o MATCH_MP EXCHANGE_LEMMA) THEN 1858 ASM_MESON_TAC[HAS_SIZE, CARD_SUBSET, SUBSET_FINITE_I]); 1859 1860val INDEPENDENT_BOUND = store_thm ("INDEPENDENT_BOUND", 1861 ``!s:real->bool. 1862 independent s ==> FINITE s /\ CARD(s) <= 1:num``, 1863 REPEAT GEN_TAC THEN DISCH_TAC THEN 1864 ONCE_REWRITE_TAC[GSYM CARD_STDBASIS] THEN 1865 MATCH_MP_TAC INDEPENDENT_SPAN_BOUND THEN 1866 KNOW_TAC ``span {1} = univ(:real)`` THENL 1867 [SIMP_TAC std_ss [EXTENSION, span, hull, IN_BIGINTER, IN_UNIV] THEN 1868 SIMP_TAC std_ss [SING_SUBSET, GSPECIFICATION, subspace] THEN 1869 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_RID] THEN 1870 FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [], 1871 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 1872 ASM_REWRITE_TAC[FINITE_SING, SUBSET_UNIV]); 1873 1874val MAXIMAL_INDEPENDENT_SUBSET_EXTEND = store_thm ("MAXIMAL_INDEPENDENT_SUBSET_EXTEND", 1875 ``!s v:real->bool. s SUBSET v /\ independent s ==> ?b. s SUBSET b /\ b SUBSET v /\ 1876 independent b /\ v SUBSET (span b)``, 1877 REPEAT GEN_TAC THEN 1878 completeInduct_on `(1:num) - CARD(s:real->bool)` THEN 1879 GEN_TAC THEN DISCH_TAC THEN FULL_SIMP_TAC std_ss [] THEN POP_ASSUM K_TAC THEN 1880 REPEAT STRIP_TAC THEN 1881 ASM_CASES_TAC ``v SUBSET (span(s:real->bool))`` THENL 1882 [ASM_MESON_TAC[SUBSET_REFL], ALL_TAC] THEN 1883 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 1884 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP] THEN 1885 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 1886 KNOW_TAC ``(!(m :num). m < (1 :num) - CARD (s :real -> bool) ==> 1887 !(s :real -> bool). (m = (1 :num) - CARD s) ==> 1888 s SUBSET (v :real -> bool) /\ independent s ==> 1889 ?(b :real -> bool). 1890 s SUBSET b /\ b SUBSET v /\ independent b /\ v SUBSET span b) ==> 1891 !s'. (1 - CARD s' < 1 - CARD s) ==> s' SUBSET v /\ independent s' ==> 1892 ?b. s' SUBSET b /\ b SUBSET v /\ independent b /\ v SUBSET span b`` THENL 1893 [METIS_TAC [], ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN 1894 FIRST_X_ASSUM(MP_TAC o SPEC ``(a:real) INSERT s``) THEN 1895 REWRITE_TAC[AND_IMP_INTRO] THEN 1896 KNOW_TAC ``1 - CARD (a INSERT s) < 1 - CARD s /\ a INSERT s SUBSET v /\ 1897 independent (a INSERT s:real->bool)`` THENL 1898 [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 1899 MESON_TAC[INSERT_SUBSET]] THEN 1900 SUBGOAL_THEN ``independent ((a:real) INSERT s)`` ASSUME_TAC THENL 1901 [ASM_REWRITE_TAC[INDEPENDENT_INSERT, COND_ID], ALL_TAC] THEN 1902 ASM_REWRITE_TAC[INSERT_SUBSET] THEN 1903 MATCH_MP_TAC(ARITH_PROVE ``(b = a + 1) /\ b <= n ==> n - b < n - a:num``) THEN 1904 ASM_SIMP_TAC std_ss [CARD_EMPTY, CARD_INSERT, INDEPENDENT_BOUND] THEN 1905 METIS_TAC[SPAN_SUPERSET, ADD1]); 1906 1907val MAXIMAL_INDEPENDENT_SUBSET = store_thm ("MAXIMAL_INDEPENDENT_SUBSET", 1908 ``!v:real->bool. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b)``, 1909 MP_TAC(SPEC ``EMPTY:real->bool`` MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN 1910 REWRITE_TAC[EMPTY_SUBSET, INDEPENDENT_EMPTY]); 1911 1912val SPAN_BREAKDOWN_EQ = store_thm ("SPAN_BREAKDOWN_EQ", 1913 ``!a:real s. (x IN span(a INSERT s) <=> (?k. (x - k * a) IN span s))``, 1914 REPEAT STRIP_TAC THEN EQ_TAC THENL 1915 [DISCH_THEN(MP_TAC o CONJ(SET_RULE ``(a:real) IN (a INSERT s)``)) THEN 1916 DISCH_THEN(MP_TAC o MATCH_MP SPAN_BREAKDOWN) THEN 1917 DISCH_THEN (X_CHOOSE_TAC ``k:real``) THEN EXISTS_TAC ``k:real`` THEN 1918 POP_ASSUM MP_TAC THEN SPEC_TAC(``x - k * a:real``,``y:real``) THEN 1919 REWRITE_TAC[GSYM SUBSET_DEF] THEN MATCH_MP_TAC SPAN_MONO THEN SET_TAC[], 1920 DISCH_THEN(X_CHOOSE_TAC ``k:real``) THEN 1921 SUBST1_TAC(REAL_ARITH ``x = (x - k * a) + k * a:real``) THEN 1922 MATCH_MP_TAC SPAN_ADD THEN 1923 ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_INSERT, SPAN_CLAUSES]]); 1924 1925val LINEAR_INDEPENDENT_EXTEND_LEMMA = store_thm ("LINEAR_INDEPENDENT_EXTEND_LEMMA", 1926 ``!f b. FINITE b ==> independent b ==> 1927 ?g:real->real. (!x y. x IN span b /\ y IN span b ==> 1928 (g(x + y) = g(x) + g(y))) /\ (!x c. x IN span b ==> 1929 (g(c * x) = c * g(x))) /\ (!x. x IN b ==> (g x = f x))``, 1930 GEN_TAC THEN 1931 ONCE_REWRITE_TAC [METIS [] 1932 ``!b. (independent b ==> 1933 ?g. (!x y. x IN span b /\ y IN span b ==> (g (x + y) = g x + g y)) /\ 1934 (!x c. x IN span b ==> (g (c * x) = c * g x)) /\ 1935 !x. x IN b ==> (g x = f x)) = 1936 (\b. independent b ==> 1937 ?g. (!x y. x IN span b /\ y IN span b ==> (g (x + y) = g x + g y)) /\ 1938 (!x c. x IN span b ==> (g (c * x) = c * g x)) /\ 1939 !x. x IN b ==> (g x = f x)) b``] THEN 1940 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 1941 REWRITE_TAC[NOT_IN_EMPTY, INDEPENDENT_INSERT] THEN CONJ_TAC THENL 1942 [REPEAT STRIP_TAC THEN EXISTS_TAC ``(\x. 0):real->real`` THEN 1943 SIMP_TAC std_ss [SPAN_EMPTY] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC, 1944 ALL_TAC] THEN 1945 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 1946 MAP_EVERY X_GEN_TAC [``b:real->bool``, ``a:real``] THEN 1947 REWRITE_TAC [AND_IMP_INTRO] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN 1948 REWRITE_TAC [CONJ_EQ_IMP] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 1949 DISCH_TAC THEN DISCH_TAC THEN REWRITE_TAC [AND_IMP_INTRO] THEN 1950 DISCH_THEN (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 1951 DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN 1952 ABBREV_TAC ``h = \z:real. @k. (z - k * a) IN span b`` THEN 1953 SUBGOAL_THEN ``!z:real. z IN span(a INSERT b) 1954 ==> (z - h(z) * a) IN span(b) /\ 1955 !k. (z - k * a) IN span(b) ==> (k = h(z))`` 1956 MP_TAC THENL 1957 [GEN_TAC THEN DISCH_TAC THEN 1958 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL 1959 [EXPAND_TAC "h" THEN CONV_TAC SELECT_CONV THEN 1960 ASM_MESON_TAC[SPAN_BREAKDOWN_EQ], 1961 ALL_TAC] THEN 1962 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM, AND_IMP_INTRO] THEN GEN_TAC THEN 1963 DISCH_THEN(MP_TAC o MATCH_MP SPAN_SUB) THEN 1964 REWRITE_TAC[REAL_ARITH ``(z - a * v) - (z - b * v) = (b - a) * v:real``] THEN 1965 ASM_CASES_TAC ``k = (h:real->real) z`` THEN ASM_REWRITE_TAC[] THEN 1966 DISCH_THEN(MP_TAC o SPEC ``inv(k - (h:real->real) z)`` o 1967 MATCH_MP SPAN_MUL) THEN 1968 ASM_SIMP_TAC real_ss [REAL_MUL_LINV, REAL_MUL_ASSOC, REAL_SUB_0], 1969 ALL_TAC] THEN 1970 SIMP_TAC std_ss [TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN 1971 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM, AND_IMP_INTRO] THEN 1972 DISCH_THEN (MP_TAC o SIMP_RULE std_ss [FORALL_AND_THM]) THEN STRIP_TAC THEN 1973 EXISTS_TAC ``\z:real. h(z) * (f:real->real)(a) + g(z - h(z) * a)`` THEN 1974 ONCE_REWRITE_TAC [CONJ_SYM] THEN REPEAT CONJ_TAC THENL 1975 [MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 1976 SUBGOAL_THEN ``(h:real->real)(x + y) = h(x) + h(y)`` ASSUME_TAC THENL 1977 [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 1978 REWRITE_TAC[REAL_ARITH 1979 ``(x + y) - (k + l) * a = (x - k * a) + (y - l * a:real)``] THEN 1980 CONJ_TAC THEN MATCH_MP_TAC SPAN_ADD THEN ASM_REWRITE_TAC[] THEN 1981 ASM_SIMP_TAC std_ss [], 1982 ALL_TAC] THEN 1983 ASM_SIMP_TAC std_ss [REAL_ARITH 1984 ``(x + y) - (k + l) * a = (x - k * a) + (y - l * a:real)``] THEN 1985 ASM_SIMP_TAC std_ss [] THEN REAL_ARITH_TAC, 1986 MAP_EVERY X_GEN_TAC [``x:real``, ``c:real``] THEN STRIP_TAC THEN 1987 SUBGOAL_THEN ``(h:real->real)(c * x) = c * h(x)`` ASSUME_TAC THENL 1988 [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 1989 REWRITE_TAC[REAL_ARITH 1990 ``c * x - (c * k) * a = c * (x - k * a:real)``] THEN 1991 CONJ_TAC THEN MATCH_MP_TAC SPAN_MUL THEN ASM_REWRITE_TAC[] THEN 1992 ASM_SIMP_TAC std_ss [], 1993 ALL_TAC] THEN 1994 ASM_SIMP_TAC std_ss [REAL_ARITH 1995 ``c * x - (c * k) * a = c * (x - k * a:real)``] THEN 1996 ASM_SIMP_TAC std_ss [] THEN REAL_ARITH_TAC, 1997 ALL_TAC] THEN 1998 X_GEN_TAC ``x:real`` THEN SIMP_TAC std_ss [IN_INSERT] THEN 1999 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THENL 2000 [SUBGOAL_THEN ``&1:real = h(a:real)`` (SUBST1_TAC o SYM) THENL 2001 [FIRST_X_ASSUM MATCH_MP_TAC, ALL_TAC] THEN 2002 REWRITE_TAC[REAL_ARITH ``a - &1 * a = 0:real``, SPAN_0] THENL 2003 [ASM_MESON_TAC[SPAN_SUPERSET, SUBSET_DEF, IN_INSERT], ALL_TAC] THEN 2004 UNDISCH_TAC ``!x y:real. x IN span b /\ y IN span b ==> 2005 ((g:real->real) (x + y) = g x + g y)`` THEN 2006 DISCH_TAC THEN SIMP_TAC std_ss [] THEN 2007 FIRST_X_ASSUM(MP_TAC o SPECL [``0:real``, ``0:real``]) THEN 2008 SIMP_TAC real_ss [SPAN_0, REAL_ADD_LID] THEN 2009 REWRITE_TAC[REAL_ARITH ``(a = a + a) <=> (a = 0:real)``] THEN 2010 DISCH_THEN SUBST1_TAC THEN REAL_ARITH_TAC, 2011 ALL_TAC] THEN 2012 SUBGOAL_THEN ``&0:real = h(x:real)`` (SUBST1_TAC o SYM) THENL 2013 [FIRST_X_ASSUM MATCH_MP_TAC, ALL_TAC] THEN 2014 SIMP_TAC std_ss [REAL_ADD_LID, REAL_MUL_LZERO, REAL_SUB_RZERO] THEN 2015 ASM_MESON_TAC[SUBSET_DEF, IN_INSERT, SPAN_SUPERSET]); 2016 2017val LINEAR_INDEPENDENT_EXTEND = store_thm ("LINEAR_INDEPENDENT_EXTEND", 2018 ``!f b. independent b ==> ?g:real->real. linear g /\ (!x. x IN b ==> (g x = f x))``, 2019 REPEAT STRIP_TAC THEN 2020 MP_TAC(ISPECL [``b:real->bool``, ``univ(:real)``] 2021 MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN 2022 ASM_SIMP_TAC std_ss [SUBSET_UNIV, UNIV_SUBSET] THEN 2023 REWRITE_TAC[EXTENSION, IN_UNIV] THEN 2024 DISCH_THEN(X_CHOOSE_THEN ``c:real->bool`` STRIP_ASSUME_TAC) THEN 2025 MP_TAC(ISPECL [``f:real->real``, ``c:real->bool``] 2026 LINEAR_INDEPENDENT_EXTEND_LEMMA) THEN 2027 ASM_SIMP_TAC std_ss [INDEPENDENT_BOUND, linear] THEN 2028 ASM_MESON_TAC[SUBSET_DEF]); 2029 2030val SUBSPACE_KERNEL = store_thm ("SUBSPACE_KERNEL", 2031 ``!f. linear f ==> subspace {x | f(x) = 0}``, 2032 SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN 2033 SIMP_TAC std_ss [LINEAR_ADD, LINEAR_CMUL, REAL_ADD_LID, REAL_MUL_RZERO] THEN 2034 MESON_TAC[LINEAR_0]); 2035 2036val LINEAR_EQ_0_SPAN = store_thm ("LINEAR_EQ_0_SPAN", 2037 ``!f:real->real b. linear f /\ (!x. x IN b ==> (f(x) = 0)) 2038 ==> !x. x IN span(b) ==> (f(x) = 0)``, 2039 REPEAT GEN_TAC THEN STRIP_TAC THEN RULE_ASSUM_TAC(SIMP_RULE std_ss [IN_DEF]) THEN 2040 ONCE_REWRITE_TAC [METIS [] ``(f x = 0) = (\x. (f:real->real) x = 0) x``] THEN 2041 MATCH_MP_TAC SPAN_INDUCT THEN ASM_SIMP_TAC std_ss [IN_DEF] THEN 2042 MP_TAC(ISPEC ``f:real->real`` SUBSPACE_KERNEL) THEN ASM_REWRITE_TAC[] THEN 2043 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 2044 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_DEF]); 2045 2046val LINEAR_EQ_0 = store_thm ("LINEAR_EQ_0", 2047 ``!f b s. linear f /\ s SUBSET (span b) /\ 2048 (!x. x IN b ==> (f(x) = 0)) ==> !x. x IN s ==> (f(x) = 0)``, 2049 MESON_TAC[LINEAR_EQ_0_SPAN, SUBSET_DEF]); 2050 2051val LINEAR_EQ = store_thm ("LINEAR_EQ", 2052 ``!f g b s. linear f /\ linear g /\ s SUBSET (span b) /\ 2053 (!x. x IN b ==> (f(x) = g(x))) ==> !x. x IN s ==> (f(x) = g(x))``, 2054 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN STRIP_TAC THEN 2055 ONCE_REWRITE_TAC [METIS [] ``(f x - g x = 0) = ((\x. (f:real->real) x - g x) x = 0)``] THEN 2056 MATCH_MP_TAC LINEAR_EQ_0 THEN SIMP_TAC std_ss [] THEN METIS_TAC[LINEAR_COMPOSE_SUB]); 2057 2058val LINEAR_EQ_STDBASIS = store_thm ("LINEAR_EQ_STDBASIS", 2059 ``!f:real->real g. linear f /\ linear g /\ 2060 (!i. 1 <= i /\ i <= 1 ==> (f i = g i)) ==> (f = g)``, 2061 REPEAT STRIP_TAC THEN 2062 SUBGOAL_THEN ``!x. x IN UNIV ==> ((f:real->real) x = g x)`` 2063 (fn th => MP_TAC th THEN SIMP_TAC std_ss [FUN_EQ_THM, IN_UNIV]) THEN 2064 MATCH_MP_TAC LINEAR_EQ THEN 2065 EXISTS_TAC ``{i :real | 1 <= i /\ i <= 1}`` THEN 2066 ASM_SIMP_TAC std_ss [SUBSET_REFL, GSPECIFICATION] THEN 2067 REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2] THEN 2068 KNOW_TAC ``span {1} = univ(:real)`` THENL 2069 [ALL_TAC, SIMP_TAC std_ss [SUBSET_REFL]] THEN 2070 SIMP_TAC std_ss [EXTENSION, span, hull, IN_BIGINTER, IN_UNIV] THEN 2071 SIMP_TAC std_ss [SING_SUBSET, GSPECIFICATION, subspace] THEN 2072 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_RID] THEN 2073 FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC []); 2074 2075val LINEAR_INJECTIVE_LEFT_INVERSE = store_thm ("LINEAR_INJECTIVE_LEFT_INVERSE", 2076 ``!f:real->real. linear f /\ (!x y. (f x = f y) ==> (x = y)) 2077 ==> ?g. linear g /\ (g o f = (\x. x))``, 2078 REWRITE_TAC[INJECTIVE_LEFT_INVERSE] THEN REPEAT STRIP_TAC THEN 2079 SUBGOAL_THEN ``?h. linear(h:real->real) /\ 2080 !x. x IN IMAGE (f:real->real) {i | 1 <= i /\ i <= 1} 2081 ==> (h x = g x)`` MP_TAC THENL 2082 [MATCH_MP_TAC LINEAR_INDEPENDENT_EXTEND THEN 2083 SIMP_TAC std_ss [REAL_LE_ANTISYM, GSPEC_EQ2, IMAGE_SING] THEN 2084 SIMP_TAC std_ss [INDEPENDENT_SING] THEN 2085 KNOW_TAC ``?g. !x. g ((f:real->real) x) = x`` THENL 2086 [METIS_TAC [], REWRITE_TAC [GSYM INJECTIVE_LEFT_INVERSE] THEN DISCH_TAC] THEN 2087 FULL_SIMP_TAC std_ss [linear] THEN KNOW_TAC ``0 = (f:real->real) 0`` THENL 2088 [UNDISCH_TAC ``!c x. (f:real->real) (c * x) = c * f x`` THEN 2089 DISCH_THEN (MP_TAC o SPECL [``0:real``, ``0:real``]) THEN REAL_ARITH_TAC, 2090 DISCH_TAC THEN ONCE_ASM_REWRITE_TAC []] THEN DISCH_TAC THEN 2091 UNDISCH_TAC ``!x y. ((f:real->real) x = f y) ==> (x = y)`` THEN 2092 DISCH_THEN (MP_TAC o SPECL [``1:real``,``0:real``]) THEN 2093 POP_ASSUM MP_TAC THEN REAL_ARITH_TAC, 2094 DISCH_THEN (X_CHOOSE_TAC ``h:real->real``) THEN EXISTS_TAC ``h:real->real`` THEN 2095 POP_ASSUM MP_TAC THEN 2096 ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE, GSPECIFICATION] THEN STRIP_TAC THEN 2097 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LINEAR_EQ_STDBASIS THEN 2098 ASM_SIMP_TAC std_ss [LINEAR_ID, LINEAR_COMPOSE, LINEAR_ID, o_THM] THEN 2099 ASM_MESON_TAC[]]); 2100 2101val dim = new_definition ("dim", 2102 ``dim v = @n. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\ 2103 b HAS_SIZE n``); 2104 2105val BASIS_EXISTS = store_thm ("BASIS_EXISTS", 2106 ``!v. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\ b HAS_SIZE (dim v)``, 2107 GEN_TAC THEN REWRITE_TAC[dim] THEN CONV_TAC SELECT_CONV THEN 2108 MESON_TAC[MAXIMAL_INDEPENDENT_SUBSET, HAS_SIZE, INDEPENDENT_BOUND]); 2109 2110val INDEPENDENT_CARD_LE_DIM = store_thm ("INDEPENDENT_CARD_LE_DIM", 2111 ``!v b:real->bool. b SUBSET v /\ independent b ==> FINITE b /\ CARD(b) <= dim v``, 2112 METIS_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, HAS_SIZE, SUBSET_TRANS]); 2113 2114val CARD_GE_DIM_INDEPENDENT = store_thm ("CARD_GE_DIM_INDEPENDENT", 2115 ``!v b:real->bool. b SUBSET v /\ independent b /\ dim v <= CARD(b) 2116 ==> v SUBSET (span b)``, 2117 REPEAT STRIP_TAC THEN 2118 SUBGOAL_THEN ``!a:real. ~(a IN v /\ ~(a IN span b))`` MP_TAC THENL 2119 [ALL_TAC, SET_TAC[]] THEN 2120 X_GEN_TAC ``a:real`` THEN STRIP_TAC THEN 2121 SUBGOAL_THEN ``independent((a:real) INSERT b)`` ASSUME_TAC THENL 2122 [METIS_TAC[INDEPENDENT_INSERT], ALL_TAC] THEN 2123 MP_TAC(ISPECL [``v:real->bool``, ``(a:real) INSERT b``] 2124 INDEPENDENT_CARD_LE_DIM) THEN 2125 ASM_SIMP_TAC std_ss [INSERT_SUBSET, CARD_EMPTY, CARD_INSERT, INDEPENDENT_BOUND] THEN 2126 METIS_TAC[SPAN_SUPERSET, SUBSET_DEF, ARITH_PROVE 2127 ``x <= y ==> ~(SUC y <= x)``]); 2128 2129val SPAN_EXPLICIT = store_thm ("SPAN_EXPLICIT", 2130 ``!(p:real -> bool). span p = 2131 {y | ?s u. FINITE s /\ s SUBSET p /\ (sum s (\v. u v * v) = y)}``, 2132 GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 2133 [ALL_TAC, 2134 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN 2135 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN 2136 MATCH_MP_TAC SPAN_SUM THEN ASM_REWRITE_TAC[] THEN 2137 ASM_MESON_TAC[SPAN_SUPERSET, SPAN_MUL]] THEN 2138 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN 2139 ONCE_REWRITE_TAC [METIS [] 2140 ``(?s u. FINITE s /\ (!x. x IN s ==> x IN p) /\ (sum s (\v. u v * v) = x)) = 2141 (\x. ?s u. FINITE s /\ (!x. x IN s ==> x IN p) /\ (sum s (\v. u v * v) = x)) x``] THEN 2142 MATCH_MP_TAC SPAN_INDUCT_ALT THEN SIMP_TAC std_ss [] THEN CONJ_TAC THENL 2143 [EXISTS_TAC ``{}:real->bool`` THEN 2144 SIMP_TAC std_ss [FINITE_EMPTY, FINITE_INSERT, SUM_CLAUSES, 2145 EMPTY_SUBSET, NOT_IN_EMPTY], ALL_TAC] THEN 2146 MAP_EVERY X_GEN_TAC [``c:real``, ``x:real``, ``y:real``] THEN 2147 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 2148 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 2149 MAP_EVERY X_GEN_TAC [``s:real->bool``, ``u:real->real``] THEN 2150 STRIP_TAC THEN EXISTS_TAC ``(x:real) INSERT s`` THEN 2151 EXISTS_TAC ``\y. if y = x then (if x IN s then (u:real->real) y + c else c) 2152 else u y`` THEN 2153 ASM_SIMP_TAC std_ss [FINITE_INSERT, IN_INSERT, SUM_CLAUSES] THEN 2154 CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC] THEN 2155 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN 2156 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL 2157 [FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE 2158 ``x IN s ==> (s = x INSERT (s DELETE x))``)) THEN 2159 ASM_SIMP_TAC std_ss [SUM_CLAUSES, FINITE_INSERT, FINITE_DELETE, IN_DELETE] THEN 2160 MATCH_MP_TAC(REAL_ARITH 2161 ``(y = z) ==> ((c + d) * x + y = d * x + (c * x + z:real))``), 2162 AP_TERM_TAC] THEN 2163 MATCH_MP_TAC SUM_EQ THEN METIS_TAC[IN_DELETE]); 2164 2165val DEPENDENT_EXPLICIT = store_thm ("DEPENDENT_EXPLICIT", 2166 ``!p. dependent (p:real -> bool) <=> 2167 ?s u. FINITE s /\ s SUBSET p /\ (?v. v IN s /\ ~(u v = &0)) /\ 2168 (sum s (\v. u v * v) = 0)``, 2169 GEN_TAC THEN SIMP_TAC std_ss [dependent, SPAN_EXPLICIT, GSPECIFICATION] THEN 2170 SIMP_TAC std_ss [GSYM RIGHT_EXISTS_AND_THM, GSYM LEFT_EXISTS_AND_THM] THEN 2171 EQ_TAC THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THENL 2172 [MAP_EVERY X_GEN_TAC [``s:real->bool``, ``u:real->real``] THEN 2173 STRIP_TAC THEN ABBREV_TAC ``a = sum s (\v. (u:real->real) v * v)`` THEN 2174 MAP_EVERY EXISTS_TAC 2175 [``(a:real) INSERT s``, 2176 ``\y. if y = a then - &1 else (u:real->real) y``, 2177 ``a:real``] THEN 2178 ASM_REWRITE_TAC[IN_INSERT, INSERT_SUBSET, FINITE_INSERT] THEN 2179 CONJ_TAC THENL [ASM_SET_TAC[], ASM_SIMP_TAC real_ss []] THEN 2180 ASM_SIMP_TAC std_ss [SUM_CLAUSES] THEN 2181 COND_CASES_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 2182 REWRITE_TAC[REAL_ARITH ``(-&1 * a + s = 0) <=> (a = s:real)``] THEN 2183 FIRST_X_ASSUM(fn th => GEN_REWR_TAC LAND_CONV [SYM th]) THEN 2184 MATCH_MP_TAC SUM_EQ THEN ASM_SET_TAC[], 2185 MAP_EVERY X_GEN_TAC [``s:real->bool``, ``u:real->real``, ``a:real``] THEN 2186 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 2187 [``s DELETE (a:real)``, 2188 ``\i. -((u:real->real) i) / (u (a:real))``] THEN 2189 ASM_SIMP_TAC std_ss [SUM_DELETE, FINITE_DELETE] THEN 2190 KNOW_TAC ``sum s (\v. -u v / (u:real->real) a * v) - -u a / u a * a = a`` THENL 2191 [REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN 2192 REWRITE_TAC [REAL_MUL_ASSOC] THEN SIMP_TAC real_ss [SUM_RMUL, SUM_NEG] THEN 2193 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_MUL_SYM]) THEN ASM_REWRITE_TAC [] THEN 2194 ASM_SIMP_TAC real_ss [REAL_MUL_LNEG, GSYM REAL_MUL_ASSOC, 2195 REAL_MUL_RNEG, REAL_MUL_RZERO] THEN 2196 ASM_SIMP_TAC real_ss [REAL_MUL_RINV], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 2197 ASM_SET_TAC []]); 2198 2199val INDEPENDENT_INJECTIVE_IMAGE_GEN = store_thm ("INDEPENDENT_INJECTIVE_IMAGE_GEN", 2200 ``!f:real->real s. independent s /\ linear f /\ 2201 (!x y. x IN span s /\ y IN span s /\ (f(x) = f(y)) ==> (x = y)) 2202 ==> independent (IMAGE f s)``, 2203 REPEAT GEN_TAC THEN 2204 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN 2205 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 2206 SIMP_TAC std_ss [independent, DEPENDENT_EXPLICIT] THEN 2207 REWRITE_TAC[CONJ_ASSOC, FINITE_SUBSET_IMAGE] THEN DISCH_TAC THEN 2208 KNOW_TAC ``(?s':real->bool u:real->real. (FINITE s' /\ s' SUBSET s) /\ 2209 (?v. v IN IMAGE f s' /\ ~(u v = &0)) /\ 2210 (sum (IMAGE f s') (\v. u v * v) = 0))`` THENL 2211 [METIS_TAC [], POP_ASSUM K_TAC] THEN 2212 SIMP_TAC std_ss [EXISTS_IN_IMAGE, LEFT_IMP_EXISTS_THM] THEN 2213 MAP_EVERY X_GEN_TAC [``t:real->bool``, ``u:real->real``] THEN 2214 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 2215 MAP_EVERY EXISTS_TAC 2216 [``t:real->bool``, ``(u:real->real) o (f:real->real)``] THEN 2217 ASM_REWRITE_TAC[o_THM] THEN 2218 FIRST_ASSUM MATCH_MP_TAC THEN REPEAT CONJ_TAC THENL 2219 [MATCH_MP_TAC SPAN_SUM THEN ASM_SIMP_TAC std_ss [] THEN 2220 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN 2221 MATCH_MP_TAC SPAN_SUPERSET THEN ASM_SET_TAC[], 2222 REWRITE_TAC[SPAN_0], 2223 ASM_SIMP_TAC std_ss [LINEAR_SUM] THEN 2224 FIRST_ASSUM(SUBST1_TAC o MATCH_MP LINEAR_0) THEN 2225 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN CONV_TAC SYM_CONV THEN 2226 W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o lhand o snd) THEN 2227 ASM_SIMP_TAC std_ss [o_DEF] THEN ASM_SIMP_TAC std_ss [LINEAR_CMUL] THEN 2228 DISCH_THEN MATCH_MP_TAC THEN ASM_MESON_TAC[SPAN_SUPERSET, SUBSET_DEF]]); 2229 2230val INDEPENDENT_INJECTIVE_IMAGE = store_thm ("INDEPENDENT_INJECTIVE_IMAGE", 2231 ``!f:real->real s. independent s /\ linear f /\ 2232 (!x y. (f(x) = f(y)) ==> (x = y)) ==> independent (IMAGE f s)``, 2233 REPEAT STRIP_TAC THEN MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN 2234 ASM_MESON_TAC[]); 2235 2236val SPAN_LINEAR_IMAGE = store_thm ("SPAN_LINEAR_IMAGE", 2237 ``!f:real->real s. linear f ==> (span(IMAGE f s) = IMAGE f (span s))``, 2238 REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 2239 X_GEN_TAC ``x:real`` THEN EQ_TAC THENL 2240 [ONCE_REWRITE_TAC [METIS [] ``x IN IMAGE f (span s) = 2241 (\x. x IN IMAGE f (span s)) x``] THEN 2242 SPEC_TAC(``x:real``, ``x:real``) THEN MATCH_MP_TAC SPAN_INDUCT THEN 2243 SIMP_TAC std_ss [SET_RULE ``(\x. x IN s) = s``] THEN 2244 ASM_SIMP_TAC std_ss [SUBSPACE_SPAN, SUBSPACE_LINEAR_IMAGE] THEN 2245 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN 2246 MESON_TAC[SPAN_SUPERSET, SUBSET_DEF], 2247 SPEC_TAC(``x:real``, ``x:real``) THEN SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 2248 ONCE_REWRITE_TAC [METIS [] ``f x IN span (IMAGE f s) = 2249 (\x. f x IN span (IMAGE f s)) x``] THEN 2250 MATCH_MP_TAC SPAN_INDUCT THEN 2251 SIMP_TAC std_ss [SET_RULE ``(\x. f x IN span(s)) = {x | f(x) IN span s}``] THEN 2252 ASM_SIMP_TAC std_ss [SUBSPACE_LINEAR_PREIMAGE, SUBSPACE_SPAN] THEN 2253 SIMP_TAC std_ss [GSPECIFICATION] THEN 2254 MESON_TAC[SPAN_SUPERSET, SUBSET_DEF, IN_IMAGE]]); 2255 2256(* ------------------------------------------------------------------------- *) 2257(* An injective map real->real is also surjective. *) 2258(* ------------------------------------------------------------------------- *) 2259 2260val LINEAR_INJECTIVE_IMP_SURJECTIVE = store_thm ("LINEAR_INJECTIVE_IMP_SURJECTIVE", 2261 ``!f:real->real. linear f /\ (!x y. (f(x) = f(y)) ==> (x = y)) 2262 ==> !y. ?x. f(x) = y``, 2263 REPEAT STRIP_TAC THEN 2264 MP_TAC(ISPEC ``univ(:real)`` BASIS_EXISTS) THEN 2265 REWRITE_TAC[SUBSET_UNIV, HAS_SIZE] THEN 2266 DISCH_THEN(X_CHOOSE_THEN ``b:real->bool`` STRIP_ASSUME_TAC) THEN 2267 SUBGOAL_THEN ``UNIV SUBSET span(IMAGE (f:real->real) b)`` MP_TAC THENL 2268 [MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN 2269 ASM_MESON_TAC[INDEPENDENT_INJECTIVE_IMAGE, LESS_EQ_REFL, 2270 SUBSET_UNIV, CARD_IMAGE_INJ], 2271 ASM_SIMP_TAC std_ss [SPAN_LINEAR_IMAGE] THEN 2272 ASM_MESON_TAC[SUBSET_DEF, IN_IMAGE, IN_UNIV]]); 2273 2274(* ------------------------------------------------------------------------- *) 2275(* Left-invertible linear transformation has a lower bound. *) 2276(* ------------------------------------------------------------------------- *) 2277 2278val LINEAR_INVERTIBLE_BOUNDED_BELOW_POS = store_thm ("LINEAR_INVERTIBLE_BOUNDED_BELOW_POS", 2279 ``!f:real->real g. linear f /\ linear g /\ (g o f = I) 2280 ==> ?B. &0 < B /\ !x. B * abs(x) <= abs(f x)``, 2281 REPEAT STRIP_TAC THEN 2282 MP_TAC(ISPEC ``g:real->real`` LINEAR_BOUNDED_POS) THEN 2283 ASM_REWRITE_TAC[] THEN 2284 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 2285 EXISTS_TAC ``inv B:real`` THEN ASM_SIMP_TAC real_ss [REAL_LT_INV_EQ] THEN 2286 X_GEN_TAC ``x:real`` THEN MATCH_MP_TAC REAL_LE_TRANS THEN 2287 EXISTS_TAC ``inv(B) * abs(((g:real->real) o (f:real->real)) x)`` THEN 2288 CONJ_TAC THENL [ASM_SIMP_TAC real_ss [I_THM, REAL_LE_REFL], ALL_TAC] THEN 2289 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN 2290 ASM_SIMP_TAC real_ss [o_THM, REAL_LE_LDIV_EQ] THEN 2291 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_REWRITE_TAC[]); 2292 2293val LINEAR_INVERTIBLE_BOUNDED_BELOW = store_thm ("LINEAR_INVERTIBLE_BOUNDED_BELOW", 2294 ``!f:real->real g. linear f /\ linear g /\ (g o f = I) ==> 2295 ?B. !x. B * abs(x) <= abs(f x)``, 2296 MESON_TAC[LINEAR_INVERTIBLE_BOUNDED_BELOW_POS]); 2297 2298val LINEAR_INJECTIVE_BOUNDED_BELOW_POS = store_thm ("LINEAR_INJECTIVE_BOUNDED_BELOW_POS", 2299 ``!f:real->real. linear f /\ (!x y. (f x = f y) ==> (x = y)) 2300 ==> ?B. &0 < B /\ !x. abs(x) * B <= abs(f x)``, 2301 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN 2302 MATCH_MP_TAC LINEAR_INVERTIBLE_BOUNDED_BELOW_POS THEN 2303 METIS_TAC[LINEAR_INJECTIVE_LEFT_INVERSE, I_THM]); 2304 2305(* ------------------------------------------------------------------------- *) 2306(* Consequences of independence or spanning for cardinality. *) 2307(* ------------------------------------------------------------------------- *) 2308 2309val INDEPENDENT_CARD_LE_DIM = store_thm ("INDEPENDENT_CARD_LE_DIM", 2310 ``!v b:real->bool. b SUBSET v /\ independent b ==> FINITE b /\ CARD(b) <= dim v``, 2311 METIS_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, HAS_SIZE, SUBSET_TRANS]); 2312 2313val SPAN_CARD_GE_DIM = store_thm ("SPAN_CARD_GE_DIM", 2314 ``!v b:real->bool. v SUBSET (span b) /\ FINITE b ==> dim(v) <= CARD(b)``, 2315 METIS_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, HAS_SIZE, SUBSET_TRANS]); 2316 2317val BASIS_CARD_EQ_DIM = store_thm ("BASIS_CARD_EQ_DIM", 2318 ``!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b 2319 ==> FINITE b /\ (CARD b = dim v)``, 2320 METIS_TAC[LESS_EQUAL_ANTISYM, INDEPENDENT_CARD_LE_DIM, SPAN_CARD_GE_DIM]); 2321 2322val BASIS_HAS_SIZE_DIM = store_thm ("BASIS_HAS_SIZE_DIM", 2323 ``!v b. independent b /\ (span b = v) ==> b HAS_SIZE (dim v)``, 2324 REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_SIZE] THEN 2325 MATCH_MP_TAC BASIS_CARD_EQ_DIM THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN 2326 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[SPAN_INC]); 2327 2328val DIM_UNIQUE = store_thm ("DIM_UNIQUE", 2329 ``!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b /\ b HAS_SIZE n 2330 ==> (dim v = n)``, 2331 MESON_TAC[BASIS_CARD_EQ_DIM, HAS_SIZE]); 2332 2333val DIM_LE_CARD = store_thm ("DIM_LE_CARD", 2334 ``!s. FINITE s ==> dim s <= CARD s``, 2335 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN 2336 ASM_REWRITE_TAC[SPAN_INC, SUBSET_REFL]); 2337 2338(* ------------------------------------------------------------------------- *) 2339(* Standard bases are a spanning set, and obviously finite. *) 2340(* ------------------------------------------------------------------------- *) 2341 2342val SPAN_STDBASIS = store_thm ("SPAN_STDBASIS", 2343 ``span {i :real | 1 <= i /\ i <= 1} = UNIV``, 2344 REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2] THEN 2345 SIMP_TAC std_ss [EXTENSION, span, hull, IN_BIGINTER, IN_UNIV] THEN 2346 SIMP_TAC std_ss [SING_SUBSET, GSPECIFICATION, subspace] THEN 2347 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_RID] THEN 2348 FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC []); 2349 2350val HAS_SIZE_STDBASIS = store_thm ("HAS_SIZE_STDBASIS", 2351 ``{i :real | 1 <= i /\ i <= 1} HAS_SIZE 1``, 2352 REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2, HAS_SIZE] THEN 2353 REWRITE_TAC [FINITE_SING, CARD_SING]); 2354 2355(* ------------------------------------------------------------------------- *) 2356(* More lemmas about dimension. *) 2357(* ------------------------------------------------------------------------- *) 2358 2359val DIM_UNIV = store_thm ("DIM_UNIV", 2360 ``dim univ(:real) = 1:num``, 2361 MATCH_MP_TAC DIM_UNIQUE THEN EXISTS_TAC ``{i :real | &1 <= i /\ i <= &1}`` THEN 2362 REWRITE_TAC[SUBSET_UNIV, SPAN_STDBASIS, HAS_SIZE_STDBASIS, INDEPENDENT_STDBASIS]); 2363 2364val DIM_SUBSET = store_thm ("DIM_SUBSET", 2365 ``!s t:real->bool. s SUBSET t ==> dim(s) <= dim(t)``, 2366 MESON_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, SUBSET_DEF, HAS_SIZE]); 2367 2368val DIM_SUBSET_UNIV = store_thm ("DIM_SUBSET_UNIV", 2369 ``!s:real->bool. dim(s) <= (1:num)``, 2370 GEN_TAC THEN REWRITE_TAC[GSYM DIM_UNIV] THEN 2371 MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]); 2372 2373(* ------------------------------------------------------------------------- *) 2374(* General notion of a topology. (moved to real/topologyTheory) *) 2375(* ------------------------------------------------------------------------- *) 2376 2377(* ------------------------------------------------------------------------- *) 2378(* Open sets. (moved to real/topologyTheory) *) 2379(* ------------------------------------------------------------------------- *) 2380 2381(* ------------------------------------------------------------------------- *) 2382(* Closed sets. (moved to real/topologyTheory) *) 2383(* ------------------------------------------------------------------------- *) 2384 2385(* ------------------------------------------------------------------------- *) 2386(* Subspace topology. *) 2387(* ------------------------------------------------------------------------- *) 2388 2389val subtopology = new_definition ("subtopology", 2390 ``subtopology top u = topology {s INTER u | open_in top s}``); 2391 2392val SUBSET_IMAGE = store_thm ("SUBSET_IMAGE", 2393 ``!f:'a->'b s t. s SUBSET (IMAGE f t) <=> ?u. u SUBSET t /\ (s = IMAGE f u)``, 2394 REPEAT GEN_TAC THEN EQ_TAC THENL [ALL_TAC, MESON_TAC[IMAGE_SUBSET]] THEN 2395 DISCH_TAC THEN EXISTS_TAC ``{x | x IN t /\ (f:'a->'b) x IN s}`` THEN 2396 POP_ASSUM MP_TAC THEN 2397 SIMP_TAC std_ss [EXTENSION, SUBSET_DEF, IN_IMAGE, GSPECIFICATION] THEN 2398 MESON_TAC[]); 2399 2400val INTER_BIGUNION = store_thm ("INTER_BIGUNION", 2401 ``(!s t. BIGUNION s INTER t = BIGUNION {x INTER t | x IN s}) /\ 2402 (!s t. t INTER BIGUNION s = BIGUNION {t INTER x | x IN s})``, 2403 ONCE_REWRITE_TAC[EXTENSION] THEN 2404 SIMP_TAC std_ss [IN_BIGUNION, GSPECIFICATION, IN_INTER] THEN 2405 MESON_TAC[IN_INTER]); 2406 2407val ISTOPLOGY_SUBTOPOLOGY = store_thm ("ISTOPLOGY_SUBTOPOLOGY", 2408 ``!top u:'a->bool. istopology {s INTER u | open_in top s}``, 2409 REWRITE_TAC[istopology, SET_RULE 2410 ``{s INTER u | open_in top s} = 2411 IMAGE (\s. s INTER u) {s | open_in top s}``] THEN 2412 SIMP_TAC std_ss [GSYM AND_IMP_INTRO, FORALL_IN_IMAGE, RIGHT_FORALL_IMP_THM] THEN 2413 SIMP_TAC std_ss [SUBSET_IMAGE, IN_IMAGE, GSPECIFICATION, SUBSET_DEF] THEN 2414 REPEAT GEN_TAC THEN REPEAT CONJ_TAC THENL 2415 [EXISTS_TAC ``{}:'a->bool`` THEN REWRITE_TAC[OPEN_IN_EMPTY, INTER_EMPTY], 2416 SIMP_TAC std_ss [SET_RULE ``(s INTER u) INTER (t INTER u) = (s INTER t) INTER u``] THEN 2417 ASM_MESON_TAC[OPEN_IN_INTER], 2418 X_GEN_TAC ``f:('a->bool)->bool`` THEN DISCH_THEN (X_CHOOSE_TAC ``g:('a->bool)->bool``) THEN 2419 EXISTS_TAC ``BIGUNION g :'a->bool`` THEN 2420 ASM_SIMP_TAC std_ss [OPEN_IN_BIGUNION, INTER_BIGUNION] THEN SET_TAC[]]); 2421 2422val OPEN_IN_SUBTOPOLOGY = store_thm ("OPEN_IN_SUBTOPOLOGY", 2423 ``!top u s. open_in (subtopology top u) s <=> 2424 ?t. open_in top t /\ (s = t INTER u)``, 2425 REWRITE_TAC[subtopology] THEN 2426 SIMP_TAC std_ss [REWRITE_RULE[CONJUNCT2 topology_tybij] ISTOPLOGY_SUBTOPOLOGY] THEN 2427 GEN_REWR_TAC (QUANT_CONV o QUANT_CONV o QUANT_CONV o LAND_CONV) [GSYM SPECIFICATION] THEN 2428 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION] THEN METIS_TAC []); 2429 2430val TOPSPACE_SUBTOPOLOGY = store_thm ("TOPSPACE_SUBTOPOLOGY", 2431 ``!top u. topspace(subtopology top u) = topspace top INTER u``, 2432 REWRITE_TAC[topspace, OPEN_IN_SUBTOPOLOGY, INTER_BIGUNION] THEN 2433 REPEAT STRIP_TAC THEN AP_TERM_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 2434 SIMP_TAC std_ss [GSPECIFICATION] THEN METIS_TAC []); 2435 2436val CLOSED_IN_SUBTOPOLOGY = store_thm ("CLOSED_IN_SUBTOPOLOGY", 2437 ``!top u s. closed_in (subtopology top u) s <=> 2438 ?t:'a->bool. closed_in top t /\ (s = t INTER u)``, 2439 REWRITE_TAC[closed_in, TOPSPACE_SUBTOPOLOGY] THEN 2440 SIMP_TAC std_ss [SUBSET_INTER, OPEN_IN_SUBTOPOLOGY, GSYM RIGHT_EXISTS_AND_THM] THEN 2441 REPEAT STRIP_TAC THEN EQ_TAC THEN 2442 DISCH_THEN(X_CHOOSE_THEN ``t:'a->bool`` STRIP_ASSUME_TAC) THEN 2443 EXISTS_TAC ``topspace top DIFF t :'a->bool`` THEN 2444 ASM_SIMP_TAC std_ss [CLOSED_IN_TOPSPACE, OPEN_IN_DIFF, CLOSED_IN_DIFF, 2445 OPEN_IN_TOPSPACE] THEN 2446 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 2447 2448val OPEN_IN_SUBTOPOLOGY_EMPTY = store_thm ("OPEN_IN_SUBTOPOLOGY_EMPTY", 2449 ``!top s. open_in (subtopology top {}) s <=> (s = {})``, 2450 REWRITE_TAC[OPEN_IN_SUBTOPOLOGY, INTER_EMPTY] THEN 2451 MESON_TAC[OPEN_IN_EMPTY]); 2452 2453val CLOSED_IN_SUBTOPOLOGY_EMPTY = store_thm ("CLOSED_IN_SUBTOPOLOGY_EMPTY", 2454 ``!top s. closed_in (subtopology top {}) s <=> (s = {})``, 2455 REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY, INTER_EMPTY] THEN 2456 MESON_TAC[CLOSED_IN_EMPTY]); 2457 2458val OPEN_IN_SUBTOPOLOGY_REFL = store_thm ("OPEN_IN_SUBTOPOLOGY_REFL", 2459 ``!top u:'a->bool. open_in (subtopology top u) u <=> u SUBSET topspace top``, 2460 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_SUBTOPOLOGY] THEN EQ_TAC THENL 2461 [REPEAT STRIP_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN 2462 MATCH_MP_TAC(SET_RULE ``s SUBSET u ==> s INTER t SUBSET u``) THEN 2463 ASM_SIMP_TAC std_ss [OPEN_IN_SUBSET], 2464 DISCH_TAC THEN EXISTS_TAC ``topspace top:'a->bool`` THEN 2465 REWRITE_TAC[OPEN_IN_TOPSPACE] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]); 2466 2467val CLOSED_IN_SUBTOPOLOGY_REFL = store_thm ("CLOSED_IN_SUBTOPOLOGY_REFL", 2468 ``!top u:'a->bool. closed_in (subtopology top u) u <=> u SUBSET topspace top``, 2469 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY] THEN EQ_TAC THENL 2470 [REPEAT STRIP_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN 2471 MATCH_MP_TAC(SET_RULE ``s SUBSET u ==> s INTER t SUBSET u``) THEN 2472 ASM_SIMP_TAC std_ss [CLOSED_IN_SUBSET], 2473 DISCH_TAC THEN EXISTS_TAC ``topspace top:'a->bool`` THEN 2474 REWRITE_TAC[CLOSED_IN_TOPSPACE] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]); 2475 2476val SUBTOPOLOGY_SUPERSET = store_thm ("SUBTOPOLOGY_SUPERSET", 2477 ``!top s:'a->bool. topspace top SUBSET s ==> (subtopology top s = top)``, 2478 REPEAT GEN_TAC THEN SIMP_TAC std_ss [TOPOLOGY_EQ, OPEN_IN_SUBTOPOLOGY] THEN 2479 DISCH_TAC THEN X_GEN_TAC ``u:'a->bool`` THEN EQ_TAC THENL 2480 [DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 MP_TAC SUBST1_TAC)) THEN 2481 DISCH_THEN(fn th => MP_TAC th THEN 2482 ASSUME_TAC(MATCH_MP OPEN_IN_SUBSET th)) THEN 2483 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN REPEAT (POP_ASSUM MP_TAC) THEN 2484 SET_TAC[], 2485 DISCH_TAC THEN EXISTS_TAC ``u:'a->bool`` THEN 2486 FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_SUBSET) THEN 2487 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]); 2488 2489val SUBTOPOLOGY_TOPSPACE = store_thm ("SUBTOPOLOGY_TOPSPACE", 2490 ``!top. subtopology top (topspace top) = top``, 2491 SIMP_TAC std_ss [SUBTOPOLOGY_SUPERSET, SUBSET_REFL]); 2492 2493val SUBTOPOLOGY_UNIV = store_thm ("SUBTOPOLOGY_UNIV", 2494 ``!top. subtopology top UNIV = top``, 2495 SIMP_TAC std_ss [SUBTOPOLOGY_SUPERSET, SUBSET_UNIV]); 2496 2497val OPEN_IN_IMP_SUBSET = store_thm ("OPEN_IN_IMP_SUBSET", 2498 ``!top s t. open_in (subtopology top s) t ==> t SUBSET s``, 2499 REWRITE_TAC[OPEN_IN_SUBTOPOLOGY] THEN SET_TAC[]); 2500 2501val CLOSED_IN_IMP_SUBSET = store_thm ("CLOSED_IN_IMP_SUBSET", 2502 ``!top s t. closed_in (subtopology top s) t ==> t SUBSET s``, 2503 REWRITE_TAC[closed_in, TOPSPACE_SUBTOPOLOGY] THEN SET_TAC[]); 2504 2505val OPEN_IN_SUBTOPOLOGY_UNION = store_thm ("OPEN_IN_SUBTOPOLOGY_UNION", 2506 ``!top s t u:'a->bool. 2507 open_in (subtopology top t) s /\ open_in (subtopology top u) s 2508 ==> open_in (subtopology top (t UNION u)) s``, 2509 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_SUBTOPOLOGY] THEN 2510 DISCH_THEN(CONJUNCTS_THEN2 2511 (X_CHOOSE_THEN ``s':'a->bool`` STRIP_ASSUME_TAC) 2512 (X_CHOOSE_THEN ``t':'a->bool`` STRIP_ASSUME_TAC)) THEN 2513 EXISTS_TAC ``s' INTER t':'a->bool`` THEN ASM_SIMP_TAC std_ss [OPEN_IN_INTER] THEN 2514 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 2515 2516val CLOSED_IN_SUBTOPOLOGY_UNION = store_thm ("CLOSED_IN_SUBTOPOLOGY_UNION", 2517 ``!top s t u:'a->bool. 2518 closed_in (subtopology top t) s /\ closed_in (subtopology top u) s 2519 ==> closed_in (subtopology top (t UNION u)) s``, 2520 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY] THEN 2521 DISCH_THEN(CONJUNCTS_THEN2 2522 (X_CHOOSE_THEN ``s':'a->bool`` STRIP_ASSUME_TAC) 2523 (X_CHOOSE_THEN ``t':'a->bool`` STRIP_ASSUME_TAC)) THEN 2524 EXISTS_TAC ``s' INTER t':'a->bool`` THEN ASM_SIMP_TAC std_ss [CLOSED_IN_INTER] THEN 2525 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 2526 2527(* ------------------------------------------------------------------------- *) 2528(* OPEN *) 2529(* ------------------------------------------------------------------------- *) 2530 2531val open_def = new_definition ("open_def", 2532 ``Open s <=> !x. x IN s ==> ?e. &0 < e /\ !x'. dist(x',x) < e ==> x' IN s``); 2533 2534val _ = overload_on ("open",``Open``); 2535 2536val closed_def = new_definition ("closed_def", 2537 ``Closed(s:real->bool) <=> open(UNIV DIFF s)``); 2538 2539val _ = overload_on ("closed",``Closed``); 2540 2541val euclidean = new_definition ("euclidean", 2542 ``euclidean = topology open``); 2543 2544val OPEN_EMPTY = store_thm ("OPEN_EMPTY", 2545 ``open {}``, 2546 REWRITE_TAC[open_def, NOT_IN_EMPTY]); 2547 2548val OPEN_UNIV = store_thm ("OPEN_UNIV", 2549 ``open univ(:real)``, 2550 REWRITE_TAC[open_def, IN_UNIV] THEN MESON_TAC[REAL_LT_01]); 2551 2552val OPEN_INTER = store_thm ("OPEN_INTER", 2553 ``!s t. open s /\ open t ==> open (s INTER t)``, 2554 REPEAT GEN_TAC THEN REWRITE_TAC [open_def] THEN 2555 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REWRITE_TAC [IN_INTER] THEN 2556 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN 2557 STRIP_TAC THEN STRIP_TAC THEN FULL_SIMP_TAC real_ss [] THEN 2558 Cases_on `e < e'` THENL [EXISTS_TAC ``e:real`` THEN 2559 ASM_REWRITE_TAC [] THEN GEN_TAC THEN 2560 UNDISCH_TAC (Term `!x'. dist (x',x) < e ==> x' IN s`) THEN 2561 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN RW_TAC std_ss [] THEN 2562 UNDISCH_TAC (Term `!x'. dist (x',x) < e' ==> x' IN t`) THEN 2563 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN 2564 KNOW_TAC ``dist (x',x) < e'`` THENL [MATCH_MP_TAC REAL_LT_TRANS THEN 2565 EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC [], ALL_TAC] THEN 2566 RW_TAC std_ss [] THEN Cases_on `e' < e` THEN 2567 EXISTS_TAC ``e':real`` THEN ASM_REWRITE_TAC [], 2568 Cases_on `e' < e` THENL [EXISTS_TAC ``e':real`` THEN 2569 ASM_REWRITE_TAC [] THEN GEN_TAC THEN 2570 UNDISCH_TAC (Term `!x'. dist (x',x) < e' ==> x' IN t`) THEN 2571 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN 2572 RW_TAC std_ss [] THEN 2573 UNDISCH_TAC (Term `!x'. dist (x',x) < e ==> x' IN s`) THEN 2574 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN 2575 KNOW_TAC ``dist (x',x) < e`` THENL [MATCH_MP_TAC REAL_LT_TRANS THEN 2576 EXISTS_TAC ``e':real`` THEN ASM_REWRITE_TAC [], ALL_TAC] THEN 2577 RW_TAC std_ss [], 2578 FULL_SIMP_TAC std_ss [REAL_NOT_LT] THEN KNOW_TAC ``(e:real) = e'`` THENL 2579 [METIS_TAC [REAL_LE_ANTISYM], ALL_TAC] THEN DISCH_TAC THEN 2580 EXISTS_TAC ``e:real`` THEN CONJ_TAC THEN FULL_SIMP_TAC real_ss []]]); 2581 2582val OPEN_BIGUNION = store_thm ("OPEN_BIGUNION", 2583 ``(!s. s IN f ==> open s) ==> open(BIGUNION f)``, 2584 REWRITE_TAC[open_def, IN_BIGUNION] THEN MESON_TAC[]); 2585 2586val OPEN_EXISTS_IN = store_thm ("OPEN_EXISTS_IN", 2587 ``!P Q:'a->real->bool. 2588 (!a. P a ==> open {x | Q a x}) ==> open {x | ?a. P a /\ Q a x}``, 2589 REPEAT STRIP_TAC THEN 2590 SUBGOAL_THEN ``open(BIGUNION {{x | Q (a:'a) (x:real)} | P a})`` MP_TAC THENL 2591 [MATCH_MP_TAC OPEN_BIGUNION THEN ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN 2592 METIS_TAC [], MATCH_MP_TAC (TAUT `(a <=> b) ==> a ==> b`) THEN AP_TERM_TAC THEN 2593 SIMP_TAC std_ss [EXTENSION, IN_BIGUNION, GSPECIFICATION] THEN 2594 SET_TAC[]]); 2595 2596val OPEN_EXISTS = store_thm ("OPEN_EXISTS", 2597 ``!Q:'a->real->bool. (!a. open {x | Q a x}) ==> open {x | ?a. Q a x}``, 2598 MP_TAC(ISPEC ``\x:'a. T`` OPEN_EXISTS_IN) THEN REWRITE_TAC[]); 2599 2600val OPEN_IN = store_thm ("OPEN_IN", 2601 ``!s:real->bool. open s <=> open_in euclidean s``, 2602 GEN_TAC THEN REWRITE_TAC[euclidean] THEN CONV_TAC SYM_CONV THEN 2603 AP_THM_TAC THEN REWRITE_TAC[GSYM(CONJUNCT2 topology_tybij)] THEN 2604 SIMP_TAC std_ss [REWRITE_RULE[IN_DEF] istopology] THEN 2605 REWRITE_TAC[OPEN_EMPTY, OPEN_INTER, SUBSET_DEF] THEN 2606 MESON_TAC[IN_DEF, OPEN_BIGUNION]); 2607 2608val TOPSPACE_EUCLIDEAN = store_thm ("TOPSPACE_EUCLIDEAN", 2609 ``topspace euclidean = univ(:real)``, 2610 SIMP_TAC std_ss [topspace, EXTENSION, IN_UNIV, IN_BIGUNION, GSPECIFICATION] THEN 2611 MESON_TAC[OPEN_UNIV, IN_UNIV, OPEN_IN]); 2612 2613val TOPSPACE_EUCLIDEAN_SUBTOPOLOGY = store_thm ("TOPSPACE_EUCLIDEAN_SUBTOPOLOGY", 2614 ``!s. topspace (subtopology euclidean s) = s``, 2615 REWRITE_TAC[TOPSPACE_EUCLIDEAN, TOPSPACE_SUBTOPOLOGY, INTER_UNIV]); 2616 2617val OPEN_IN_REFL = store_thm ("OPEN_IN_REFL", 2618 ``!s:real->bool. open_in (subtopology euclidean s) s``, 2619 REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL, TOPSPACE_EUCLIDEAN, SUBSET_UNIV]); 2620 2621val CLOSED_IN_REFL = store_thm ("CLOSED_IN_REFL", 2622 ``!s:real->bool. closed_in (subtopology euclidean s) s``, 2623 REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY_REFL, TOPSPACE_EUCLIDEAN, SUBSET_UNIV]); 2624 2625val CLOSED_IN = store_thm ("CLOSED_IN", 2626 ``!s:real->bool. closed s <=> closed_in euclidean s``, 2627 REWRITE_TAC[closed_def, closed_in, TOPSPACE_EUCLIDEAN, OPEN_IN, SUBSET_UNIV]); 2628 2629val OPEN_UNION = store_thm ("OPEN_UNION", 2630 ``!s t. open s /\ open t ==> open(s UNION t)``, 2631 REWRITE_TAC [open_def] THEN REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN 2632 POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN 2633 POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN 2634 REPEAT STRIP_TAC THEN Cases_on `x IN s` THENL 2635 [FULL_SIMP_TAC std_ss [] THEN EXISTS_TAC ``e:real`` THEN 2636 FULL_SIMP_TAC std_ss [IN_UNION], FULL_SIMP_TAC std_ss [IN_UNION] THEN 2637 EXISTS_TAC ``e:real`` THEN FULL_SIMP_TAC std_ss [IN_UNION]]); 2638 2639val OPEN_SUB_OPEN = store_thm ("OPEN_SUB_OPEN", 2640 ``!s. open s <=> !x. x IN s ==> ?t. open t /\ x IN t /\ t SUBSET s``, 2641 GEN_TAC THEN EQ_TAC THENL 2642 [RW_TAC std_ss [] THEN EXISTS_TAC ``s:real->bool`` THEN 2643 ASM_REWRITE_TAC [SUBSET_REFL], DISCH_TAC THEN 2644 REWRITE_TAC [open_def] THEN GEN_TAC THEN 2645 POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN DISCH_TAC THEN DISCH_TAC THEN 2646 FULL_SIMP_TAC std_ss [open_def] THEN 2647 UNDISCH_TAC (Term `!x. x IN t ==> ?e. 0 < e /\ !x'. dist (x',x) < e ==> x' IN t `) 2648 THEN DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN 2649 RW_TAC std_ss [] THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC [] 2650 THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN 2651 RW_TAC std_ss [] THEN METIS_TAC [SUBSET_DEF]]); 2652 2653val CLOSED_EMPTY = store_thm ("CLOSED_EMPTY", 2654 ``closed {}``, 2655 REWRITE_TAC[CLOSED_IN, CLOSED_IN_EMPTY]); 2656 2657val CLOSED_UNIV = store_thm ("CLOSED_UNIV", 2658 ``closed(UNIV:real->bool)``, 2659 REWRITE_TAC[CLOSED_IN, GSYM TOPSPACE_EUCLIDEAN, CLOSED_IN_TOPSPACE]); 2660 2661val CLOSED_UNION = store_thm ("CLOSED_UNION", 2662 ``!s t. closed s /\ closed t ==> closed(s UNION t)``, 2663 REWRITE_TAC[CLOSED_IN, CLOSED_IN_UNION]); 2664 2665val CLOSED_INTER = store_thm ("CLOSED_INTER", 2666 ``!s t. closed s /\ closed t ==> closed(s INTER t)``, 2667 REWRITE_TAC[CLOSED_IN, CLOSED_IN_INTER]); 2668 2669val CLOSED_BIGINTER = store_thm ("CLOSED_BIGINTER", 2670 ``!f. (!s:real->bool. s IN f ==> closed s) ==> closed(BIGINTER f)``, 2671 REWRITE_TAC[CLOSED_IN] THEN REPEAT STRIP_TAC THEN 2672 ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN 2673 ASM_SIMP_TAC std_ss [CLOSED_IN_BIGINTER, BIGINTER_EMPTY] THEN 2674 REWRITE_TAC[GSYM TOPSPACE_EUCLIDEAN, CLOSED_IN_TOPSPACE]); 2675 2676val BIGINTER_GSPEC = store_thm ("BIGINTER_GSPEC", 2677 ``(!P f. BIGINTER {f x | P x} = {a | !x. P x ==> a IN (f x)}) /\ 2678 (!P f. BIGINTER {f x y | P x y} = {a | !x y. P x y ==> a IN (f x y)}) /\ 2679 (!P f. BIGINTER {f x y z | P x y z} = 2680 {a | !x y z. P x y z ==> a IN (f x y z)})``, 2681 REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 2682 SIMP_TAC std_ss [IN_BIGINTER, GSPECIFICATION, EXISTS_PROD] THEN MESON_TAC[]); 2683 2684val CLOSED_FORALL_IN = store_thm ("CLOSED_FORALL_IN", 2685 ``!P Q:'a->real->bool. 2686 (!a. P a ==> closed {x | Q a x}) ==> closed {x | !a. P a ==> Q a x}``, 2687 REPEAT STRIP_TAC THEN 2688 SUBGOAL_THEN ``closed(BIGINTER {{x | Q (a:'a) (x:real)} | P a})`` MP_TAC THENL 2689 [MATCH_MP_TAC CLOSED_BIGINTER THEN ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC], 2690 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN SIMP_TAC std_ss [BIGINTER_GSPEC] THEN 2691 SET_TAC[]]); 2692 2693val CLOSED_FORALL = store_thm ("CLOSED_FORALL", 2694 ``!Q:'a->real->bool. (!a. closed {x | Q a x}) ==> closed {x | !a. Q a x}``, 2695 MP_TAC(ISPEC ``\x:'a. T`` CLOSED_FORALL_IN) THEN REWRITE_TAC[]); 2696 2697val OPEN_CLOSED = store_thm ("OPEN_CLOSED", 2698 ``!s:real->bool. open s <=> closed(UNIV DIFF s)``, 2699 SIMP_TAC std_ss [OPEN_IN, CLOSED_IN, TOPSPACE_EUCLIDEAN, SUBSET_UNIV, 2700 OPEN_IN_CLOSED_IN_EQ]); 2701 2702val OPEN_DIFF = store_thm ("OPEN_DIFF", 2703 ``!s t. open s /\ closed t ==> open(s DIFF t)``, 2704 REWRITE_TAC[OPEN_IN, CLOSED_IN, OPEN_IN_DIFF]); 2705 2706val CLOSED_DIFF = store_thm ("CLOSED_DIFF", 2707 ``!s t. closed s /\ open t ==> closed(s DIFF t)``, 2708 REWRITE_TAC[OPEN_IN, CLOSED_IN, CLOSED_IN_DIFF]); 2709 2710val OPEN_BIGINTER = store_thm ("OPEN_BIGINTER", 2711 ``!s. FINITE s /\ (!t. t IN s ==> open t) ==> (open (BIGINTER s))``, 2712 REWRITE_TAC [GSYM AND_IMP_INTRO] THEN GEN_TAC THEN 2713 KNOW_TAC `` (!t. t IN s ==> open t) ==> open (BIGINTER s) = 2714 (\x. (!t. t IN x ==> open t) ==> open (BIGINTER x)) s`` THENL 2715 [SIMP_TAC std_ss [GSPECIFICATION] THEN DISCH_TAC THEN 2716 ASM_REWRITE_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN 2717 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 2718 REWRITE_TAC [BIGINTER_INSERT, BIGINTER_EMPTY, OPEN_UNIV, 2719 IN_INSERT] THEN MESON_TAC [OPEN_INTER]); 2720 2721val CLOSED_BIGUNION = store_thm ("CLOSED_BIGUNION", 2722 ``!s. FINITE s /\ (!t. t IN s ==> closed t) ==> closed(BIGUNION s)``, 2723 REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 2724 KNOW_TAC ``!s. ((!t. t IN s ==> closed t) ==> closed(BIGUNION s)) = 2725 (\s. (!t. t IN s ==> closed t) ==> closed(BIGUNION s)) s`` THENL 2726 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 2727 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 2728 REWRITE_TAC[BIGUNION_INSERT, BIGUNION_EMPTY, CLOSED_EMPTY, IN_INSERT] THEN 2729 MESON_TAC[CLOSED_UNION]); 2730 2731(* ------------------------------------------------------------------------- *) 2732(* Open and closed balls. *) 2733(* ------------------------------------------------------------------------- *) 2734 2735val ball = new_definition ("ball", 2736 ``ball(x,e) = { y | dist(x,y) < e}``); 2737 2738val cball = new_definition ("cball", 2739 ``cball(x,e) = { y | dist(x,y) <= e}``); 2740 2741val sphere = new_definition ("sphere", 2742 ``sphere(x,e) = { y | dist(x,y) = e}``); 2743 2744val IN_BALL = store_thm ("IN_BALL", 2745 ``!x y e. y IN ball(x,e) <=> dist(x,y) < e``, 2746 REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [ball, GSPECIFICATION]); 2747 2748val IN_CBALL = store_thm ("IN_CBALL", 2749 ``!x y e. y IN cball(x,e) <=> dist(x,y) <= e``, 2750 REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [cball, GSPECIFICATION]); 2751 2752val IN_SPHERE = store_thm ("IN_SPHERE", 2753 ``!x y e. y IN sphere(x,e) <=> (dist(x,y) = e)``, 2754 REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [sphere, GSPECIFICATION]); 2755 2756val IN_BALL_0 = store_thm ("IN_BALL_0", 2757 ``!x e. x IN ball(0,e) <=> abs(x) < e``, 2758 REWRITE_TAC [IN_BALL, dist, REAL_SUB_LZERO, ABS_NEG]); 2759 2760val IN_CBALL_0 = store_thm ("IN_CBALL_0", 2761 ``!x e. x IN cball(0,e) <=> abs(x) <= e``, 2762 REWRITE_TAC[IN_CBALL, dist, REAL_SUB_LZERO, ABS_NEG]); 2763 2764val IN_SPHERE_0 = store_thm ("IN_SPHERE_0", 2765 ``!x e. x IN sphere(0,e) <=> (abs(x) = e)``, 2766 REWRITE_TAC[IN_SPHERE, dist, REAL_SUB_LZERO, ABS_NEG]); 2767 2768val BALL_TRIVIAL = store_thm ("BALL_TRIVIAL", 2769 ``!x. ball(x,&0) = {}``, 2770 REWRITE_TAC[EXTENSION, IN_BALL, IN_SING, NOT_IN_EMPTY, dist] THEN REAL_ARITH_TAC); 2771 2772val CBALL_TRIVIAL = store_thm ("CBALL_TRIVIAL", 2773 ``!x. cball(x,&0) = {x}``, 2774 REWRITE_TAC[EXTENSION, IN_CBALL, IN_SING, NOT_IN_EMPTY, dist] THEN REAL_ARITH_TAC); 2775 2776val CENTRE_IN_CBALL = store_thm ("CENTRE_IN_CBALL", 2777 ``!x e. x IN cball(x,e) <=> &0 <= e``, 2778 MESON_TAC[IN_CBALL, DIST_REFL]); 2779 2780val BALL_SUBSET_CBALL = store_thm ("BALL_SUBSET_CBALL", 2781 ``!x e. ball(x,e) SUBSET cball(x,e)``, 2782 REWRITE_TAC[IN_BALL, IN_CBALL, SUBSET_DEF] THEN REAL_ARITH_TAC); 2783 2784val SPHERE_SUBSET_CBALL = store_thm ("SPHERE_SUBSET_CBALL", 2785 ``!x e. sphere(x,e) SUBSET cball(x,e)``, 2786 REWRITE_TAC[IN_SPHERE, IN_CBALL, SUBSET_DEF] THEN REAL_ARITH_TAC); 2787 2788val SUBSET_BALL = store_thm ("SUBSET_BALL", 2789 ``!x d e. d <= e ==> ball(x,d) SUBSET ball(x,e)``, 2790 REWRITE_TAC[SUBSET_DEF, IN_BALL] THEN MESON_TAC[REAL_LTE_TRANS]); 2791 2792val SUBSET_CBALL = store_thm ("SUBSET_CBALL", 2793 ``!x d e. d <= e ==> cball(x,d) SUBSET cball(x,e)``, 2794 REWRITE_TAC[SUBSET_DEF, IN_CBALL] THEN MESON_TAC[REAL_LE_TRANS]); 2795 2796val BALL_MAX_UNION = store_thm ("BALL_MAX_UNION", 2797 ``!a r s. ball(a,max r s) = ball(a,r) UNION ball(a,s)``, 2798 rpt GEN_TAC 2799 >> REWRITE_TAC [IN_BALL, IN_UNION, EXTENSION, dist] 2800 >> GEN_TAC >> Q.ABBREV_TAC `b = abs (a - x)` 2801 >> REWRITE_TAC [REAL_LT_MAX]); 2802 2803val BALL_MIN_INTER = store_thm ("BALL_MIN_INTER", 2804 ``!a r s. ball(a,min r s) = ball(a,r) INTER ball(a,s)``, 2805 rpt GEN_TAC 2806 >> REWRITE_TAC [IN_BALL, IN_INTER, EXTENSION, dist] 2807 >> GEN_TAC >> Q.ABBREV_TAC `b = abs (a - x)` 2808 >> REWRITE_TAC [REAL_LT_MIN]); 2809 2810val CBALL_MAX_UNION = store_thm ("CBALL_MAX_UNION", 2811 ``!a r s. cball(a,max r s) = cball(a,r) UNION cball(a,s)``, 2812 rpt GEN_TAC 2813 >> REWRITE_TAC [IN_CBALL, IN_UNION, EXTENSION, dist] 2814 >> GEN_TAC >> Q.ABBREV_TAC `b = abs (a - x)` 2815 >> REWRITE_TAC [REAL_LE_MAX]); 2816 2817val CBALL_MIN_INTER = store_thm ("CBALL_MIN_INTER", 2818 ``!x d e. cball(x,min d e) = cball(x,d) INTER cball(x,e)``, 2819 rpt GEN_TAC 2820 >> REWRITE_TAC [EXTENSION, IN_INTER, IN_CBALL, dist] 2821 >> Q.X_GEN_TAC `a` >> Q.ABBREV_TAC `b = abs (x - a)` 2822 >> REWRITE_TAC [REAL_LE_MIN]); 2823 2824val BALL_TRANSLATION = store_thm ("BALL_TRANSLATION", 2825 ``!a x r. ball(a + x,r) = IMAGE (\y. a + y) (ball(x,r))``, 2826 REPEAT GEN_TAC THEN REWRITE_TAC [EXTENSION, IN_BALL, IN_IMAGE, dist] THEN 2827 GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x' - a:real`` THEN 2828 RW_TAC std_ss [REAL_SUB_ADD2] THEN 2829 ASM_REWRITE_TAC [REAL_ARITH ``x - (x' - a) = a + x - x':real``], 2830 RW_TAC std_ss [] THEN 2831 METIS_TAC [REAL_ARITH ``a - (b + c) = a - b - c:real``, REAL_ADD_SUB]]); 2832 2833val CBALL_TRANSLATION = store_thm ("CBALL_TRANSLATION", 2834 ``!a x r. cball(a + x,r) = IMAGE (\y. a + y) (cball(x,r))``, 2835 REPEAT GEN_TAC THEN REWRITE_TAC [EXTENSION, IN_CBALL, IN_IMAGE, dist] THEN 2836 GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x' - a:real`` THEN 2837 RW_TAC std_ss [REAL_SUB_ADD2] THEN 2838 ASM_REWRITE_TAC [REAL_ARITH ``x - (x' - a) = a + x - x':real``], 2839 RW_TAC std_ss [] THEN 2840 METIS_TAC [REAL_ARITH ``a - (b + c) = a - b - c:real``, REAL_ADD_SUB]]); 2841 2842val SPHERE_TRANSLATION = store_thm ("SPHERE_TRANSLATION", 2843 ``!a x r. sphere(a + x,r) = IMAGE (\y. a + y) (sphere(x,r))``, 2844 REPEAT GEN_TAC THEN REWRITE_TAC [EXTENSION, IN_SPHERE, IN_IMAGE, dist] THEN 2845 GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x' - a:real`` THEN 2846 RW_TAC std_ss [REAL_SUB_ADD2] THEN 2847 ASM_REWRITE_TAC [REAL_ARITH ``x - (x' - a) = a + x - x':real``], 2848 RW_TAC std_ss [] THEN 2849 METIS_TAC [REAL_ARITH ``a - (b + c) = a - b - c:real``, REAL_ADD_SUB]]); 2850 2851val BALL_LINEAR_IMAGE = store_thm ("BALL_LINEAR_IMAGE", 2852 ``!f:real->real x r. 2853 linear f /\ (!y. ?x. f x = y) /\ (!x. abs(f x) = abs x) 2854 ==> (ball(f x,r) = IMAGE f (ball(x,r)))``, 2855 REWRITE_TAC[ball] THEN 2856 SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION] THEN 2857 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL 2858 [UNDISCH_TAC ``!y. ?x. (f:real->real) x = y`` THEN DISCH_TAC THEN 2859 POP_ASSUM (MP_TAC o SPEC ``x':real``) THEN STRIP_TAC THEN 2860 EXISTS_TAC ``x'':real`` THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN 2861 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x. abs ((f:real->real) x) = abs x`` THEN 2862 DISCH_THEN (MP_TAC o SYM o SPEC ``x - x'':real``) THEN DISCH_TAC THEN 2863 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2864 DISCH_THEN (MP_TAC o SPECL [``x:real``, ``-x'':real``]) THEN 2865 REWRITE_TAC [GSYM real_sub] THEN DISCH_TAC THEN 2866 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-x = -1 * x:real``] THEN 2867 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2868 DISCH_THEN (MP_TAC o SPECL [``-1:real``,``x'':real``]) THEN ASM_REAL_ARITH_TAC, 2869 ASM_REWRITE_TAC [real_sub] THEN REWRITE_TAC [REAL_ARITH ``-(f:real->real) x = -1 * f x``] THEN 2870 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2871 DISCH_THEN (MP_TAC o SYM o SPECL [``-1:real``,``x'':real``]) THEN DISCH_TAC THEN 2872 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-1 * x:real = -x``] THEN 2873 UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2874 DISCH_THEN (MP_TAC o SYM o SPECL [``x:real``, ``-x'':real``]) THEN DISCH_TAC THEN 2875 ASM_REWRITE_TAC [GSYM real_sub]]); 2876 2877val CBALL_LINEAR_IMAGE = store_thm ("CBALL_LINEAR_IMAGE", 2878 ``!f:real->real x r. 2879 linear f /\ (!y. ?x. f x = y) /\ (!x. abs(f x) = abs x) 2880 ==> (cball(f x,r) = IMAGE f (cball(x,r)))``, 2881 REWRITE_TAC[cball] THEN 2882 SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION] THEN 2883 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL 2884 [UNDISCH_TAC ``!y. ?x. (f:real->real) x = y`` THEN DISCH_TAC THEN 2885 POP_ASSUM (MP_TAC o SPEC ``x':real``) THEN STRIP_TAC THEN 2886 EXISTS_TAC ``x'':real`` THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN 2887 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x. abs ((f:real->real) x) = abs x`` THEN 2888 DISCH_THEN (MP_TAC o SYM o SPEC ``x - x'':real``) THEN DISCH_TAC THEN 2889 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2890 DISCH_THEN (MP_TAC o SPECL [``x:real``, ``-x'':real``]) THEN 2891 REWRITE_TAC [GSYM real_sub] THEN DISCH_TAC THEN 2892 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-x = -1 * x:real``] THEN 2893 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2894 DISCH_THEN (MP_TAC o SPECL [``-1:real``,``x'':real``]) THEN ASM_REAL_ARITH_TAC, 2895 ASM_REWRITE_TAC [real_sub] THEN REWRITE_TAC [REAL_ARITH ``-(f:real->real) x = -1 * f x``] THEN 2896 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2897 DISCH_THEN (MP_TAC o SYM o SPECL [``-1:real``,``x'':real``]) THEN DISCH_TAC THEN 2898 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-1 * x:real = -x``] THEN 2899 UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2900 DISCH_THEN (MP_TAC o SYM o SPECL [``x:real``, ``-x'':real``]) THEN DISCH_TAC THEN 2901 ASM_REWRITE_TAC [GSYM real_sub]]); 2902 2903val SPHERE_LINEAR_IMAGE = store_thm ("SPHERE_LINEAR_IMAGE", 2904 ``!f:real->real x r. 2905 linear f /\ (!y. ?x. f x = y) /\ (!x. abs(f x) = abs x) 2906 ==> (sphere(f x,r) = IMAGE f (sphere(x,r)))``, 2907 REWRITE_TAC[sphere] THEN 2908 SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION] THEN 2909 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL 2910 [UNDISCH_TAC ``!y. ?x. (f:real->real) x = y`` THEN DISCH_TAC THEN 2911 POP_ASSUM (MP_TAC o SPEC ``x':real``) THEN STRIP_TAC THEN 2912 EXISTS_TAC ``x'':real`` THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN 2913 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x. abs ((f:real->real) x) = abs x`` THEN 2914 DISCH_THEN (MP_TAC o SYM o SPEC ``x - x'':real``) THEN DISCH_TAC THEN 2915 ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2916 DISCH_THEN (MP_TAC o SPECL [``x:real``, ``-x'':real``]) THEN 2917 REWRITE_TAC [GSYM real_sub] THEN DISCH_TAC THEN 2918 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-x = -1 * x:real``] THEN 2919 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2920 DISCH_THEN (MP_TAC o SPECL [``-1:real``,``x'':real``]) THEN ASM_REAL_ARITH_TAC, 2921 ASM_REWRITE_TAC [real_sub] THEN REWRITE_TAC [REAL_ARITH ``-(f:real->real) x = -1 * f x``] THEN 2922 UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN 2923 DISCH_THEN (MP_TAC o SYM o SPECL [``-1:real``,``x'':real``]) THEN DISCH_TAC THEN 2924 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-1 * x:real = -x``] THEN 2925 UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN 2926 DISCH_THEN (MP_TAC o SYM o SPECL [``x:real``, ``-x'':real``]) THEN DISCH_TAC THEN 2927 ASM_REWRITE_TAC [GSYM real_sub]]); 2928 2929val BALL_SCALING = store_thm ("BALL_SCALING", 2930 ``!c. &0 < c ==> !x r. ball(c * x,c * r) = IMAGE (\x. c * x) (ball(x,r))``, 2931 REWRITE_TAC [IMAGE_DEF, IN_BALL] THEN BETA_TAC THEN 2932 SIMP_TAC std_ss [ball, EXTENSION, GSPECIFICATION, dist] THEN 2933 REPEAT STRIP_TAC THEN EQ_TAC THENL [DISCH_TAC THEN 2934 EXISTS_TAC ``x' / c:real`` THEN 2935 FULL_SIMP_TAC std_ss [REAL_DIV_LMUL, REAL_POS_NZ] THEN 2936 KNOW_TAC `` abs (x - x' / c) < r = abs c * abs (x - x' / c) < c * r:real`` THENL 2937 [FULL_SIMP_TAC std_ss [abs, REAL_LT_IMP_LE, REAL_LT_LMUL], ALL_TAC] THEN 2938 DISC_RW_KILL THEN REWRITE_TAC [GSYM ABS_MUL] THEN 2939 FULL_SIMP_TAC std_ss [REAL_SUB_LDISTRIB, REAL_DIV_LMUL, REAL_POS_NZ], 2940 STRIP_TAC THEN FULL_SIMP_TAC std_ss [GSYM dist, DIST_MUL, abs, 2941 REAL_LT_IMP_LE, REAL_LT_LMUL]]); 2942 2943val CBALL_SCALING = store_thm ("CBALL_SCALING", 2944 ``!c. &0 < c ==> !x r. cball(c * x,c * r) = IMAGE (\x. c * x) (cball(x,r))``, 2945 REWRITE_TAC [IMAGE_DEF, IN_CBALL] THEN BETA_TAC THEN 2946 SIMP_TAC std_ss [cball, EXTENSION, GSPECIFICATION, dist] THEN 2947 REPEAT STRIP_TAC THEN EQ_TAC THENL [DISCH_TAC THEN 2948 EXISTS_TAC ``x' / c:real`` THEN 2949 FULL_SIMP_TAC std_ss [REAL_DIV_LMUL, REAL_POS_NZ] THEN 2950 KNOW_TAC `` abs (x - x' / c) <= r = abs c * abs (x - x' / c) <= c * r:real`` THENL 2951 [FULL_SIMP_TAC std_ss [abs, REAL_LT_IMP_LE, REAL_LE_LMUL], ALL_TAC] THEN 2952 DISC_RW_KILL THEN REWRITE_TAC [GSYM ABS_MUL] THEN 2953 FULL_SIMP_TAC std_ss [REAL_SUB_LDISTRIB, REAL_DIV_LMUL, REAL_POS_NZ], 2954 STRIP_TAC THEN FULL_SIMP_TAC std_ss [GSYM dist, DIST_MUL, abs, 2955 REAL_LT_IMP_LE, REAL_LE_LMUL]]); 2956 2957val CBALL_DIFF_BALL = store_thm ("CBALL_DIFF_BALL", 2958 ``!a r. cball(a,r) DIFF ball(a,r) = sphere(a,r)``, 2959 SIMP_TAC std_ss [ball, cball, sphere, EXTENSION, IN_DIFF, GSPECIFICATION] THEN 2960 REAL_ARITH_TAC); 2961 2962val BALL_UNION_SPHERE = store_thm ("BALL_UNION_SPHERE", 2963 ``!a r. ball(a,r) UNION sphere(a,r) = cball(a,r)``, 2964 SIMP_TAC std_ss [ball, cball, sphere, EXTENSION, IN_UNION, GSPECIFICATION] THEN 2965 REAL_ARITH_TAC); 2966 2967val SPHERE_UNION_BALL = store_thm ("SPHERE_UNION_BALL", 2968 ``!a r. sphere(a,r) UNION ball(a,r) = cball(a,r)``, 2969 SIMP_TAC std_ss [ball, cball, sphere, EXTENSION, IN_UNION, GSPECIFICATION] THEN 2970 REAL_ARITH_TAC); 2971 2972val CBALL_DIFF_SPHERE = store_thm ("CBALL_DIFF_SPHERE", 2973 ``!a r. cball(a,r) DIFF sphere(a,r) = ball(a,r)``, 2974 REWRITE_TAC[EXTENSION, IN_DIFF, IN_SPHERE, IN_BALL, IN_CBALL] THEN 2975 REAL_ARITH_TAC); 2976 2977val OPEN_BALL = store_thm ("OPEN_BALL", 2978 ``!x e. open(ball(x,e))``, 2979 REPEAT GEN_TAC THEN REWRITE_TAC[open_def, ball] THEN 2980 FULL_SIMP_TAC std_ss [GSPECIFICATION] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN 2981 MESON_TAC [REAL_SUB_LT, REAL_LT_SUB_LADD, REAL_ADD_SYM, REAL_LET_TRANS, 2982 DIST_TRIANGLE_ALT]); 2983 2984val CENTRE_IN_BALL = store_thm ("CENTRE_IN_BALL", 2985 ``!x e. x IN ball(x,e) <=> &0 < e``, 2986 MESON_TAC[IN_BALL, DIST_REFL]); 2987 2988val OPEN_CONTAINS_BALL = store_thm ("OPEN_CONTAINS_BALL", 2989 ``!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ ball(x,e) SUBSET s``, 2990 REWRITE_TAC[open_def, SUBSET_DEF, IN_BALL] THEN SIMP_TAC std_ss [DIST_SYM]); 2991 2992val OPEN_CONTAINS_BALL_EQ = store_thm ("OPEN_CONTAINS_BALL_EQ", 2993 ``!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ ball(x,e) SUBSET s)``, 2994 MESON_TAC[OPEN_CONTAINS_BALL, SUBSET_DEF, CENTRE_IN_BALL]); 2995 2996val BALL_EQ_EMPTY = store_thm ("BALL_EQ_EMPTY", 2997 ``!x e. (ball(x,e) = {}) <=> e <= &0``, 2998 REWRITE_TAC[EXTENSION, IN_BALL, NOT_IN_EMPTY, REAL_NOT_LT] THEN 2999 MESON_TAC[DIST_POS_LE, REAL_LE_TRANS, DIST_REFL]); 3000 3001val BALL_EMPTY = store_thm ("BALL_EMPTY", 3002 ``!x e. e <= &0 ==> (ball(x,e) = {})``, 3003 REWRITE_TAC[BALL_EQ_EMPTY]); 3004 3005val OPEN_CONTAINS_CBALL = store_thm ("OPEN_CONTAINS_CBALL", 3006 ``!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ cball(x,e) SUBSET s``, 3007 GEN_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN EQ_TAC THENL 3008 [ALL_TAC, ASM_MESON_TAC[SUBSET_TRANS, BALL_SUBSET_CBALL]] THEN 3009 KNOW_TAC ``!x. (x IN s ==> ?e. 0 < e /\ cball (x,e) SUBSET s) = 3010 (\x:real. x IN s ==> ?e. 0 < e /\ cball (x,e) SUBSET s) x`` THENL 3011 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 3012 KNOW_TAC ``!x. (x IN s ==> ?e. 0 < e /\ ball (x,e) SUBSET s) = 3013 (\x:real. x IN s ==> ?e. 0 < e /\ ball (x,e) SUBSET s) x`` THENL 3014 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 3015 MATCH_MP_TAC MONO_ALL THEN GEN_TAC THEN BETA_TAC THEN 3016 MATCH_MP_TAC MONO_IMP THEN 3017 REWRITE_TAC[SUBSET_DEF, IN_BALL, IN_CBALL] THEN 3018 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 3019 EXISTS_TAC ``e / &2:real`` THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN 3020 SUBGOAL_THEN ``e / &2 < e:real`` (fn th => ASM_MESON_TAC[th, REAL_LET_TRANS]) THEN 3021 UNDISCH_TAC ``0 < e:real`` THEN SIMP_TAC arith_ss [REAL_LT_HALF2]); 3022 3023val OPEN_CONTAINS_CBALL_EQ = store_thm ("OPEN_CONTAINS_CBALL_EQ", 3024 ``!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ cball(x,e) SUBSET s)``, 3025 MESON_TAC[OPEN_CONTAINS_CBALL, SUBSET_DEF, REAL_LT_IMP_LE, CENTRE_IN_CBALL]); 3026 3027val SPHERE_EQ_EMPTY = store_thm ("SPHERE_EQ_EMPTY", 3028 ``!a:real r. (sphere(a,r) = {}) <=> r < &0``, 3029 SIMP_TAC std_ss [sphere, EXTENSION, GSPECIFICATION, NOT_IN_EMPTY] THEN 3030 REPEAT GEN_TAC THEN EQ_TAC THENL [CCONTR_TAC THEN 3031 FULL_SIMP_TAC std_ss [REAL_NOT_LT] THEN 3032 UNDISCH_TAC ``!x. dist (a,x) <> r`` THEN 3033 FULL_SIMP_TAC std_ss [REAL_LE_LT, dist] THENL 3034 [EXISTS_TAC ``a - r:real`` THEN POP_ASSUM MP_TAC THEN 3035 REAL_ARITH_TAC, EXISTS_TAC ``a:real`` THEN 3036 METIS_TAC [REAL_SUB_REFL, EQ_SYM_EQ, ABS_0]], DISCH_TAC THEN 3037 ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN CCONTR_TAC THEN 3038 UNDISCH_TAC ``r < 0:real`` THEN FULL_SIMP_TAC std_ss [REAL_NOT_LT, DIST_POS_LE]]); 3039 3040val SPHERE_EMPTY = store_thm ("SPHERE_EMPTY", 3041 ``!a:real r. r < &0 ==> (sphere(a,r) = {})``, 3042 REWRITE_TAC[SPHERE_EQ_EMPTY]); 3043 3044val NEGATIONS_BALL = store_thm ("NEGATIONS_BALL", 3045 ``!r. IMAGE (\x:real. -x) (ball(0:real,r)) = ball(0,r)``, 3046 GEN_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_BALL_0] THEN 3047 GEN_TAC THEN EQ_TAC THENL [METIS_TAC [ABS_NEG], DISCH_TAC THEN 3048 EXISTS_TAC ``-x:real`` THEN 3049 FULL_SIMP_TAC std_ss [ABS_NEG, REAL_NEG_NEG]]); 3050 3051val NEGATIONS_CBALL = store_thm ("NEGATIONS_CBALL", 3052 ``!r. IMAGE (\x. -x) (cball(0:real,r)) = cball(0,r)``, 3053 GEN_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_CBALL_0] THEN 3054 GEN_TAC THEN EQ_TAC THENL [METIS_TAC [ABS_NEG], DISCH_TAC THEN 3055 EXISTS_TAC ``-x:real`` THEN 3056 FULL_SIMP_TAC std_ss [ABS_NEG, REAL_NEG_NEG]]); 3057 3058val NEGATIONS_SPHERE = store_thm ("NEGATIONS_SPHERE", 3059 ``!r. IMAGE (\x. -x) (sphere(0:real,r)) = sphere(0,r)``, 3060 GEN_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_SPHERE_0] THEN 3061 GEN_TAC THEN EQ_TAC THENL [METIS_TAC [ABS_NEG], DISCH_TAC THEN 3062 EXISTS_TAC ``-x:real`` THEN 3063 FULL_SIMP_TAC std_ss [ABS_NEG, REAL_NEG_NEG]]); 3064 3065(* ------------------------------------------------------------------------- *) 3066(* Basic "localization" results are handy for connectedness. *) 3067(* ------------------------------------------------------------------------- *) 3068 3069val OPEN_IN_OPEN = store_thm ("OPEN_IN_OPEN", 3070 ``!s:real->bool u. 3071 open_in (subtopology euclidean u) s <=> ?t. open t /\ (s = u INTER t)``, 3072 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [OPEN_IN_SUBTOPOLOGY, GSYM OPEN_IN] THEN 3073 SIMP_TAC std_ss [INTER_ACI]); 3074 3075val OPEN_IN_INTER_OPEN = store_thm ("OPEN_IN_INTER_OPEN", 3076 ``!s t u:real->bool. 3077 open_in (subtopology euclidean u) s /\ open t 3078 ==> open_in (subtopology euclidean u) (s INTER t)``, 3079 SIMP_TAC std_ss [OPEN_IN_OPEN] THEN REPEAT STRIP_TAC THEN 3080 ASM_MESON_TAC[INTER_ASSOC, OPEN_INTER]); 3081 3082val OPEN_IN_OPEN_INTER = store_thm ("OPEN_IN_OPEN_INTER", 3083 ``!u s. open s ==> open_in (subtopology euclidean u) (u INTER s)``, 3084 REWRITE_TAC[OPEN_IN_OPEN] THEN MESON_TAC[]); 3085 3086val OPEN_OPEN_IN_TRANS = store_thm ("OPEN_OPEN_IN_TRANS", 3087 ``!s t. open s /\ open t /\ t SUBSET s 3088 ==> open_in (subtopology euclidean s) t``, 3089 MESON_TAC[OPEN_IN_OPEN_INTER, SET_RULE ``(t:real->bool) SUBSET s ==> (t = s INTER t)``]); 3090 3091val OPEN_SUBSET = store_thm ("OPEN_SUBSET", 3092 ``!s t:real->bool. 3093 s SUBSET t /\ open s ==> open_in (subtopology euclidean t) s``, 3094 REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN 3095 EXISTS_TAC ``s:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 3096 3097val CLOSED_IN_CLOSED = store_thm ("CLOSED_IN_CLOSED", 3098 ``!s:real->bool u. 3099 closed_in (subtopology euclidean u) s <=> ?t. closed t /\ (s = u INTER t)``, 3100 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [CLOSED_IN_SUBTOPOLOGY, GSYM CLOSED_IN] THEN 3101 SIMP_TAC std_ss [INTER_ACI]); 3102 3103val CLOSED_SUBSET_EQ = store_thm ("CLOSED_SUBSET_EQ", 3104 ``!u s:real->bool. 3105 closed s ==> (closed_in (subtopology euclidean u) s <=> s SUBSET u)``, 3106 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 3107 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN 3108 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY], 3109 REWRITE_TAC[CLOSED_IN_CLOSED] THEN EXISTS_TAC ``s:real->bool`` THEN 3110 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]); 3111 3112val CLOSED_IN_INTER_CLOSED = store_thm ("CLOSED_IN_INTER_CLOSED", 3113 ``!s t u:real->bool. 3114 closed_in (subtopology euclidean u) s /\ closed t 3115 ==> closed_in (subtopology euclidean u) (s INTER t)``, 3116 SIMP_TAC std_ss [CLOSED_IN_CLOSED] THEN REPEAT STRIP_TAC THEN 3117 ASM_MESON_TAC[INTER_ASSOC, CLOSED_INTER]); 3118 3119val CLOSED_IN_CLOSED_INTER = store_thm ("CLOSED_IN_CLOSED_INTER", 3120 ``!u s. closed s ==> closed_in (subtopology euclidean u) (u INTER s)``, 3121 REWRITE_TAC[CLOSED_IN_CLOSED] THEN MESON_TAC[]); 3122 3123val CLOSED_SUBSET = store_thm ("CLOSED_SUBSET", 3124 ``!s t:real->bool. 3125 s SUBSET t /\ closed s ==> closed_in (subtopology euclidean t) s``, 3126 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN 3127 EXISTS_TAC ``s:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 3128 3129val OPEN_IN_SUBSET_TRANS = store_thm ("OPEN_IN_SUBSET_TRANS", 3130 ``!s t u:real->bool. 3131 open_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u 3132 ==> open_in (subtopology euclidean t) s``, 3133 REPEAT GEN_TAC THEN SIMP_TAC std_ss [OPEN_IN_OPEN, LEFT_EXISTS_AND_THM] THEN 3134 SET_TAC[]); 3135 3136val CLOSED_IN_SUBSET_TRANS = store_thm ("CLOSED_IN_SUBSET_TRANS", 3137 ``!s t u:real->bool. 3138 closed_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u 3139 ==> closed_in (subtopology euclidean t) s``, 3140 REPEAT GEN_TAC THEN SIMP_TAC std_ss [CLOSED_IN_CLOSED] THEN 3141 REPEAT STRIP_TAC THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 3142 3143val open_in = store_thm ("open_in", 3144 ``!u s:real->bool. 3145 open_in (subtopology euclidean u) s <=> 3146 s SUBSET u /\ 3147 !x. x IN s ==> ?e. &0 < e /\ 3148 !x'. x' IN u /\ dist(x',x) < e ==> x' IN s``, 3149 REPEAT GEN_TAC THEN 3150 SIMP_TAC std_ss [OPEN_IN_SUBTOPOLOGY, GSYM OPEN_IN] THEN EQ_TAC THENL 3151 [REWRITE_TAC[open_def] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[INTER_SUBSET, IN_INTER], 3152 ALL_TAC] THEN 3153 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN DISCH_TAC THEN 3154 FULL_SIMP_TAC std_ss [GSYM RIGHT_EXISTS_IMP_THM] THEN POP_ASSUM MP_TAC THEN 3155 SIMP_TAC std_ss [SKOLEM_THM] THEN DISCH_THEN(X_CHOOSE_TAC ``d:real->real``) THEN 3156 EXISTS_TAC ``BIGUNION {b | ?x:real. (b = ball(x,d x)) /\ x IN s}`` THEN 3157 CONJ_TAC THENL 3158 [MATCH_MP_TAC OPEN_BIGUNION THEN 3159 ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN METIS_TAC [LEFT_EXISTS_IMP_THM, OPEN_BALL], 3160 GEN_REWR_TAC I [EXTENSION] THEN 3161 SIMP_TAC std_ss [IN_INTER, IN_BIGUNION, GSPECIFICATION] THEN 3162 ASM_MESON_TAC[SUBSET_DEF, DIST_REFL, DIST_SYM, IN_BALL]]); 3163 3164val OPEN_IN_CONTAINS_BALL = store_thm ("OPEN_IN_CONTAINS_BALL", 3165 ``!s t:real->bool. 3166 open_in (subtopology euclidean t) s <=> 3167 s SUBSET t /\ 3168 !x. x IN s ==> ?e. &0 < e /\ ball(x,e) INTER t SUBSET s``, 3169 SIMP_TAC std_ss [open_in, INTER_DEF, SUBSET_DEF, GSPECIFICATION, IN_BALL] THEN 3170 MESON_TAC[DIST_SYM]); 3171 3172val OPEN_IN_CONTAINS_CBALL = store_thm ("OPEN_IN_CONTAINS_CBALL", 3173 ``!s t:real->bool. 3174 open_in (subtopology euclidean t) s <=> 3175 s SUBSET t /\ 3176 !x. x IN s ==> ?e. &0 < e /\ cball(x,e) INTER t SUBSET s``, 3177 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_CONTAINS_BALL] THEN 3178 AP_TERM_TAC THEN REWRITE_TAC[IN_BALL, IN_INTER, SUBSET_DEF, IN_CBALL] THEN 3179 MESON_TAC[METIS [REAL_LT_HALF1, REAL_LT_HALF2, REAL_LET_TRANS] 3180 ``&0 < e:real ==> &0 < e / &2 /\ (x <= e / &2 ==> x < e)``, 3181 REAL_LT_IMP_LE]); 3182 3183(* ------------------------------------------------------------------------- *) 3184(* These "transitivity" results are handy too. *) 3185(* ------------------------------------------------------------------------- *) 3186 3187val OPEN_IN_TRANS = store_thm ("OPEN_IN_TRANS", 3188 ``!s t u. open_in (subtopology euclidean t) s /\ 3189 open_in (subtopology euclidean u) t 3190 ==> open_in (subtopology euclidean u) s``, 3191 ASM_MESON_TAC[OPEN_IN_OPEN, OPEN_IN, OPEN_INTER, INTER_ASSOC]); 3192 3193val OPEN_IN_TRANS_EQ = store_thm ("OPEN_IN_TRANS_EQ", 3194 ``!s t:real->bool. 3195 (!u. open_in (subtopology euclidean t) u 3196 ==> open_in (subtopology euclidean s) t) 3197 <=> open_in (subtopology euclidean s) t``, 3198 MESON_TAC[OPEN_IN_TRANS, OPEN_IN_REFL]); 3199 3200val OPEN_IN_OPEN_TRANS = store_thm ("OPEN_IN_OPEN_TRANS", 3201 ``!s t. open_in (subtopology euclidean t) s /\ open t ==> open s``, 3202 REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] OPEN_IN] THEN 3203 REWRITE_TAC[OPEN_IN_TRANS]); 3204 3205val CLOSED_IN_TRANS = store_thm ("CLOSED_IN_TRANS", 3206 ``!s t u. closed_in (subtopology euclidean t) s /\ 3207 closed_in (subtopology euclidean u) t 3208 ==> closed_in (subtopology euclidean u) s``, 3209 ASM_MESON_TAC[CLOSED_IN_CLOSED, CLOSED_IN, CLOSED_INTER, INTER_ASSOC]); 3210 3211val CLOSED_IN_TRANS_EQ = store_thm ("CLOSED_IN_TRANS_EQ", 3212 ``!s t:real->bool. 3213 (!u. closed_in (subtopology euclidean t) u 3214 ==> closed_in (subtopology euclidean s) t) 3215 <=> closed_in (subtopology euclidean s) t``, 3216 MESON_TAC[CLOSED_IN_TRANS, CLOSED_IN_REFL]); 3217 3218val CLOSED_IN_CLOSED_TRANS = store_thm ("CLOSED_IN_CLOSED_TRANS", 3219 ``!s t. closed_in (subtopology euclidean t) s /\ closed t ==> closed s``, 3220 REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] CLOSED_IN] THEN 3221 REWRITE_TAC[CLOSED_IN_TRANS]); 3222 3223val OPEN_IN_SUBTOPOLOGY_INTER_SUBSET = store_thm ("OPEN_IN_SUBTOPOLOGY_INTER_SUBSET", 3224 ``!s u v. open_in (subtopology euclidean u) (u INTER s) /\ v SUBSET u 3225 ==> open_in (subtopology euclidean v) (v INTER s)``, 3226 REPEAT GEN_TAC THEN SIMP_TAC std_ss [OPEN_IN_OPEN, GSYM LEFT_EXISTS_AND_THM] THEN 3227 STRIP_TAC THEN EXISTS_TAC ``t:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 3228 3229val OPEN_IN_OPEN_EQ = store_thm ("OPEN_IN_OPEN_EQ", 3230 ``!s t. open s 3231 ==> (open_in (subtopology euclidean s) t <=> open t /\ t SUBSET s)``, 3232 MESON_TAC[OPEN_OPEN_IN_TRANS, OPEN_IN_OPEN_TRANS, open_in]); 3233 3234val CLOSED_IN_CLOSED_EQ = store_thm ("CLOSED_IN_CLOSED_EQ", 3235 ``!s t. closed s 3236 ==> (closed_in (subtopology euclidean s) t <=> 3237 closed t /\ t SUBSET s)``, 3238 MESON_TAC[CLOSED_SUBSET, CLOSED_IN_CLOSED_TRANS, closed_in, 3239 TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]); 3240 3241(* ------------------------------------------------------------------------- *) 3242(* Line segments, with open/closed overloading of (a,b) and [a,b]. *) 3243(* ------------------------------------------------------------------------- *) 3244 3245val closed_segment = new_definition ("closed_segment", 3246 ``closed_segment (l:(real#real)list) = 3247 {((&1:real) - u) * FST(HD l) + u * SND(HD l) | &0 <= u /\ u <= &1}``); 3248 3249val open_segment = new_definition ("open_segment", 3250 ``open_segment(a,b) = closed_segment[a,b] DIFF {a;b}``); 3251 3252val OPEN_SEGMENT_ALT = store_thm ("OPEN_SEGMENT_ALT", 3253 ``!a b:real. 3254 ~(a = b) 3255 ==> (open_segment(a,b) = {(&1 - u) * a + u * b | &0 < u /\ u < &1:real})``, 3256 REPEAT STRIP_TAC THEN REWRITE_TAC[open_segment, closed_segment, FST, SND, HD] THEN 3257 SIMP_TAC std_ss [EXTENSION, IN_DIFF, IN_INSERT, NOT_IN_EMPTY, GSPECIFICATION] THEN 3258 X_GEN_TAC ``x:real`` THEN SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM] THEN 3259 AP_TERM_TAC THEN SIMP_TAC std_ss [FUN_EQ_THM] THEN 3260 X_GEN_TAC ``u:real`` THEN ASM_CASES_TAC ``x:real = (&1 - u) * a + u * b`` THEN 3261 ASM_REWRITE_TAC[REAL_LE_LT, 3262 REAL_ARITH ``((&1 - u) * a + u * b = a) <=> (u * (b - a) = 0:real)``, 3263 REAL_ARITH ``((&1 - u) * a + u * b = b) <=> ((&1 - u) * (b - a) = 0:real)``, 3264 REAL_ENTIRE, REAL_SUB_0] THEN UNDISCH_TAC ``a <> b:real`` THEN DISCH_TAC THEN 3265 POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN DISCH_TAC THEN 3266 ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC); 3267 3268val _ = overload_on ("segment",``open_segment``); 3269val _ = overload_on ("segment",``closed_segment``); 3270 3271val segment = store_thm ("segment", 3272 ``(segment[a,b] = {(&1 - u) * a + u * b | &0 <= u /\ u <= &1:real}) /\ 3273 (segment(a,b) = segment[a,b] DIFF {a;b:real})``, 3274 REWRITE_TAC[open_segment, closed_segment, HD]); 3275 3276val SEGMENT_REFL = store_thm ("SEGMENT_REFL", 3277 ``(!a. segment[a,a] = {a}) /\ 3278 (!a. segment(a,a) = {})``, 3279 REWRITE_TAC[segment, REAL_ARITH ``(&1 - u) * a + u * a = a:real``] THEN 3280 CONJ_TAC THENL [ALL_TAC, SET_TAC[REAL_POS]] THEN 3281 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION] THEN REPEAT GEN_TAC THEN 3282 EQ_TAC THEN REWRITE_TAC [IN_SING] THENL [METIS_TAC [], ALL_TAC] THEN DISCH_TAC THEN 3283 ASM_REWRITE_TAC [] THEN EXISTS_TAC ``1:real`` THEN REAL_ARITH_TAC); 3284 3285val IN_SEGMENT = store_thm ("IN_SEGMENT", 3286 ``!a b x:real. 3287 ((x IN segment[a,b] <=> 3288 ?u. &0 <= u /\ u <= &1 /\ (x = (&1 - u) * a + u * b:real))) /\ 3289 ((x IN segment(a,b) <=> 3290 ~(a = b) /\ ?u. &0 < u /\ u < &1 /\ (x = (&1 - u) * a + u * b:real)))``, 3291 REPEAT STRIP_TAC THENL 3292 [SIMP_TAC std_ss [segment, GSPECIFICATION, CONJ_ASSOC], ALL_TAC] THEN 3293 ASM_CASES_TAC ``a:real = b`` THEN 3294 ASM_REWRITE_TAC[SEGMENT_REFL, NOT_IN_EMPTY] THEN 3295 ASM_SIMP_TAC std_ss [OPEN_SEGMENT_ALT, GSPECIFICATION, CONJ_ASSOC] THEN METIS_TAC []); 3296 3297val SEGMENT_SYM = store_thm ("SEGMENT_SYM", 3298 ``(!a b:real. segment[a,b] = segment[b,a]) /\ 3299 (!a b:real. segment(a,b) = segment(b,a))``, 3300 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN 3301 SIMP_TAC std_ss [open_segment] THEN 3302 CONJ_TAC THENL [ALL_TAC, SIMP_TAC std_ss [INSERT_COMM, INSERT_INSERT]] THEN 3303 REWRITE_TAC[EXTENSION, IN_SEGMENT] THEN REPEAT GEN_TAC THEN EQ_TAC THEN 3304 DISCH_THEN(X_CHOOSE_TAC ``u:real``) THEN EXISTS_TAC ``&1 - u:real`` THEN 3305 ASM_REWRITE_TAC[] THEN 3306 REPEAT CONJ_TAC THEN TRY ASM_ARITH_TAC THEN ASM_REAL_ARITH_TAC); 3307 3308val ENDS_IN_SEGMENT = store_thm ("ENDS_IN_SEGMENT", 3309 ``!a b. a IN segment[a,b] /\ b IN segment[a,b]``, 3310 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [segment, GSPECIFICATION] THENL 3311 [EXISTS_TAC ``&0:real``, EXISTS_TAC ``&1:real``] THEN 3312 (CONJ_TAC THENL [REAL_ARITH_TAC, REAL_ARITH_TAC])); 3313 3314val ENDS_NOT_IN_SEGMENT = store_thm ("ENDS_NOT_IN_SEGMENT", 3315 ``!a b. ~(a IN segment(a,b)) /\ ~(b IN segment(a,b))``, 3316 REWRITE_TAC[open_segment] THEN SET_TAC[]); 3317 3318val SEGMENT_CLOSED_OPEN = store_thm ("SEGMENT_CLOSED_OPEN", 3319 ``!a b. segment[a,b] = segment(a,b) UNION {a;b}``, 3320 REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN MATCH_MP_TAC(SET_RULE 3321 ``a IN s /\ b IN s ==> (s = (s DIFF {a;b}) UNION {a;b})``) THEN 3322 REWRITE_TAC[ENDS_IN_SEGMENT]); 3323 3324val SEGMENT_OPEN_SUBSET_CLOSED = store_thm ("SEGMENT_OPEN_SUBSET_CLOSED", 3325 ``!a b. segment(a,b) SUBSET segment[a,b]``, 3326 REWRITE_TAC[CONJUNCT2(SPEC_ALL segment)] THEN SET_TAC[]); 3327 3328val MIDPOINT_IN_SEGMENT = store_thm ("MIDPOINT_IN_SEGMENT", 3329 ``(!a b:real. midpoint(a,b) IN segment[a,b]) /\ 3330 (!a b:real. midpoint(a,b) IN segment(a,b) <=> ~(a = b))``, 3331 REWRITE_TAC[IN_SEGMENT] THEN REPEAT STRIP_TAC THENL 3332 [ALL_TAC, ASM_CASES_TAC ``a:real = b`` THEN ASM_REWRITE_TAC[]] THEN 3333 EXISTS_TAC ``&1 / &2:real`` THEN REWRITE_TAC[midpoint] THEN 3334 REWRITE_TAC [REAL_HALF_BETWEEN] THEN 3335 REWRITE_TAC [METIS [REAL_HALF_DOUBLE, REAL_EQ_SUB_RADD] 3336 ``1 - 1 / 2 = 1 / 2:real``] THEN REWRITE_TAC [GSYM REAL_LDISTRIB] THEN 3337 REWRITE_TAC [REAL_INV_1OVER]); 3338 3339val BETWEEN_IN_SEGMENT = store_thm ("BETWEEN_IN_SEGMENT", 3340 ``!x a b:real. between x (a,b) <=> x IN segment[a,b]``, 3341 REPEAT GEN_TAC THEN REWRITE_TAC[between] THEN 3342 ASM_CASES_TAC ``a:real = b`` THEN 3343 ASM_REWRITE_TAC[SEGMENT_REFL, IN_SING] THENL 3344 [REWRITE_TAC [dist] THEN REAL_ARITH_TAC, ALL_TAC] THEN 3345 SIMP_TAC std_ss [segment, GSPECIFICATION] THEN EQ_TAC THENL 3346 [DISCH_THEN(ASSUME_TAC o SYM) THEN 3347 EXISTS_TAC ``dist(a:real,x) / dist(a,b)`` THEN 3348 ASM_SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ, DIST_POS_LT] THEN CONJ_TAC 3349 THENL [FIRST_ASSUM(SUBST1_TAC o SYM) THEN 3350 ASM_REWRITE_TAC [dist] THEN REWRITE_TAC [REAL_SUB_RDISTRIB, REAL_MUL_LID] THEN 3351 ONCE_REWRITE_TAC [REAL_ARITH ``(x = a - y + z) = (y - z = a - x:real)``] THEN 3352 REWRITE_TAC [GSYM REAL_SUB_LDISTRIB] THEN KNOW_TAC ``(a - b:real) <> 0`` THENL 3353 [ASM_REAL_ARITH_TAC, DISCH_TAC] THEN ASM_SIMP_TAC std_ss [GSYM ABS_DIV] THEN 3354 Cases_on `0 < a - b:real` THENL 3355 [ASM_SIMP_TAC std_ss [GSYM REAL_EQ_RDIV_EQ] THEN REWRITE_TAC [ABS_REFL] THEN 3356 ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_MUL_LZERO] THEN 3357 FULL_SIMP_TAC std_ss [dist] THEN ASM_REAL_ARITH_TAC, 3358 FULL_SIMP_TAC std_ss [REAL_NOT_LT, REAL_LE_LT] THENL 3359 [ALL_TAC, ASM_REAL_ARITH_TAC] THEN 3360 POP_ASSUM MP_TAC THEN GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_LT_NEG] THEN 3361 ONCE_REWRITE_TAC [REAL_ARITH ``(-0 = 0:real) /\ (-(a - b) = (b - a:real))``] THEN 3362 DISCH_TAC THEN ONCE_REWRITE_TAC [REAL_ARITH ``((a - b) = -(b - a:real))``] THEN 3363 ONCE_ASM_REWRITE_TAC [REAL_ARITH ``a * -b = -a * b:real``] THEN 3364 ASM_SIMP_TAC std_ss [GSYM REAL_EQ_RDIV_EQ] THEN REWRITE_TAC [real_div] THEN 3365 ONCE_REWRITE_TAC [REAL_ARITH ``(-a * b = -(a * b:real))``] THEN 3366 REWRITE_TAC [REAL_EQ_NEG] THEN KNOW_TAC ``(b - a:real) <> 0`` THENL 3367 [ASM_REAL_ARITH_TAC, DISCH_TAC] THEN ASM_SIMP_TAC std_ss [GSYM REAL_NEG_INV] THEN 3368 ONCE_REWRITE_TAC [REAL_ARITH ``(-(a * b) = (a * -b:real))``] THEN 3369 FULL_SIMP_TAC std_ss [REAL_NEG_NEG, dist] THEN 3370 REWRITE_TAC [ABS_REFL, GSYM real_div] THEN 3371 ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_MUL_LZERO] THEN 3372 ASM_REAL_ARITH_TAC], ALL_TAC] THEN FULL_SIMP_TAC std_ss [dist] THEN 3373 ASM_REAL_ARITH_TAC, ALL_TAC] THEN 3374 STRIP_TAC THEN ASM_REWRITE_TAC[dist] THEN 3375 SIMP_TAC std_ss [REAL_ARITH ``a - ((&1 - u) * a + u * b) = u * (a - b:real)``, 3376 REAL_ARITH ``((&1 - u) * a + u * b) - b = (&1 - u) * (a - b:real)``, 3377 ABS_MUL, GSYM REAL_ADD_RDISTRIB] THEN 3378 FULL_SIMP_TAC std_ss [REAL_ARITH ``u <= 1 = 0 <= 1 - u:real``, GSYM ABS_REFL] THEN 3379 REAL_ARITH_TAC); 3380 3381val REAL_CONVEX_BOUND_LE = store_thm ("REAL_CONVEX_BOUND_LE", 3382 ``!x y a u v. x <= a /\ y <= a /\ &0 <= u /\ &0 <= v /\ (u + v = &1:real) 3383 ==> u * x + v * y <= a:real``, 3384 REPEAT STRIP_TAC THEN 3385 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``(u + v) * a:real`` THEN 3386 CONJ_TAC THENL [ALL_TAC, ASM_SIMP_TAC std_ss [REAL_LE_REFL, REAL_MUL_LID]] THEN 3387 ASM_SIMP_TAC std_ss [REAL_ADD_RDISTRIB] THEN MATCH_MP_TAC REAL_LE_ADD2 THEN 3388 UNDISCH_TAC ``0 <= v:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_LE_LT] THEN 3389 STRIP_TAC THEN UNDISCH_TAC ``0 <= u:real`` THEN 3390 GEN_REWR_TAC LAND_CONV [REAL_LE_LT] THEN STRIP_TAC THEN 3391 ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 3392 POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN DISCH_TAC THEN 3393 DISCH_TAC THEN ASM_REWRITE_TAC [REAL_LE_LT, REAL_MUL_LZERO]); 3394 3395val IN_SEGMENT_COMPONENT = store_thm ("IN_SEGMENT_COMPONENT", 3396 ``!a b x:real i. x IN segment[a,b] 3397 ==> min (a) (b) <= x /\ x <= max (a) (b)``, 3398 REPEAT STRIP_TAC THEN 3399 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [IN_SEGMENT]) THEN 3400 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 3401 FIRST_X_ASSUM(X_CHOOSE_THEN ``t:real`` STRIP_ASSUME_TAC) THEN 3402 ASM_REWRITE_TAC [] THEN 3403 SIMP_TAC std_ss [REAL_ARITH ``c <= u * a + t * b <=> u * -a + t * -b <= -c:real``] THEN 3404 MATCH_MP_TAC REAL_CONVEX_BOUND_LE THEN 3405 RW_TAC real_ss [] THEN 3406 ASM_REAL_ARITH_TAC); 3407 3408val SEGMENT_TRANSLATION = store_thm ("SEGMENT_TRANSLATION", 3409 ``(!c a b. segment[c + a,c + b] = IMAGE (\x. c + x) (segment[a,b])) /\ 3410 (!c a b. segment(c + a,c + b) = IMAGE (\x. c + x) (segment(a,b)))``, 3411 SIMP_TAC std_ss [EXTENSION, IN_SEGMENT, IN_IMAGE] THEN 3412 SIMP_TAC std_ss [REAL_ARITH ``(&1 - u) * (c + a) + u * (c + b) = 3413 c + (&1 - u) * a + u * b:real``] THEN 3414 SIMP_TAC std_ss [REAL_ARITH ``(c + a:real = c + b) <=> (a = b)``] THEN 3415 CONJ_TAC THEN 3416 (REPEAT GEN_TAC THEN EQ_TAC THENL 3417 [REPEAT STRIP_TAC THEN EXISTS_TAC ``(1 - u) * a + u * b:real`` THEN 3418 ASM_SIMP_TAC std_ss [REAL_ADD_ASSOC] THEN EXISTS_TAC ``u:real`` THEN 3419 ASM_SIMP_TAC std_ss [], 3420 REPEAT STRIP_TAC THEN EXISTS_TAC ``u:real`` THEN 3421 ASM_SIMP_TAC std_ss [REAL_ADD_ASSOC]])); 3422 3423val CLOSED_SEGMENT_LINEAR_IMAGE = store_thm ("CLOSED_SEGMENT_LINEAR_IMAGE", 3424 ``!f a b. linear f 3425 ==> (segment[f a,f b] = IMAGE f (segment[a,b]))``, 3426 REPEAT STRIP_TAC THEN REWRITE_TAC[EXTENSION, IN_IMAGE, IN_SEGMENT] THEN 3427 FIRST_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN 3428 FIRST_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_ADD th)]) THEN 3429 MESON_TAC[]); 3430 3431val OPEN_SEGMENT_LINEAR_IMAGE = store_thm ("OPEN_SEGMENT_LINEAR_IMAGE", 3432 ``!f:real->real a b. 3433 linear f /\ (!x y. (f x = f y) ==> (x = y)) 3434 ==> (segment(f a,f b) = IMAGE f (segment(a,b)))``, 3435 REWRITE_TAC[open_segment, closed_segment, FST, SND, HD] THEN 3436 SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION, IN_DIFF] THEN 3437 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL 3438 [EXISTS_TAC ``(1 - u) * a + u * b:real`` THEN 3439 CONJ_TAC THENL [METIS_TAC [], ALL_TAC] THEN 3440 CONJ_TAC THENL [EXISTS_TAC ``u:real`` THEN ASM_REWRITE_TAC [], ALL_TAC] THEN 3441 ASM_SET_TAC [], 3442 CONJ_TAC THENL [EXISTS_TAC ``u:real`` THEN METIS_TAC [], ALL_TAC] THEN 3443 ASM_SET_TAC []]); 3444 3445val IN_OPEN_SEGMENT = store_thm ("IN_OPEN_SEGMENT", 3446 ``!a b x:real. 3447 x IN segment(a,b) <=> x IN segment[a,b] /\ ~(x = a) /\ ~(x = b)``, 3448 REPEAT GEN_TAC THEN REWRITE_TAC[open_segment, IN_DIFF] THEN SET_TAC[]); 3449 3450val IN_OPEN_SEGMENT_ALT = store_thm ("IN_OPEN_SEGMENT_ALT", 3451 ``!a b x:real. 3452 x IN segment(a,b) <=> 3453 x IN segment[a,b] /\ ~(x = a) /\ ~(x = b) /\ ~(a = b)``, 3454 REPEAT GEN_TAC THEN ASM_CASES_TAC ``a:real = b`` THEN 3455 ASM_REWRITE_TAC[SEGMENT_REFL, IN_SING, NOT_IN_EMPTY] THEN 3456 ASM_MESON_TAC[IN_OPEN_SEGMENT]); 3457 3458val COLLINEAR_DIST_IN_CLOSED_SEGMENT = store_thm ("COLLINEAR_DIST_IN_CLOSED_SEGMENT", 3459 ``!a b x. collinear {x;a;b} /\ 3460 dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b) 3461 ==> x IN segment[a,b]``, 3462 REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT, COLLINEAR_DIST_BETWEEN]); 3463 3464val COLLINEAR_DIST_IN_OPEN_SEGMENT = store_thm ("COLLINEAR_DIST_IN_OPEN_SEGMENT", 3465 ``!a b x. collinear {x;a;b} /\ 3466 dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b) 3467 ==> x IN segment(a,b)``, 3468 REWRITE_TAC[IN_OPEN_SEGMENT] THEN 3469 METIS_TAC[COLLINEAR_DIST_IN_CLOSED_SEGMENT, REAL_LT_LE, DIST_SYM]); 3470 3471val DIST_IN_OPEN_CLOSED_SEGMENT = store_thm ("BILINEAR_BOUNDED", 3472 ``(!a b x:real. 3473 x IN segment[a,b] ==> dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)) /\ 3474 (!a b x:real. 3475 x IN segment(a,b) ==> dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b))``, 3476 SIMP_TAC std_ss [IN_SEGMENT, GSYM RIGHT_EXISTS_AND_THM, LEFT_IMP_EXISTS_THM, dist, 3477 REAL_ARITH 3478 ``(((&1 - u) * a + u * b) - a:real = u * (b - a)) /\ 3479 (((&1 - u) * a + u * b) - b = -(&1 - u) * (b - a))``] THEN 3480 REWRITE_TAC[ABS_MUL, ABS_NEG] THEN ONCE_REWRITE_TAC [ABS_SUB] THEN CONJ_TAC THEN 3481 REPEAT GEN_TAC THEN STRIP_TAC THENL 3482 [ONCE_REWRITE_TAC [REAL_ARITH 3483 ``x * y <= abs (b - a) = x * y <= abs (a - b:real)``] THEN 3484 REWRITE_TAC[REAL_ARITH ``x * y <= y <=> x * y <= &1 * y:real``] THEN 3485 CONJ_TAC THEN MATCH_MP_TAC REAL_LE_RMUL_IMP THEN 3486 REWRITE_TAC[ABS_POS] THEN ASM_REAL_ARITH_TAC, 3487 ONCE_REWRITE_TAC [REAL_ARITH 3488 ``x * y < abs (b - a) = x * y < abs (a - b:real)``] THEN 3489 REWRITE_TAC[REAL_ARITH ``x * y < y <=> x * y < &1 * y:real``] THEN 3490 CONJ_TAC THEN MATCH_MP_TAC REAL_LT_RMUL_IMP THEN 3491 ASM_REAL_ARITH_TAC]); 3492 3493val DIST_IN_CLOSED_SEGMENT = store_thm ("DIST_IN_CLOSED_SEGMENT", 3494 ``(!a b x:real. 3495 x IN segment[a,b] ==> dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b))``, 3496 REWRITE_TAC [DIST_IN_OPEN_CLOSED_SEGMENT]); 3497 3498val DIST_IN_OPEN_SEGMENT = store_thm ("DIST_IN_OPEN_SEGMENT", 3499 ``(!a b x:real. 3500 x IN segment(a,b) ==> dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b))``, 3501 REWRITE_TAC [DIST_IN_OPEN_CLOSED_SEGMENT]); 3502 3503(* ------------------------------------------------------------------------- *) 3504(* Connectedness. *) 3505(* ------------------------------------------------------------------------- *) 3506 3507val connected = new_definition ("connected", 3508 ``connected s <=> 3509 ~(?e1 e2. open e1 /\ open e2 /\ s SUBSET (e1 UNION e2) /\ 3510 (e1 INTER e2 INTER s = {}) /\ 3511 ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))``); 3512 3513val CONNECTED_CLOSED = store_thm ("CONNECTED_CLOSED", 3514 ``!s:real->bool. 3515 connected s <=> 3516 ~(?e1 e2. closed e1 /\ closed e2 /\ s SUBSET (e1 UNION e2) /\ 3517 (e1 INTER e2 INTER s = {}) /\ 3518 ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))``, 3519 GEN_TAC THEN REWRITE_TAC[connected] THEN AP_TERM_TAC THEN 3520 EQ_TAC THEN STRIP_TAC THEN 3521 MAP_EVERY EXISTS_TAC [``univ(:real) DIFF e1``, ``univ(:real) DIFF e2``] THEN 3522 ASM_REWRITE_TAC[GSYM closed_def, GSYM OPEN_CLOSED] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 3523 3524val CONNECTED_OPEN_IN = store_thm ("CONNECTED_OPEN_IN", 3525 ``!s. connected s <=> 3526 ~(?e1 e2. 3527 open_in (subtopology euclidean s) e1 /\ 3528 open_in (subtopology euclidean s) e2 /\ 3529 s SUBSET e1 UNION e2 /\ 3530 (e1 INTER e2 = {}) /\ 3531 ~(e1 = {}) /\ 3532 ~(e2 = {}))``, 3533 GEN_TAC THEN REWRITE_TAC[connected, OPEN_IN_OPEN] THEN 3534 SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM] THEN 3535 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN SET_TAC[]); 3536 3537val CONNECTED_OPEN_IN_EQ = store_thm ("CONNECTED_OPEN_IN_EQ", 3538 ``!s. connected s <=> 3539 ~(?e1 e2. 3540 open_in (subtopology euclidean s) e1 /\ 3541 open_in (subtopology euclidean s) e2 /\ 3542 (e1 UNION e2 = s) /\ (e1 INTER e2 = {}) /\ 3543 ~(e1 = {}) /\ ~(e2 = {}))``, 3544 GEN_TAC THEN REWRITE_TAC[CONNECTED_OPEN_IN] THEN 3545 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN 3546 EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN 3547 RULE_ASSUM_TAC(REWRITE_RULE[OPEN_IN_CLOSED_IN_EQ, 3548 TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN 3549 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 3550 3551val CONNECTED_CLOSED_IN = store_thm ("CONNECTED_CLOSED_IN", 3552 ``!s. connected s <=> 3553 ~(?e1 e2. 3554 closed_in (subtopology euclidean s) e1 /\ 3555 closed_in (subtopology euclidean s) e2 /\ 3556 s SUBSET e1 UNION e2 /\ 3557 (e1 INTER e2 = {}) /\ 3558 ~(e1 = {}) /\ 3559 ~(e2 = {}))``, 3560 GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED, CLOSED_IN_CLOSED] THEN 3561 SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM] THEN 3562 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN SET_TAC[]); 3563 3564val CONNECTED_CLOSED_IN_EQ = store_thm ("CONNECTED_CLOSED_IN_EQ", 3565 ``!s. connected s <=> 3566 ~(?e1 e2. 3567 closed_in (subtopology euclidean s) e1 /\ 3568 closed_in (subtopology euclidean s) e2 /\ 3569 (e1 UNION e2 = s) /\ (e1 INTER e2 = {}) /\ 3570 ~(e1 = {}) /\ ~(e2 = {}))``, 3571 GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED_IN] THEN 3572 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN 3573 EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN 3574 RULE_ASSUM_TAC(REWRITE_RULE[closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN 3575 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 3576 3577val EXISTS_DIFF = store_thm ("EXISTS_DIFF", 3578 ``(?s:'a->bool. P(UNIV DIFF s)) <=> (?s. P s)``, 3579 MESON_TAC[prove(``UNIV DIFF (UNIV DIFF s) = s``,SET_TAC[])]); 3580 3581val CONNECTED_CLOPEN = store_thm ("CONNECTED_CLOPEN", 3582 ``!s. connected s <=> 3583 !t. open_in (subtopology euclidean s) t /\ 3584 closed_in (subtopology euclidean s) t ==> (t = {}) \/ (t = s)``, 3585 GEN_TAC THEN REWRITE_TAC[connected, OPEN_IN_OPEN, CLOSED_IN_CLOSED] THEN 3586 REWRITE_TAC [METIS [GSYM EXISTS_DIFF] ``!e1. (?e2. open e2) = 3587 ?e2. open (univ(:real) DIFF e2)``] THEN 3588 KNOW_TAC ``(?e1 e2. open e1 /\ open e2 /\ s SUBSET e1 UNION e2 /\ 3589 (e1 INTER e2 INTER s = {}) /\ e1 INTER s <> {} /\ 3590 e2 INTER s <> {}) = 3591 (?e1 e2. open e1 /\ open (univ(:real) DIFF e2) /\ 3592 s SUBSET e1 UNION (univ(:real) DIFF e2) /\ 3593 (e1 INTER (univ(:real) DIFF e2) INTER s = {}) /\ e1 INTER s <> {} /\ 3594 (univ(:real) DIFF e2) INTER s <> {})`` THENL 3595 [EQ_TAC THENL [STRIP_TAC THEN EXISTS_TAC ``e1:real->bool`` THEN 3596 ASM_SIMP_TAC std_ss [EXISTS_DIFF] THEN METIS_TAC [], 3597 METIS_TAC [GSYM EXISTS_DIFF]], ALL_TAC] THEN DISC_RW_KILL THEN 3598 ONCE_REWRITE_TAC[TAUT `(~a <=> b) <=> (a <=> ~b)`] THEN 3599 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, GSYM CONJ_ASSOC, DE_MORGAN_THM] THEN 3600 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> b /\ a /\ c /\ d`] THEN 3601 KNOW_TAC ``(?t. (?t'. closed t' /\ (t = s INTER t')) /\ 3602 (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s) = 3603 (?t t'. (closed t' /\ (t = s INTER t')) /\ 3604 (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s)`` THENL 3605 [SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM], ALL_TAC] THEN DISC_RW_KILL THEN 3606 REWRITE_TAC [GSYM closed_def] THEN 3607 KNOW_TAC ``((?e1 e2. closed e2 /\ open e1 /\ s SUBSET e1 UNION (univ(:real) DIFF e2) /\ 3608 (e1 INTER (univ(:real) DIFF e2) INTER s = {}) /\ e1 INTER s <> {} /\ 3609 (univ(:real) DIFF e2) INTER s <> {}) <=> ?t t'. (closed t' /\ (t = s INTER t')) /\ 3610 (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s) = 3611 ((?e2 e1. closed e2 /\ open e1 /\ s SUBSET e1 UNION (univ(:real) DIFF e2) /\ 3612 (e1 INTER (univ(:real) DIFF e2) INTER s = {}) /\ e1 INTER s <> {} /\ 3613 (univ(:real) DIFF e2) INTER s <> {}) <=> ?t' t. (closed t' /\ (t = s INTER t')) /\ 3614 (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s)`` THENL 3615 [METIS_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN AP_TERM_TAC THEN ABS_TAC THEN 3616 KNOW_TAC ``(?t. (closed e2 /\ (t = s INTER e2)) /\ 3617 (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s) = 3618 (?t' t.(closed e2 /\ (t = s INTER e2)) /\ 3619 (open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s)`` THENL 3620 [METIS_TAC [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM], ALL_TAC] THEN 3621 DISC_RW_KILL THEN AP_TERM_TAC THEN ABS_TAC THEN 3622 REWRITE_TAC[TAUT `(a /\ b) /\ (c /\ d) /\ e <=> a /\ c /\ b /\ d /\ e`] THEN 3623 SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN 3624 AP_TERM_TAC THEN AP_TERM_TAC THEN SET_TAC[]); 3625 3626val CONNECTED_CLOSED_SET = store_thm ("CONNECTED_CLOSED_SET", 3627 ``!s:real->bool. 3628 closed s 3629 ==> (connected s <=> 3630 ~(?e1 e2. closed e1 /\ closed e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\ 3631 (e1 UNION e2 = s) /\ (e1 INTER e2 = {})))``, 3632 REPEAT STRIP_TAC THEN EQ_TAC THENL 3633 [REWRITE_TAC [CONNECTED_CLOSED, GSYM MONO_NOT_EQ] THEN 3634 STRIP_TAC THEN EXISTS_TAC ``e1:real->bool`` THEN 3635 EXISTS_TAC ``e2:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN 3636 REWRITE_TAC [AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN 3637 SIMP_TAC std_ss [] THEN SET_TAC[], 3638 REWRITE_TAC [CONNECTED_CLOSED_IN, GSYM MONO_NOT_EQ] THEN 3639 SIMP_TAC std_ss [PULL_EXISTS] THEN 3640 SIMP_TAC std_ss [CLOSED_IN_CLOSED, LEFT_IMP_EXISTS_THM, GSYM AND_IMP_INTRO] THEN 3641 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 3642 REWRITE_TAC[AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN 3643 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 3644 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 3645 [``s INTER u:real->bool``, ``s INTER v:real->bool``] THEN 3646 ASM_SIMP_TAC std_ss [CLOSED_INTER] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]); 3647 3648val CONNECTED_OPEN_SET = store_thm ("CONNECTED_OPEN_SET", 3649 ``!s:real->bool. 3650 open s 3651 ==> (connected s <=> 3652 ~(?e1 e2. open e1 /\ open e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\ 3653 (e1 UNION e2 = s) /\ (e1 INTER e2 = {})))``, 3654 REPEAT STRIP_TAC THEN EQ_TAC THENL 3655 [REWRITE_TAC[connected, GSYM MONO_NOT_EQ] THEN 3656 STRIP_TAC THEN EXISTS_TAC ``e1:real->bool`` THEN 3657 EXISTS_TAC ``e2:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN 3658 REWRITE_TAC [AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN 3659 SIMP_TAC std_ss [] THEN SET_TAC[], 3660 REWRITE_TAC [CONNECTED_OPEN_IN, GSYM MONO_NOT_EQ] THEN 3661 SIMP_TAC std_ss [PULL_EXISTS] THEN 3662 SIMP_TAC std_ss [OPEN_IN_OPEN, LEFT_IMP_EXISTS_THM, GSYM AND_IMP_INTRO] THEN 3663 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 3664 REWRITE_TAC[AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN 3665 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 3666 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 3667 [``s INTER u:real->bool``, ``s INTER v:real->bool``] THEN 3668 ASM_SIMP_TAC std_ss [OPEN_INTER] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]); 3669 3670val CONNECTED_IFF_CONNECTABLE_POINTS = store_thm ("CONNECTED_IFF_CONNECTABLE_POINTS", 3671 ``!s:real->bool. 3672 connected s <=> 3673 !a b. a IN s /\ b IN s 3674 ==> ?t. connected t /\ t SUBSET s /\ a IN t /\ b IN t``, 3675 GEN_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSET_REFL], DISCH_TAC] THEN 3676 SIMP_TAC std_ss [connected, NOT_EXISTS_THM] THEN 3677 MAP_EVERY X_GEN_TAC [``e1:real->bool``, ``e2:real->bool``] THEN 3678 REWRITE_TAC [METIS [DE_MORGAN_THM] ``~a \/ ~b \/ ~c \/ (d <> e) \/ (f = g) \/ (h = i) = 3679 ~(a /\ b /\ c /\ (d = e) /\ (f <> g) /\ (h <> i))``] THEN 3680 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 3681 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 3682 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 3683 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 3684 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER] THEN DISCH_THEN(CONJUNCTS_THEN2 3685 (X_CHOOSE_TAC ``a:real``) (X_CHOOSE_TAC ``b:real``)) THEN 3686 FIRST_X_ASSUM(MP_TAC o SPECL [``a:real``, ``b:real``]) THEN 3687 ASM_REWRITE_TAC[connected] THEN 3688 DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN 3689 REWRITE_TAC[] THEN 3690 MAP_EVERY EXISTS_TAC [``e1:real->bool``, ``e2:real->bool``] THEN 3691 ASM_SET_TAC[]); 3692 3693val CONNECTED_EMPTY = store_thm ("CONNECTED_EMPTY", 3694 ``connected {}``, 3695 REWRITE_TAC[connected, INTER_EMPTY]); 3696 3697val CONNECTED_SING = store_thm ("CONNECTED_SING", 3698 ``!a. connected{a}``, 3699 REWRITE_TAC[connected] THEN SET_TAC[]); 3700 3701val CONNECTED_REAL_LEMMA = store_thm ("CONNECTED_REAL_LEMMA", 3702 ``!f:real->real a b e1 e2. 3703 a <= b /\ f(a) IN e1 /\ f(b) IN e2 /\ 3704 (!e x. a <= x /\ x <= b /\ &0 < e 3705 ==> ?d. &0 < d /\ 3706 !y. abs(y - x) < d ==> dist(f(y),f(x)) < e) /\ 3707 (!y. y IN e1 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e1) /\ 3708 (!y. y IN e2 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e2) /\ 3709 ~(?x. a <= x /\ x <= b /\ f(x) IN e1 /\ f(x) IN e2) 3710 ==> ?x. a <= x /\ x <= b /\ ~(f(x) IN e1) /\ ~(f(x) IN e2)``, 3711 REWRITE_TAC[EXTENSION, NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN 3712 MP_TAC(SPEC ``\c. !x:real. a <= x /\ x <= c ==> (f(x):real) IN e1`` 3713 REAL_COMPLETE) THEN 3714 SIMP_TAC std_ss [] THEN 3715 KNOW_TAC ``(?x:real. !x'. a <= x' /\ x' <= x ==> (f x'):real IN e1) /\ 3716 (?M. !x. (!x'. a <= x' /\ x' <= x ==> f x' IN e1) ==> x <= M)`` THENL 3717 [METIS_TAC[REAL_LT_IMP_LE, REAL_LE_TOTAL, REAL_LE_ANTISYM], 3718 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 3719 DISCH_THEN (X_CHOOSE_TAC ``x:real``) THEN EXISTS_TAC ``x:real`` THEN 3720 POP_ASSUM MP_TAC THEN STRIP_TAC THEN 3721 SUBGOAL_THEN ``a <= x /\ x <= b:real`` STRIP_ASSUME_TAC THENL 3722 [METIS_TAC[REAL_LT_IMP_LE, REAL_LE_TOTAL, REAL_LE_ANTISYM], ALL_TAC] THEN 3723 ASM_REWRITE_TAC[] THEN 3724 SUBGOAL_THEN ``!z:real. a <= z /\ z < x ==> (f(z):real) IN e1`` ASSUME_TAC THENL 3725 [METIS_TAC[REAL_NOT_LT, REAL_LT_IMP_LE], ALL_TAC] THEN 3726 REPEAT STRIP_TAC THENL 3727 [SUBGOAL_THEN 3728 ``?d:real. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real) IN e1`` 3729 STRIP_ASSUME_TAC THENL [METIS_TAC[], ALL_TAC] THEN 3730 METIS_TAC[REAL_ARITH ``z <= x + e /\ e < d ==> z < x \/ abs(z - x) < d:real``, 3731 REAL_ARITH ``&0 < e ==> ~(x + e <= x:real)``, REAL_DOWN], 3732 SUBGOAL_THEN 3733 ``?d:real. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real) IN e2`` 3734 STRIP_ASSUME_TAC THENL [METIS_TAC[], ALL_TAC] THEN 3735 MP_TAC(SPECL [``x - a:real``, ``d:real``] REAL_DOWN2) THEN 3736 KNOW_TAC ``0 < x - a:real /\ 0 < d:real`` THENL 3737 [METIS_TAC[REAL_LT_LE, REAL_SUB_LT], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 3738 METIS_TAC[REAL_ARITH ``e < x - a ==> a <= x - e:real``, 3739 REAL_ARITH ``&0 < e /\ x <= b ==> x - e <= b:real``, 3740 REAL_ARITH ``&0 < e /\ e < d ==> x - e < x /\ abs((x - e) - x) < d:real``]]); 3741 3742val CONNECTED_SEGMENT = store_thm ("CONNECTED_SEGMENT", 3743 ``(!a b:real. connected(segment[a,b])) /\ 3744 (!a b:real. connected(segment(a,b)))``, 3745 CONJ_TAC THEN REPEAT GEN_TAC THENL 3746 [ASM_CASES_TAC ``b:real = a`` THEN 3747 ASM_SIMP_TAC std_ss [SEGMENT_REFL, CONNECTED_EMPTY, CONNECTED_SING] THEN 3748 ASM_SIMP_TAC std_ss [connected, OPEN_SEGMENT_ALT, CONJUNCT1 segment, 3749 NOT_EXISTS_THM] THEN 3750 REWRITE_TAC [METIS [DE_MORGAN_THM] 3751 ``~a \/ ~b \/ ~c \/ (d <> e) \/ (f = g) \/ (h = i) = 3752 ~(a /\ b /\ c /\ (d = e) /\ (f <> g) /\ (h <> i))`` ] THEN 3753 MAP_EVERY X_GEN_TAC [``e1:real->bool``, ``e2:real->bool``] THEN 3754 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 3755 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 3756 PURE_ONCE_REWRITE_TAC[INTER_COMM] THEN 3757 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REWRITE_TAC [IN_INTER] THEN 3758 DISCH_TAC THEN DISCH_TAC THEN 3759 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN 3760 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN 3761 REWRITE_TAC [GSYM CONJ_ASSOC] THEN 3762 SIMP_TAC std_ss [NOT_EXISTS_THM, LEFT_IMP_EXISTS_THM] THEN 3763 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN 3764 MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN 3765 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 3766 MAP_EVERY (fn t => SPEC_TAC(t,t)) 3767 [``e2:real->bool``, ``e1:real->bool``, ``v:real``, ``u:real``] THEN 3768 KNOW_TAC ``!(u :real) (v :real). (\u v. !(e1 :real -> bool) (e2 :real -> bool). 3769 (e1 INTER e2 INTER 3770 {((1 :real) - u) * (a :real) + u * (b :real) | 3771 (0 :real) <= u /\ u <= (1 :real)} = 3772 ({} :real -> bool)) /\ 3773 {((1 :real) - u) * a + u * b | 3774 (0 :real) <= u /\ u <= (1 :real)} SUBSET e1 UNION e2 /\ 3775 (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3776 (0 :real) <= u /\ u <= (1 :real) /\ 3777 ((1 :real) - u) * a + u * b IN e1 ==> 3778 ~((0 :real) <= v) \/ ~(v <= (1 :real)) \/ 3779 ((1 :real) - v) * a + v * b NOTIN e2) u v`` THENL 3780 [ALL_TAC, METIS_TAC []] THEN 3781 MATCH_MP_TAC REAL_WLOG_LE THEN CONJ_TAC THENL 3782 [MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN BETA_TAC THEN 3783 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) 3784 [UNION_COMM, INTER_COMM] THEN 3785 KNOW_TAC ``(!(e1 :real -> bool) (e2 :real -> bool). 3786 (e1 INTER e2 INTER 3787 {((1 :real) - u) * (a :real) + u * (b :real) | 3788 (0 :real) <= u /\ u <= (1 :real)} = 3789 ({} :real -> bool)) /\ 3790 {((1 :real) - u) * a + u * b | 3791 (0 :real) <= u /\ u <= (1 :real)} SUBSET e1 UNION e2 /\ 3792 (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3793 (0 :real) <= (u :real) /\ u <= (1 :real) /\ 3794 ((1 :real) - u) * a + u * b IN e1 ==> 3795 ~((0 :real) <= (v :real)) \/ ~(v <= (1 :real)) \/ 3796 ((1 :real) - v) * a + v * b NOTIN e2) <=> 3797 !(e2 :real -> bool) (e1 :real -> bool). 3798 ({((1 :real) - u) * a + u * b | 3799 (0 :real) <= u /\ u <= (1 :real)} INTER (e1 INTER e2) = 3800 ({} :real -> bool)) /\ 3801 {((1 :real) - u) * a + u * b | 3802 (0 :real) <= u /\ u <= (1 :real)} SUBSET e2 UNION e1 /\ 3803 (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3804 (0 :real) <= v /\ v <= (1 :real) /\ 3805 ((1 :real) - v) * a + v * b IN e1 ==> 3806 ~((0 :real) <= u) \/ ~(u <= (1 :real)) \/ 3807 ((1 :real) - u) * a + u * b NOTIN e2`` THENL 3808 [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]] THEN 3809 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN 3810 SIMP_TAC std_ss [UNION_ACI, INTER_ACI] THEN METIS_TAC[], 3811 ALL_TAC] THEN 3812 MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN 3813 SIMP_TAC std_ss [] THEN 3814 REPEAT STRIP_TAC THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 3815 MP_TAC(ISPECL 3816 [``\u. (&1 - u) * a + u * b:real``, ``u:real``, ``v:real``, 3817 ``e1:real->bool``, ``e2:real->bool``] 3818 CONNECTED_REAL_LEMMA) THEN BETA_TAC THEN 3819 ASM_REWRITE_TAC [GSYM open_def, REAL_POS, NOT_IMP] THEN 3820 REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL 3821 [MAP_EVERY X_GEN_TAC [``e:real``, ``x:real``] THEN STRIP_TAC THEN 3822 EXISTS_TAC ``e / dist(a:real,b)`` THEN 3823 ASM_SIMP_TAC std_ss [REAL_LT_DIV, GSYM DIST_NZ] THEN 3824 GEN_TAC THEN REWRITE_TAC[dist] THEN STRIP_TAC THEN 3825 ASM_SIMP_TAC std_ss [ABS_MUL, GSYM REAL_LT_RDIV_EQ, GSYM ABS_NZ, REAL_SUB_0, 3826 ABS_NEG, REAL_ARITH 3827 ``((&1 - y') * a + y' * b) - ((&1 - x') * a + x' * b):real = 3828 -((y' - x') * (a - b))``], 3829 RULE_ASSUM_TAC(SIMP_RULE std_ss [EXTENSION, IN_INTER, GSPECIFICATION, 3830 SUBSET_DEF, IN_UNION, NOT_IN_EMPTY]) THEN 3831 METIS_TAC[REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS]], ALL_TAC] THEN 3832 ASM_CASES_TAC ``b:real = a`` THEN 3833 ASM_SIMP_TAC std_ss [SEGMENT_REFL, CONNECTED_EMPTY, CONNECTED_SING] THEN 3834 ASM_SIMP_TAC std_ss [connected, OPEN_SEGMENT_ALT, CONJUNCT1 segment, 3835 NOT_EXISTS_THM] THEN 3836 REWRITE_TAC [METIS [DE_MORGAN_THM] 3837 ``~a \/ ~b \/ ~c \/ (d <> e) \/ (f = g) \/ (h = i) = 3838 ~(a /\ b /\ c /\ (d = e) /\ (f <> g) /\ (h <> i))`` ] THEN 3839 MAP_EVERY X_GEN_TAC [``e1:real->bool``, ``e2:real->bool``] THEN 3840 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 3841 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 3842 PURE_ONCE_REWRITE_TAC[INTER_COMM] THEN 3843 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REWRITE_TAC [IN_INTER] THEN 3844 DISCH_TAC THEN DISCH_TAC THEN 3845 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN 3846 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN 3847 REWRITE_TAC [GSYM CONJ_ASSOC] THEN 3848 SIMP_TAC std_ss [NOT_EXISTS_THM, LEFT_IMP_EXISTS_THM] THEN 3849 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN 3850 MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN 3851 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 3852 MAP_EVERY (fn t => SPEC_TAC(t,t)) 3853 [``e2:real->bool``, ``e1:real->bool``, ``v:real``, ``u:real``] THEN 3854 KNOW_TAC ``!(u :real) (v :real). (\u v. !(e1 :real -> bool) (e2 :real -> bool). 3855 (e1 INTER e2 INTER 3856 {((1 :real) - u) * (a :real) + u * (b :real) | 3857 (0 :real) < u /\ u < (1 :real)} = 3858 ({} :real -> bool)) /\ 3859 {((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} SUBSET 3860 e1 UNION e2 /\ (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3861 (0 :real) < u /\ u < (1 :real) /\ 3862 ((1 :real) - u) * a + u * b IN e1 ==> 3863 ~((0 :real) < v) \/ ~(v < (1 :real)) \/ 3864 ((1 :real) - v) * a + v * b NOTIN e2) u v`` THENL 3865 [ALL_TAC, METIS_TAC []] THEN 3866 MATCH_MP_TAC REAL_WLOG_LE THEN CONJ_TAC THENL 3867 [MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN BETA_TAC THEN 3868 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) 3869 [UNION_COMM, INTER_COMM] THEN 3870 KNOW_TAC `` (!(e1 :real -> bool) (e2 :real -> bool). 3871 (e1 INTER e2 INTER 3872 {((1 :real) - u) * (a :real) + u * (b :real) | 3873 (0 :real) < u /\ u < (1 :real)} = 3874 ({} :real -> bool)) /\ 3875 {((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} SUBSET 3876 e1 UNION e2 /\ (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3877 (0 :real) < (u :real) /\ u < (1 :real) /\ 3878 ((1 :real) - u) * a + u * b IN e1 ==> 3879 ~((0 :real) < (v :real)) \/ ~(v < (1 :real)) \/ 3880 ((1 :real) - v) * a + v * b NOTIN e2) <=> 3881 !(e2 :real -> bool) (e1 :real -> bool). 3882 ({((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} INTER 3883 (e1 INTER e2) = 3884 ({} :real -> bool)) /\ 3885 {((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} SUBSET 3886 e2 UNION e1 /\ (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==> 3887 (0 :real) < v /\ v < (1 :real) /\ 3888 ((1 :real) - v) * a + v * b IN e1 ==> 3889 ~((0 :real) < u) \/ ~(u < (1 :real)) \/ 3890 ((1 :real) - u) * a + u * b NOTIN e2`` THENL 3891 [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]] THEN 3892 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN 3893 SIMP_TAC std_ss [UNION_ACI, INTER_ACI] THEN METIS_TAC[], 3894 ALL_TAC] THEN 3895 MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN 3896 SIMP_TAC std_ss [] THEN 3897 REPEAT STRIP_TAC THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 3898 MP_TAC(ISPECL 3899 [``\u. (&1 - u) * a + u * b:real``, ``u:real``, ``v:real``, 3900 ``e1:real->bool``, ``e2:real->bool``] 3901 CONNECTED_REAL_LEMMA) THEN BETA_TAC THEN 3902 ASM_REWRITE_TAC [GSYM open_def, REAL_POS, NOT_IMP] THEN 3903 REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL 3904 [MAP_EVERY X_GEN_TAC [``e:real``, ``x:real``] THEN STRIP_TAC THEN 3905 EXISTS_TAC ``e / dist(a:real,b)`` THEN 3906 ASM_SIMP_TAC std_ss [REAL_LT_DIV, GSYM DIST_NZ] THEN 3907 GEN_TAC THEN REWRITE_TAC[dist] THEN STRIP_TAC THEN 3908 ASM_SIMP_TAC std_ss [ABS_MUL, GSYM REAL_LT_RDIV_EQ, GSYM ABS_NZ, REAL_SUB_0, 3909 ABS_NEG, REAL_ARITH 3910 ``((&1 - y') * a + y' * b) - ((&1 - x') * a + x' * b):real = 3911 -((y' - x') * (a - b))``], 3912 RULE_ASSUM_TAC(SIMP_RULE std_ss [EXTENSION, IN_INTER, GSPECIFICATION, 3913 SUBSET_DEF, IN_UNION, NOT_IN_EMPTY]) THEN 3914 METIS_TAC[REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS]]); 3915 3916val CONNECTED_UNIV = store_thm ("CONNECTED_UNIV", 3917 ``connected univ(:real)``, 3918 ONCE_REWRITE_TAC[CONNECTED_IFF_CONNECTABLE_POINTS] THEN 3919 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN 3920 REWRITE_TAC[IN_UNIV, SUBSET_UNIV] THEN 3921 EXISTS_TAC ``segment[a:real,b]`` THEN 3922 ASM_SIMP_TAC std_ss [CONNECTED_SEGMENT, ENDS_IN_SEGMENT]); 3923 3924val CLOPEN = store_thm ("CLOPEN", 3925 ``!s. closed s /\ open s <=> (s = {}) \/ (s = univ(:real))``, 3926 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN 3927 ASM_REWRITE_TAC[CLOSED_EMPTY, OPEN_EMPTY, CLOSED_UNIV, OPEN_UNIV] THEN 3928 MATCH_MP_TAC(REWRITE_RULE[CONNECTED_CLOPEN] CONNECTED_UNIV) THEN 3929 ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV, GSYM OPEN_IN, GSYM CLOSED_IN]); 3930 3931val CONNECTED_BIGUNION = store_thm ("CONNECTED_BIGUNION", 3932 ``!P:(real->bool)->bool. 3933 (!s. s IN P ==> connected s) /\ ~(BIGINTER P = {}) 3934 ==> connected(BIGUNION P)``, 3935 GEN_TAC THEN REWRITE_TAC[connected] THEN STRIP_TAC THEN 3936 CCONTR_TAC THEN POP_ASSUM (MP_TAC o REWRITE_RULE [REAL_NEG_NEG]) THEN 3937 STRIP_TAC THEN UNDISCH_TAC ``~(BIGINTER P :real->bool = {})`` THEN 3938 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_BIGINTER] THEN 3939 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 3940 SUBGOAL_THEN ``(a:real) IN e1 \/ a IN e2`` STRIP_ASSUME_TAC THENL 3941 [ASM_SET_TAC[], 3942 UNDISCH_TAC ``~(e2 INTER BIGUNION P:real->bool = {})``, 3943 UNDISCH_TAC ``~(e1 INTER BIGUNION P:real->bool = {})``] THEN 3944 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER, IN_BIGUNION] THEN 3945 DISCH_THEN(X_CHOOSE_THEN ``b:real`` 3946 (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 3947 DISCH_THEN(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN 3948 UNDISCH_TAC ``!t:real->bool. t IN P ==> a IN t`` THEN 3949 DISCH_THEN(MP_TAC o SPEC ``s:real->bool``) THEN 3950 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 3951 FIRST_X_ASSUM(MP_TAC o SPEC ``s:real->bool``) THEN 3952 ASM_REWRITE_TAC[] THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 3953 POP_ASSUM (MP_TAC o SPECL [``e1:real->bool``, ``e2:real->bool``]) THEN 3954 ASM_SET_TAC[]); 3955 3956val CONNECTED_UNION = store_thm ("CONNECTED_UNION", 3957 ``!s t:real->bool. 3958 connected s /\ connected t /\ ~(s INTER t = {}) 3959 ==> connected (s UNION t)``, 3960 REWRITE_TAC[GSYM BIGUNION_2, GSYM BIGINTER_2] THEN 3961 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_BIGUNION THEN 3962 ASM_SET_TAC[]); 3963 3964val CONNECTED_DIFF_OPEN_FROM_CLOSED = store_thm ("CONNECTED_DIFF_OPEN_FROM_CLOSED", 3965 ``!s t u:real->bool. 3966 s SUBSET t /\ t SUBSET u /\ 3967 open s /\ closed t /\ connected u /\ connected(t DIFF s) 3968 ==> connected(u DIFF s)``, 3969 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [connected, NOT_EXISTS_THM] THEN 3970 MAP_EVERY X_GEN_TAC [``v:real->bool``, ``w:real->bool``] THEN 3971 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 3972 UNDISCH_TAC ``connected(t DIFF s:real->bool)`` THEN SIMP_TAC std_ss [connected] THEN 3973 MAP_EVERY EXISTS_TAC [``v:real->bool``, ``w:real->bool``] THEN 3974 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN 3975 CONJ_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN 3976 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 3977 MAP_EVERY (fn t => SPEC_TAC(t,t)) [``v:real->bool``, ``w:real->bool``] THEN 3978 KNOW_TAC ``(!v:real->bool w:real->bool. 3979 ~(w INTER (u DIFF s) = {}) /\ ~(v INTER (u DIFF s) = {}) /\ 3980 (v INTER w INTER (u DIFF s) = {}) /\ u DIFF s SUBSET v UNION w /\ 3981 open w /\ open v /\ connected u /\ closed t /\ open s /\ 3982 t SUBSET u /\ s SUBSET t 3983 ==> ~(v INTER (u DIFF s) = {}) /\ ~(w INTER (u DIFF s) = {}) /\ 3984 (w INTER v INTER (u DIFF s) = {}) /\ u DIFF s SUBSET w UNION v /\ 3985 open v /\ open w /\ connected u /\ closed t /\ open s /\ 3986 t SUBSET u /\ s SUBSET t) /\ 3987 (!w v. (~(w INTER (u DIFF s) = {}) /\ ~(v INTER (u DIFF s) = {}) /\ 3988 (v INTER w INTER (u DIFF s) = {}) /\ u DIFF s SUBSET v UNION w /\ 3989 open w /\ open v /\ connected u /\ closed t /\ open s /\ 3990 t SUBSET u /\ s SUBSET t) /\ (w INTER (t DIFF s) = {}) 3991 ==> F)`` THENL 3992 [CONJ_TAC THENL [SIMP_TAC std_ss [CONJ_ACI, INTER_ACI, UNION_ACI], ALL_TAC] THEN 3993 REPEAT STRIP_TAC THEN UNDISCH_TAC ``connected u`` THEN 3994 GEN_REWR_TAC LAND_CONV [connected] THEN SIMP_TAC std_ss [] THEN 3995 MAP_EVERY EXISTS_TAC [``v UNION s:real->bool``, ``w DIFF t:real->bool``] THEN 3996 ASM_SIMP_TAC std_ss [OPEN_UNION, OPEN_DIFF] THEN ASM_SET_TAC[], METIS_TAC []]); 3997 3998val CONNECTED_DISJOINT_BIGUNION_OPEN_UNIQUE = store_thm 3999 ("CONNECTED_DISJOINT_BIGUNION_OPEN_UNIQUE", 4000 ``!f:(real->bool)->bool f'. 4001 pairwise DISJOINT f /\ pairwise DISJOINT f' /\ 4002 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 4003 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 4004 (BIGUNION f = BIGUNION f') 4005 ==> (f = f')``, 4006 GEN_REWR_TAC (funpow 2 BINDER_CONV o RAND_CONV) [EXTENSION] THEN 4007 KNOW_TAC ``(!f f'. 4008 pairwise DISJOINT f /\ pairwise DISJOINT f' /\ 4009 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 4010 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 4011 (BIGUNION f = BIGUNION f') 4012 ==> pairwise DISJOINT f' /\ pairwise DISJOINT f /\ 4013 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 4014 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 4015 (BIGUNION f' = BIGUNION f)) /\ 4016 (!f f' x. (pairwise DISJOINT f /\ pairwise DISJOINT f' /\ 4017 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 4018 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 4019 (BIGUNION f = BIGUNION f')) /\ x IN f ==> x IN f')`` THENL 4020 [ALL_TAC, METIS_TAC []] THEN 4021 CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN 4022 GEN_TAC THEN GEN_TAC THEN X_GEN_TAC ``s:real->bool`` THEN STRIP_TAC THEN 4023 SUBGOAL_THEN 4024 ``?t a:real. t IN f' /\ a IN s /\ a IN t`` STRIP_ASSUME_TAC 4025 THENL [ASM_SET_TAC[], ALL_TAC] THEN 4026 SUBGOAL_THEN ``s:real->bool = t`` (fn th => ASM_REWRITE_TAC[th]) THEN 4027 REWRITE_TAC[EXTENSION] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 4028 MAP_EVERY (fn t => SPEC_TAC(t,t)) 4029 [``s:real->bool``, ``t:real->bool``, 4030 ``f:(real->bool)->bool``, ``f':(real->bool)->bool``] THEN 4031 KNOW_TAC ``(!f f' s t. 4032 a IN t /\ a IN s /\ t IN f' /\ s IN f /\ 4033 (BIGUNION f = BIGUNION f') /\ 4034 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 4035 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 4036 pairwise DISJOINT f' /\ pairwise DISJOINT f 4037 ==> a IN s /\ a IN t /\ s IN f /\ t IN f' /\ 4038 (BIGUNION f' = BIGUNION f) /\ 4039 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 4040 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 4041 pairwise DISJOINT f /\ pairwise DISJOINT f') /\ 4042 (!f f' s t x. 4043 (a IN t /\ a IN s /\ t IN f' /\ s IN f /\ 4044 (BIGUNION f = BIGUNION f') /\ 4045 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\ 4046 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\ 4047 pairwise DISJOINT f' /\ pairwise DISJOINT f) /\ 4048 x IN s ==> x IN t)`` THENL 4049 [ALL_TAC, METIS_TAC []] THEN 4050 CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN 4051 GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN 4052 X_GEN_TAC ``b:real`` THEN STRIP_TAC THEN 4053 UNDISCH_TAC 4054 ``!s:real->bool. s IN f ==> open s /\ connected s /\ ~(s = {})`` THEN 4055 DISCH_THEN(MP_TAC o SPEC ``s:real->bool``) THEN ASM_REWRITE_TAC[] THEN 4056 STRIP_TAC THEN ASM_CASES_TAC ``(b:real) IN t`` THEN 4057 ASM_REWRITE_TAC[] THEN 4058 UNDISCH_TAC ``connected(s:real->bool)`` THEN 4059 REWRITE_TAC[connected] THEN 4060 MAP_EVERY EXISTS_TAC 4061 [``t:real->bool``, ``BIGUNION(f' DELETE (t:real->bool))``] THEN 4062 REPEAT STRIP_TAC THENL 4063 [ASM_SIMP_TAC std_ss [], 4064 MATCH_MP_TAC OPEN_BIGUNION THEN ASM_SIMP_TAC std_ss [IN_DELETE], 4065 REWRITE_TAC[GSYM BIGUNION_INSERT] THEN ASM_SET_TAC[], 4066 MATCH_MP_TAC(SET_RULE ``(t INTER u = {}) ==> (t INTER u INTER s = {})``) THEN 4067 SIMP_TAC std_ss [INTER_BIGUNION, EMPTY_BIGUNION, FORALL_IN_GSPEC] THEN 4068 REWRITE_TAC [IN_DELETE, GSYM DISJOINT_DEF] THEN ASM_MESON_TAC[pairwise], 4069 ASM_SET_TAC[], ASM_SET_TAC[]]); 4070 4071val CONNECTED_FROM_CLOSED_UNION_AND_INTER = store_thm ("CONNECTED_FROM_CLOSED_UNION_AND_INTER", 4072 ``!s t:real->bool. 4073 closed s /\ closed t /\ connected(s UNION t) /\ connected(s INTER t) 4074 ==> connected s /\ connected t``, 4075 KNOW_TAC ``(!s t. closed s /\ closed t /\ 4076 connected (s UNION t) /\ connected (s INTER t) 4077 ==> closed t /\ closed s /\ connected (t UNION s) /\ 4078 connected (t INTER s)) /\ 4079 (!s t. closed s /\ closed t /\ connected (s UNION t) /\ 4080 connected (s INTER t) ==> connected s)`` THENL 4081 [ALL_TAC, MESON_TAC []] THEN 4082 CONJ_TAC THENL [SIMP_TAC std_ss [UNION_COMM, INTER_COMM], REPEAT STRIP_TAC] THEN 4083 ASM_SIMP_TAC std_ss [CONNECTED_CLOSED_SET] THEN 4084 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 4085 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 4086 ASM_CASES_TAC 4087 ``~(s INTER t SUBSET (u:real->bool)) /\ ~(s INTER t SUBSET v)`` 4088 THENL 4089 [UNDISCH_TAC ``connected(s INTER t:real->bool)`` THEN 4090 ASM_SIMP_TAC std_ss [CONNECTED_CLOSED] THEN 4091 MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN 4092 ASM_REWRITE_TAC[] THEN ASM_SET_TAC [], 4093 POP_ASSUM (MP_TAC o REWRITE_RULE [DE_MORGAN_THM]) THEN 4094 STRIP_TAC THEN UNDISCH_TAC ``connected(s UNION t:real->bool)`` THEN 4095 ASM_SIMP_TAC std_ss [CONNECTED_CLOSED] THENL 4096 [MAP_EVERY EXISTS_TAC [``t UNION u:real->bool``, ``v:real->bool``] THEN 4097 ASM_SIMP_TAC std_ss [CLOSED_UNION] THEN ASM_SET_TAC[], 4098 MAP_EVERY EXISTS_TAC [``t UNION v:real->bool``, ``u:real->bool``] THEN 4099 ASM_SIMP_TAC std_ss [CLOSED_UNION] THEN ASM_SET_TAC[]]]); 4100 4101val CONNECTED_FROM_OPEN_UNION_AND_INTER = store_thm ("CONNECTED_FROM_OPEN_UNION_AND_INTER", 4102 ``!s t:real->bool. 4103 open s /\ open t /\ connected(s UNION t) /\ connected(s INTER t) 4104 ==> connected s /\ connected t``, 4105 4106 KNOW_TAC ``(!s t. 4107 open s /\ open t /\ connected (s UNION t) /\ connected (s INTER t) 4108 ==> open t /\ open s /\ connected (t UNION s) /\ connected (t INTER s)) /\ 4109 (!s t. 4110 open s /\ open t /\ connected (s UNION t) /\ connected (s INTER t) 4111 ==> connected s)`` THENL 4112 [ALL_TAC, MESON_TAC []] THEN 4113 CONJ_TAC THENL [SIMP_TAC std_ss [UNION_COMM, INTER_COMM], REPEAT STRIP_TAC] THEN 4114 ASM_SIMP_TAC std_ss [CONNECTED_OPEN_SET] THEN 4115 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 4116 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN ASM_CASES_TAC 4117 ``~(s INTER t SUBSET (u:real->bool)) /\ ~(s INTER t SUBSET v)`` 4118 THENL 4119 [UNDISCH_TAC ``connected(s INTER t:real->bool)`` THEN 4120 ASM_SIMP_TAC std_ss [connected] THEN 4121 MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN 4122 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[], 4123 POP_ASSUM (MP_TAC o REWRITE_RULE [DE_MORGAN_THM]) THEN 4124 STRIP_TAC THEN UNDISCH_TAC ``connected(s UNION t:real->bool)`` THEN 4125 ASM_SIMP_TAC std_ss [connected] THENL 4126 [MAP_EVERY EXISTS_TAC [``t UNION u:real->bool``, ``v:real->bool``] THEN 4127 ASM_SIMP_TAC std_ss [OPEN_UNION] THEN ASM_SET_TAC[], 4128 MAP_EVERY EXISTS_TAC [``t UNION v:real->bool``, ``u:real->bool``] THEN 4129 ASM_SIMP_TAC std_ss [OPEN_UNION] THEN ASM_SET_TAC[]]]); 4130 4131(* ------------------------------------------------------------------------- *) 4132(* Sort of induction principle for connected sets. *) 4133(* ------------------------------------------------------------------------- *) 4134 4135val CONNECTED_INDUCTION = store_thm ("CONNECTED_INDUCTION", 4136 ``!P Q s:real->bool. connected s /\ 4137 (!t a. open_in (subtopology euclidean s) t /\ a IN t 4138 ==> ?z. z IN t /\ P z) /\ (!a. a IN s 4139 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ 4140 !x y. x IN t /\ y IN t /\ P x /\ P y /\ Q x ==> Q y) 4141 ==> !a b. a IN s /\ b IN s /\ P a /\ P b /\ Q a ==> Q b``, 4142 REPEAT STRIP_TAC THEN 4143 GEN_REWR_TAC I [TAUT `p <=> ~ ~p`] THEN DISCH_TAC THEN 4144 UNDISCH_TAC ``connected s`` THEN GEN_REWR_TAC LAND_CONV [CONNECTED_OPEN_IN] THEN 4145 REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC 4146 [``{b:real | ?t. open_in (subtopology euclidean s) t /\ 4147 b IN t /\ !x. x IN t /\ P x ==> Q x}``, 4148 ``{b:real | ?t. open_in (subtopology euclidean s) t /\ 4149 b IN t /\ !x. x IN t /\ P x ==> ~(Q x)}``] THEN 4150 REPEAT CONJ_TAC THENL 4151 [ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN 4152 X_GEN_TAC ``c:real`` THEN SIMP_TAC std_ss [GSPECIFICATION] THEN 4153 ASM_SET_TAC[], 4154 ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN 4155 X_GEN_TAC ``c:real`` THEN SIMP_TAC std_ss [GSPECIFICATION] THEN 4156 ASM_SET_TAC[], 4157 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNION] THEN 4158 X_GEN_TAC ``c:real`` THEN DISCH_TAC THEN 4159 FIRST_X_ASSUM(MP_TAC o SPEC ``c:real``) THEN ASM_SET_TAC[], 4160 KNOW_TAC ``!x. ~((?t. open_in (subtopology euclidean s) t /\ 4161 x IN t /\ (!x. x IN t /\ P x ==> Q x)) /\ 4162 (?t. open_in (subtopology euclidean s) t /\ x IN t /\ 4163 (!x. x IN t /\ P x ==> ~Q x)))`` THENL 4164 [ALL_TAC, SIMP_TAC std_ss [EXTENSION, IN_INTER, NOT_IN_EMPTY, GSPECIFICATION]] THEN 4165 X_GEN_TAC ``c:real`` THEN DISCH_THEN(CONJUNCTS_THEN2 4166 (X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) 4167 (X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC)) THEN 4168 FIRST_X_ASSUM(MP_TAC o SPECL [``t INTER u:real->bool``, ``c:real``]) THEN 4169 ASM_SIMP_TAC std_ss [OPEN_IN_INTER] THEN ASM_SET_TAC[], 4170 ASM_SET_TAC[], ASM_SET_TAC[]]); 4171 4172val CONNECTED_EQUIVALENCE_RELATION_GEN = store_thm ("CONNECTED_EQUIVALENCE_RELATION_GEN", 4173 ``!P R s:real->bool. connected s /\ (!x y. R x y ==> R y x) /\ 4174 (!x y z. R x y /\ R y z ==> R x z) /\ 4175 (!t a. open_in (subtopology euclidean s) t /\ a IN t 4176 ==> ?z. z IN t /\ P z) /\ (!a. a IN s 4177 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ 4178 !x y. x IN t /\ y IN t /\ P x /\ P y ==> R x y) 4179 ==> !a b. a IN s /\ b IN s /\ P a /\ P b ==> R a b``, 4180 REPEAT GEN_TAC THEN STRIP_TAC THEN 4181 SUBGOAL_THEN 4182 ``!a:real. a IN s /\ P a 4183 ==> !b c. b IN s /\ c IN s /\ P b /\ P c /\ R a b ==> R a c`` 4184 MP_TAC THENL [ALL_TAC, ASM_MESON_TAC[]] THEN 4185 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION THEN 4186 ASM_REWRITE_TAC [] THEN 4187 X_GEN_TAC ``b:real`` THEN POP_ASSUM MP_TAC THEN 4188 POP_ASSUM (MP_TAC o Q.SPEC `b:real`) THEN 4189 METIS_TAC[]); 4190 4191val CONNECTED_INDUCTION_SIMPLE = store_thm ("CONNECTED_INDUCTION_SIMPLE", 4192 ``!P s:real->bool. connected s /\ 4193 (!a. a IN s 4194 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ 4195 !x y. x IN t /\ y IN t /\ P x ==> P y) 4196 ==> !a b. a IN s /\ b IN s /\ P a ==> P b``, 4197 MP_TAC(ISPEC ``\x:real. T`` CONNECTED_INDUCTION) THEN 4198 REWRITE_TAC[] THEN STRIP_TAC THEN 4199 MAP_EVERY X_GEN_TAC [``Q:real->bool``, ``s:real->bool``] THEN 4200 POP_ASSUM (MP_TAC o Q.SPECL [`Q:real->bool`, `s:real->bool`]) THEN 4201 METIS_TAC[]); 4202 4203val CONNECTED_EQUIVALENCE_RELATION = store_thm ("CONNECTED_EQUIVALENCE_RELATION", 4204 ``!R s:real->bool. connected s /\ 4205 (!x y. R x y ==> R y x) /\ 4206 (!x y z. R x y /\ R y z ==> R x z) /\ 4207 (!a. a IN s 4208 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ 4209 !x. x IN t ==> R a x) 4210 ==> !a b. a IN s /\ b IN s ==> R a b``, 4211 REPEAT GEN_TAC THEN STRIP_TAC THEN 4212 SUBGOAL_THEN 4213 ``!a:real. a IN s ==> !b c. b IN s /\ c IN s /\ R a b ==> R a c`` 4214 MP_TAC THENL [ALL_TAC, ASM_MESON_TAC[]] THEN 4215 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION_SIMPLE THEN 4216 ASM_MESON_TAC[]); 4217 4218(* ------------------------------------------------------------------------- *) 4219(* Limit points. *) 4220(* ------------------------------------------------------------------------- *) 4221 4222val _ = set_fixity "limit_point_of" (Infix(NONASSOC, 450)); 4223 4224val limit_point_of = new_definition ("limit_point_of", 4225 ``x limit_point_of s <=> 4226 !t. x IN t /\ open t ==> ?y. ~(y = x) /\ y IN s /\ y IN t``); 4227 4228val LIMPT_SUBSET = store_thm ("LIMPT_SUBSET", 4229 ``!x s t. x limit_point_of s /\ s SUBSET t ==> x limit_point_of t``, 4230 REWRITE_TAC[limit_point_of, SUBSET_DEF] THEN MESON_TAC[]); 4231 4232val LIMPT_APPROACHABLE = store_thm ("LIMPT_APPROACHABLE", 4233 ``!x s. x limit_point_of s <=> 4234 !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) < e``, 4235 REPEAT GEN_TAC THEN REWRITE_TAC[limit_point_of] THEN 4236 MESON_TAC[open_def, DIST_SYM, OPEN_BALL, CENTRE_IN_BALL, IN_BALL]); 4237 4238val lemma = prove ( 4239 ``&0 < d:real ==> x <= d / &2 ==> x < d``, 4240 SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_LT] THEN REAL_ARITH_TAC); 4241 4242val APPROACHABLE_LT_LE = store_thm ("APPROACHABLE_LT_LE", 4243 ``!P f. (?d:real. &0 < d /\ !x. f(x) < d ==> P x) = 4244 (?d:real. &0 < d /\ !x. f(x) <= d ==> P x)``, 4245 MESON_TAC[REAL_LT_IMP_LE, lemma, REAL_LT_HALF1]); 4246 4247val LIMPT_APPROACHABLE_LE = store_thm ("LIMPT_APPROACHABLE_LE", 4248 ``!x s. x limit_point_of s <=> 4249 !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) <= e``, 4250 REPEAT GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN 4251 MATCH_MP_TAC(TAUT `(~a <=> ~b) ==> (a <=> b)`) THEN 4252 KNOW_TAC ``!e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e) = 4253 (\e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e)) e`` THENL 4254 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 4255 KNOW_TAC ``!e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) <= e) = 4256 (\e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) <= e)) e `` THENL 4257 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 4258 REWRITE_TAC [NOT_FORALL_THM] THEN BETA_TAC THEN REWRITE_TAC [NOT_IMP] THEN 4259 KNOW_TAC ``!x'' x'. ( x'' IN s /\ x'' <> x /\ dist (x'',x) < x') = 4260 (\x''. x'' IN s /\ x'' <> x /\ dist (x'',x) < x') x''`` THENL 4261 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 4262 KNOW_TAC ``!x'' x'. ( x'' IN s /\ x'' <> x /\ dist (x'',x) <= x') = 4263 (\x''. x'' IN s /\ x'' <> x /\ dist (x'',x) <= x') x''`` THENL 4264 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 4265 REWRITE_TAC [NOT_EXISTS_THM] THEN BETA_TAC THEN 4266 SIMP_TAC std_ss [TAUT `~(a /\ b /\ c) <=> c ==> ~(a /\ b)`, APPROACHABLE_LT_LE]); 4267 4268val REAL_CHOOSE_SIZE = store_thm ("REAL_CHOOSE_SIZE", 4269 ``!c. &0 <= c ==> (?x. abs x = c:real)``, 4270 METIS_TAC [ABS_REFL]); 4271 4272val LIMPT_UNIV = store_thm ("LIMPT_UNIV", 4273 ``!x:real. x limit_point_of UNIV``, 4274 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE, IN_UNIV] THEN 4275 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 4276 SUBGOAL_THEN ``?c:real. abs(c) = e / &2`` CHOOSE_TAC THENL 4277 [ASM_SIMP_TAC std_ss [REAL_CHOOSE_SIZE, REAL_LT_HALF1, REAL_LT_IMP_LE], 4278 ALL_TAC] THEN 4279 EXISTS_TAC ``x + c:real`` THEN 4280 REWRITE_TAC[dist, REAL_ADD_RID_UNIQ] THEN ASM_REWRITE_TAC[REAL_ADD_SUB] THEN 4281 ASM_REWRITE_TAC [REAL_LT_HALF2] THEN KNOW_TAC ``0 < abs c:real`` THENL 4282 [ASM_SIMP_TAC std_ss [REAL_LT_HALF1], METIS_TAC [ABS_NZ]]); 4283 4284val CLOSED_LIMPT = store_thm ("CLOSED_LIMPT", 4285 ``!s. closed s <=> !x. x limit_point_of s ==> x IN s``, 4286 REWRITE_TAC[closed_def] THEN ONCE_REWRITE_TAC[OPEN_SUB_OPEN] THEN 4287 REWRITE_TAC[limit_point_of, IN_DIFF, IN_UNIV, SUBSET_DEF] THEN MESON_TAC[]); 4288 4289val LIMPT_EMPTY = store_thm ("LIMPT_EMPTY", 4290 ``!x. ~(x limit_point_of {})``, 4291 REWRITE_TAC[LIMPT_APPROACHABLE, NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]); 4292 4293val NO_LIMIT_POINT_IMP_CLOSED = store_thm ("NO_LIMIT_POINT_IMP_CLOSED", 4294 ``!s. ~(?x. x limit_point_of s) ==> closed s``, 4295 MESON_TAC[CLOSED_LIMPT]); 4296 4297val CLOSED_POSITIVE_ORTHANT = store_thm ("CLOSED_POSITIVE_ORTHANT", 4298 ``closed {x:real | &0 <= x}``, 4299 REWRITE_TAC[CLOSED_LIMPT, LIMPT_APPROACHABLE] THEN 4300 SIMP_TAC std_ss [GSPECIFICATION] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 4301 REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN 4302 FIRST_X_ASSUM(MP_TAC o SPEC ``-(x:real)``) THEN 4303 ASM_SIMP_TAC std_ss [REAL_LT_RNEG, REAL_ADD_LID, NOT_EXISTS_THM] THEN 4304 X_GEN_TAC ``y:real`` THEN ONCE_REWRITE_TAC [METIS []``(a = b) = ~(a <> b:real)``] THEN 4305 REWRITE_TAC [GSYM DE_MORGAN_THM] THEN 4306 MATCH_MP_TAC(TAUT `(a ==> ~c) ==> ~(a /\ b /\ c)`) THEN DISCH_TAC THEN 4307 MATCH_MP_TAC(REAL_ARITH ``!b. abs x <= b /\ b <= a ==> ~(a + x < &0:real)``) THEN 4308 EXISTS_TAC ``abs(y - x :real)`` THEN ASM_SIMP_TAC std_ss [dist, REAL_LE_REFL] THEN 4309 ASM_SIMP_TAC std_ss [REAL_ARITH ``x < &0 /\ &0 <= y:real ==> abs(x) <= abs(y - x)``]); 4310 4311val FINITE_SET_AVOID = store_thm ("FINITE_SET_AVOID", 4312 ``!a:real s. FINITE s 4313 ==> ?d. &0 < d /\ !x. x IN s /\ ~(x = a) ==> d <= dist(a,x)``, 4314 GEN_TAC THEN 4315 KNOW_TAC ``!s. (?d. 0 < d /\ !x:real. x IN s /\ x <> a ==> d <= dist (a,x)) = 4316 (\s. ?d. 0 < d /\ !x:real. x IN s /\ x <> a ==> d <= dist (a,x)) s `` THENL 4317 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 4318 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 4319 REWRITE_TAC[NOT_IN_EMPTY] THEN 4320 CONJ_TAC THENL [MESON_TAC[REAL_LT_01], ALL_TAC] THEN 4321 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 4322 MAP_EVERY X_GEN_TAC [``s:real->bool``, ``x:real``] THEN 4323 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN DISCH_TAC THEN 4324 FIRST_X_ASSUM(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 4325 ASM_CASES_TAC ``x:real = a`` THEN REWRITE_TAC[IN_INSERT] THENL 4326 [ASM_MESON_TAC[], ALL_TAC] THEN 4327 EXISTS_TAC ``min d (dist(a:real,x))`` THEN 4328 ASM_REWRITE_TAC[REAL_LT_MIN, GSYM DIST_NZ, REAL_MIN_LE] THEN 4329 ASM_MESON_TAC[REAL_LE_REFL]); 4330 4331val LIMIT_POINT_FINITE = store_thm ("LIMIT_POINT_FINITE", 4332 ``!s a. FINITE s ==> ~(a limit_point_of s)``, 4333 REWRITE_TAC[LIMPT_APPROACHABLE, GSYM REAL_NOT_LE] THEN 4334 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM, REAL_NOT_LE, 4335 REAL_NOT_LT, TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN 4336 MESON_TAC[FINITE_SET_AVOID, DIST_SYM]); 4337 4338val LIMPT_SING = store_thm ("LIMPT_SING", 4339 ``!x y:real. ~(x limit_point_of {y})``, 4340 SIMP_TAC std_ss [LIMIT_POINT_FINITE, FINITE_SING]); 4341 4342val LIMIT_POINT_UNION = store_thm ("LIMIT_POINT_UNION", 4343 ``!s t x:real. x limit_point_of (s UNION t) <=> 4344 x limit_point_of s \/ x limit_point_of t``, 4345 REPEAT GEN_TAC THEN EQ_TAC THENL 4346 [ALL_TAC, MESON_TAC[LIMPT_SUBSET, SUBSET_UNION]] THEN 4347 REWRITE_TAC[LIMPT_APPROACHABLE, IN_UNION] THEN DISCH_TAC THEN 4348 MATCH_MP_TAC(TAUT `(~a ==> b) ==> a \/ b`) THEN 4349 KNOW_TAC ``!e. &0 < e /\ ~(?x'. x' IN s /\ ~(x' = x) /\ dist (x',x) < e) 4350 ==> (!e. &0 < e ==> (?x'. x' IN t /\ ~(x' = x) /\ dist (x',x) < e))`` THENL 4351 [ALL_TAC, SIMP_TAC std_ss [NOT_FORALL_THM, LEFT_IMP_EXISTS_THM, NOT_IMP]] THEN 4352 X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN 4353 FIRST_X_ASSUM(MP_TAC o SPEC ``min d e:real``) THEN ASM_MESON_TAC[REAL_LT_MIN]); 4354 4355val LIMPT_INSERT = store_thm ("LIMPT_INSERT", 4356 ``!s x y:real. x limit_point_of (y INSERT s) <=> x limit_point_of s``, 4357 ONCE_REWRITE_TAC[SET_RULE ``y:real INSERT s = {y} UNION s``] THEN 4358 REWRITE_TAC[LIMIT_POINT_UNION] THEN 4359 SIMP_TAC std_ss [FINITE_SING, LIMIT_POINT_FINITE]); 4360 4361val LIMPT_OF_LIMPTS = store_thm ("LIMPT_OF_LIMPTS", 4362 ``!x:real s. x limit_point_of {y | y limit_point_of s} 4363 ==> x limit_point_of s``, 4364 SIMP_TAC std_ss [LIMPT_APPROACHABLE, GSPECIFICATION] THEN REPEAT GEN_TAC THEN 4365 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 4366 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN 4367 DISCH_THEN (X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN 4368 FIRST_X_ASSUM(MP_TAC o SPEC ``dist(y:real,x)``) THEN 4369 ASM_SIMP_TAC std_ss [DIST_POS_LT] THEN 4370 DISCH_THEN (X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN 4371 EXISTS_TAC ``z:real`` THEN 4372 ASM_REWRITE_TAC[] THEN 4373 CONJ_TAC THENL 4374 [FIRST_ASSUM MP_TAC THEN GEN_REWR_TAC (LAND_CONV o LAND_CONV) [DIST_SYM] THEN 4375 REWRITE_TAC [dist] THEN REAL_ARITH_TAC, ALL_TAC] THEN 4376 FULL_SIMP_TAC std_ss [dist, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 4377 ASM_REAL_ARITH_TAC); 4378 4379val CLOSED_LIMPTS = store_thm ("CLOSED_LIMPTS", 4380 ``!s. closed {x:real | x limit_point_of s}``, 4381 SIMP_TAC std_ss [CLOSED_LIMPT, GSPECIFICATION, LIMPT_OF_LIMPTS]); 4382 4383val DISCRETE_IMP_CLOSED = store_thm ("DISCRETE_IMP_CLOSED", 4384 ``!s:real->bool e. &0 < e /\ 4385 (!x y. x IN s /\ y IN s /\ abs(y - x) < e ==> (y = x)) 4386 ==> closed s``, 4387 REPEAT STRIP_TAC THEN 4388 SUBGOAL_THEN ``!x:real. ~(x limit_point_of s)`` 4389 (fn th => MESON_TAC[th, CLOSED_LIMPT]) THEN 4390 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN DISCH_TAC THEN 4391 FIRST_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 4392 REWRITE_TAC[REAL_LT_HALF1, ASSUME ``&0 < e:real``] THEN 4393 DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN 4394 FIRST_X_ASSUM(MP_TAC o SPEC ``min (e / &2) (dist(x:real,y))``) THEN 4395 ASM_REWRITE_TAC [REAL_LT_MIN, REAL_LT_HALF1] THEN 4396 KNOW_TAC ``0 < dist(x,y:real)`` THENL 4397 [ASM_SIMP_TAC std_ss [DIST_POS_LT], ALL_TAC] THEN 4398 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 4399 DISCH_THEN(X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN 4400 FIRST_X_ASSUM(MP_TAC o SPECL [``y:real``, ``z:real``]) THEN 4401 ASM_SIMP_TAC arith_ss [GSYM dist] THEN CONJ_TAC THENL 4402 [MATCH_MP_TAC REAL_LET_TRANS THEN 4403 EXISTS_TAC ``dist(z,x) + dist(x,y:real)`` THEN 4404 METIS_TAC [DIST_TRIANGLE, GSYM REAL_HALF_DOUBLE, REAL_LT_ADD2, DIST_SYM], 4405 REPEAT (POP_ASSUM MP_TAC) THEN REWRITE_TAC [dist, DIST_NZ] THEN 4406 REAL_ARITH_TAC]); 4407 4408val LIMPT_OF_UNIV = store_thm ("LIMPT_OF_UNIV", 4409 ``!x. x limit_point_of univ(:real)``, 4410 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE, IN_UNIV] THEN 4411 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 4412 MP_TAC(ISPECL [``x:real``, ``e / &2:real``] REAL_CHOOSE_DIST) THEN 4413 KNOW_TAC ``0 <= e / 2:real`` THENL 4414 [METIS_TAC [REAL_LT_HALF1, REAL_LE_LT], ALL_TAC] THEN DISCH_TAC THEN 4415 ASM_REWRITE_TAC [] THEN STRIP_TAC THEN EXISTS_TAC ``y:real`` THEN 4416 CONJ_TAC THENL [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN 4417 ASM_REWRITE_TAC [DIST_NZ, REAL_LT_HALF1], MATCH_MP_TAC REAL_LET_TRANS THEN 4418 EXISTS_TAC ``e / 2:real`` THEN METIS_TAC [REAL_LT_HALF2, REAL_LE_LT, DIST_SYM]]); 4419 4420val LIMPT_OF_OPEN_IN = store_thm ("LIMPT_OF_OPEN_IN", 4421 ``!s t x:real. open_in (subtopology euclidean s) t /\ 4422 x limit_point_of s /\ x IN t 4423 ==> x limit_point_of t``, 4424 REWRITE_TAC[open_in, SUBSET_DEF, LIMPT_APPROACHABLE] THEN 4425 REPEAT GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 4426 UNDISCH_TAC ``!x. x IN t ==> 4427 ?e. 0 < e /\ !x'. x' IN s /\ dist (x',x) < e ==> x' IN t`` THEN DISCH_TAC THEN 4428 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 4429 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 4430 UNDISCH_TAC ``!e. 0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e`` THEN 4431 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``min d e / &2:real``) THEN 4432 KNOW_TAC ``0 < min d e / 2:real`` THENL [REWRITE_TAC [min_def] THEN 4433 METIS_TAC [REAL_LT_HALF1], ALL_TAC] THEN DISCH_TAC THEN 4434 ASM_REWRITE_TAC [] THEN STRIP_TAC THEN EXISTS_TAC ``x':real`` THEN 4435 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN TRY (FIRST_X_ASSUM MATCH_MP_TAC) THEN 4436 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_TRANS THEN 4437 EXISTS_TAC ``min d e / 2:real`` THEN ASM_REWRITE_TAC [] THEN 4438 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d e:real`` THEN 4439 METIS_TAC [REAL_MIN_LE1, min_def, REAL_LT_HALF2]); 4440 4441val LIMPT_OF_OPEN = store_thm ("LIMPT_OF_OPEN", 4442 ``!s x:real. open s /\ x IN s ==> x limit_point_of s``, 4443 REWRITE_TAC[OPEN_IN] THEN ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN 4444 MESON_TAC[LIMPT_OF_OPEN_IN, LIMPT_OF_UNIV]); 4445 4446val OPEN_IN_SING = store_thm ("OPEN_IN_SING", 4447 ``!s a. open_in (subtopology euclidean s) {a} <=> 4448 a IN s /\ ~(a limit_point_of s)``, 4449 REWRITE_TAC[open_in, LIMPT_APPROACHABLE, SING_SUBSET, IN_SING] THEN 4450 METIS_TAC[]); 4451 4452(* ------------------------------------------------------------------------- *) 4453(* Interior of a set. *) 4454(* ------------------------------------------------------------------------- *) 4455 4456val interior = new_definition ("interior", 4457 ``interior s = {x | ?t. open t /\ x IN t /\ t SUBSET s}``); 4458 4459val INTERIOR_EQ = store_thm ("INTERIOR_EQ", 4460 ``!s. (interior s = s) <=> open s``, 4461 GEN_TAC THEN REWRITE_TAC[EXTENSION, interior] THEN 4462 SIMP_TAC std_ss [GSPECIFICATION] THEN GEN_REWR_TAC RAND_CONV [OPEN_SUB_OPEN] 4463 THEN MESON_TAC[SUBSET_DEF]); 4464 4465val INTERIOR_OPEN = store_thm ("INTERIOR_OPEN", 4466 ``!s. open s ==> (interior s = s)``, 4467 MESON_TAC[INTERIOR_EQ]); 4468 4469val INTERIOR_EMPTY = store_thm ("INTERIOR_EMPTY", 4470 ``interior {} = {}``, 4471 SIMP_TAC std_ss [INTERIOR_OPEN, OPEN_EMPTY]); 4472 4473val INTERIOR_UNIV = store_thm ("INTERIOR_UNIV", 4474 ``interior univ(:real) = univ(:real)``, 4475 SIMP_TAC std_ss [INTERIOR_OPEN, OPEN_UNIV]); 4476 4477val OPEN_INTERIOR = store_thm ("OPEN_INTERIOR", 4478 ``!s. open(interior s)``, 4479 GEN_TAC THEN REWRITE_TAC[interior] THEN GEN_REWR_TAC I [OPEN_SUB_OPEN] THEN 4480 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN MESON_TAC[]); 4481 4482val INTERIOR_INTERIOR = store_thm ("INTERIOR_INTERIOR", 4483 ``!s. interior(interior s) = interior s``, 4484 MESON_TAC[INTERIOR_EQ, OPEN_INTERIOR]); 4485 4486val INTERIOR_SUBSET = store_thm ("INTERIOR_SUBSET", 4487 ``!s. (interior s) SUBSET s``, 4488 SIMP_TAC std_ss [SUBSET_DEF, interior, GSPECIFICATION] THEN MESON_TAC[]); 4489 4490val SUBSET_INTERIOR_EQ = store_thm ("SUBSET_INTERIOR_EQ", 4491 ``!s:real->bool. s SUBSET interior s <=> open s``, 4492 REWRITE_TAC[GSYM INTERIOR_EQ, 4493 SET_RULE ``!(s:real->bool) t. (s = t) <=> s SUBSET t /\ t SUBSET s``, 4494 INTERIOR_SUBSET]); 4495 4496val SUBSET_INTERIOR = store_thm ("SUBSET_INTERIOR", 4497 ``!s t. s SUBSET t ==> (interior s) SUBSET (interior t)``, 4498 SIMP_TAC std_ss [interior, SUBSET_DEF, GSPECIFICATION] THEN MESON_TAC[]); 4499 4500val INTERIOR_MAXIMAL = store_thm ("INTERIOR_MAXIMAL", 4501 ``!s t. t SUBSET s /\ open t ==> t SUBSET (interior s)``, 4502 SIMP_TAC std_ss[interior, SUBSET_DEF, GSPECIFICATION] THEN MESON_TAC[]); 4503 4504val INTERIOR_MAXIMAL_EQ = store_thm ("INTERIOR_MAXIMAL_EQ", 4505 ``!s t:real->bool. open s ==> (s SUBSET interior t <=> s SUBSET t)``, 4506 MESON_TAC[INTERIOR_MAXIMAL, SUBSET_TRANS, INTERIOR_SUBSET]); 4507 4508val INTERIOR_UNIQUE = store_thm ("INTERIOR_UNIQUE", 4509 ``!s t. t SUBSET s /\ open t /\ (!t'. t' SUBSET s /\ open t' ==> t' SUBSET t) 4510 ==> (interior s = t)``, 4511 MESON_TAC[SUBSET_ANTISYM, INTERIOR_MAXIMAL, INTERIOR_SUBSET, OPEN_INTERIOR]); 4512 4513val IN_INTERIOR = store_thm ("IN_INTERIOR", 4514 ``!x s. x IN interior s <=> ?e. &0 < e /\ ball(x,e) SUBSET s``, 4515 SIMP_TAC std_ss [interior, GSPECIFICATION] THEN 4516 MESON_TAC[OPEN_CONTAINS_BALL, SUBSET_TRANS, CENTRE_IN_BALL, OPEN_BALL]); 4517 4518val OPEN_SUBSET_INTERIOR = store_thm ("OPEN_SUBSET_INTERIOR", 4519 ``!s t. open s ==> (s SUBSET interior t <=> s SUBSET t)``, 4520 MESON_TAC[INTERIOR_MAXIMAL, INTERIOR_SUBSET, SUBSET_TRANS]); 4521 4522val INTERIOR_INTER = store_thm ("INTERIOR_INTER", 4523 ``!s t:real->bool. interior(s INTER t) = interior s INTER interior t``, 4524 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 4525 [REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THEN 4526 MATCH_MP_TAC SUBSET_INTERIOR THEN REWRITE_TAC[INTER_SUBSET], 4527 MATCH_MP_TAC INTERIOR_MAXIMAL THEN SIMP_TAC std_ss [OPEN_INTER, OPEN_INTERIOR] THEN 4528 MATCH_MP_TAC(SET_RULE 4529 ``s SUBSET s' /\ t SUBSET t' ==> s INTER t SUBSET s' INTER t'``) THEN 4530 REWRITE_TAC[INTERIOR_SUBSET]]); 4531 4532val INTERIOR_FINITE_BIGINTER = store_thm ("INTERIOR_FINITE_BIGINTER", 4533 ``!s:(real->bool)->bool. 4534 FINITE s ==> (interior(BIGINTER s) = BIGINTER(IMAGE interior s))``, 4535 GEN_TAC THEN KNOW_TAC ``(interior (BIGINTER s) = BIGINTER (IMAGE interior s)) = 4536 (\s:(real->bool)->bool. (interior (BIGINTER s) = BIGINTER (IMAGE interior s))) s`` THENL 4537 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 4538 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 4539 REWRITE_TAC[BIGINTER_EMPTY, BIGINTER_INSERT, INTERIOR_UNIV, IMAGE_EMPTY, 4540 IMAGE_INSERT] THEN SIMP_TAC std_ss [INTERIOR_INTER]); 4541 4542val INTERIOR_BIGINTER_SUBSET = store_thm ("INTERIOR_BIGINTER_SUBSET", 4543 ``!f. interior(BIGINTER f) SUBSET BIGINTER (IMAGE interior f)``, 4544 REWRITE_TAC[SUBSET_DEF, IN_INTERIOR, IN_BIGINTER, FORALL_IN_IMAGE] THEN 4545 MESON_TAC[]); 4546 4547val UNION_INTERIOR_SUBSET = store_thm ("UNION_INTERIOR_SUBSET", 4548 ``!s t:real->bool. 4549 interior s UNION interior t SUBSET interior(s UNION t)``, 4550 SIMP_TAC std_ss [INTERIOR_MAXIMAL_EQ, OPEN_UNION, OPEN_INTERIOR] THEN 4551 REPEAT GEN_TAC THEN MATCH_MP_TAC(SET_RULE 4552 ``s SUBSET s' /\ t SUBSET t' ==> (s UNION t) SUBSET (s' UNION t')``) THEN 4553 REWRITE_TAC[INTERIOR_SUBSET]); 4554 4555val INTERIOR_EQ_EMPTY = store_thm ("INTERIOR_EQ_EMPTY", 4556 ``!s:real->bool. (interior s = {}) <=> !t. open t /\ t SUBSET s ==> (t = {})``, 4557 MESON_TAC[INTERIOR_MAXIMAL_EQ, SUBSET_EMPTY, 4558 OPEN_INTERIOR, INTERIOR_SUBSET]); 4559 4560val INTERIOR_EQ_EMPTY_ALT = store_thm ("INTERIOR_EQ_EMPTY_ALT", 4561 ``!s:real->bool. (interior s = {}) <=> 4562 !t. open t /\ ~(t = {}) ==> ~(t DIFF s = {})``, 4563 GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY] THEN SET_TAC[]); 4564 4565val INTERIOR_LIMIT_POINT = store_thm ("INTERIOR_LIMIT_POINT", 4566 ``!s x:real. x IN interior s ==> x limit_point_of s``, 4567 REPEAT GEN_TAC THEN 4568 SIMP_TAC std_ss [IN_INTERIOR, GSPECIFICATION, SUBSET_DEF, IN_BALL] THEN 4569 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 4570 REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC ``d:real`` THEN 4571 DISCH_TAC THEN 4572 MP_TAC(ISPECL [``x:real``, ``min d e / &2:real``] REAL_CHOOSE_DIST) THEN 4573 KNOW_TAC ``0 <= min d e / 2:real`` THENL 4574 [METIS_TAC [min_def, REAL_LE_LT, REAL_LT_HALF1], ALL_TAC] THEN 4575 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN 4576 EXISTS_TAC ``y:real`` THEN REPEAT CONJ_TAC THENL 4577 [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [] THEN 4578 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d e:real`` THEN 4579 METIS_TAC [REAL_MIN_LE1, min_def, REAL_LT_HALF2], 4580 CONV_TAC (RAND_CONV SYM_CONV) THEN REWRITE_TAC[DIST_NZ] THEN 4581 ASM_REWRITE_TAC [] THEN METIS_TAC [min_def, REAL_LE_LT, REAL_LT_HALF1], 4582 ONCE_REWRITE_TAC[DIST_SYM] THEN ASM_REWRITE_TAC [] THEN 4583 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d e:real`` THEN 4584 METIS_TAC [REAL_MIN_LE1, min_def, REAL_LT_HALF2]]); 4585 4586val INTERIOR_SING = store_thm ("INTERIOR_SING", 4587 ``!a:real. interior {a} = {}``, 4588 REWRITE_TAC[EXTENSION, NOT_IN_EMPTY] THEN 4589 MESON_TAC[INTERIOR_LIMIT_POINT, LIMPT_SING]); 4590 4591val INTERIOR_CLOSED_UNION_EMPTY_INTERIOR = store_thm ("INTERIOR_CLOSED_UNION_EMPTY_INTERIOR", 4592 ``!s t:real->bool. closed(s) /\ (interior(t) = {}) 4593 ==> (interior(s UNION t) = interior(s))``, 4594 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 4595 SIMP_TAC std_ss [SUBSET_INTERIOR, SUBSET_UNION] THEN 4596 REWRITE_TAC[SUBSET_DEF, IN_INTERIOR, IN_INTER, IN_UNION] THEN 4597 X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN 4598 ASM_REWRITE_TAC[] THEN X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 4599 SUBGOAL_THEN ``(y:real) limit_point_of s`` 4600 (fn th => ASM_MESON_TAC[CLOSED_LIMPT, th]) THEN 4601 REWRITE_TAC[IN_INTERIOR, NOT_IN_EMPTY, LIMPT_APPROACHABLE] THEN 4602 X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN 4603 SUBGOAL_THEN 4604 ``?z:real. ~(z IN t) /\ ~(z = y) /\ dist(z,y) < d /\ dist(x,z) < e`` 4605 (fn th => ASM_MESON_TAC[th, IN_BALL]) THEN 4606 UNDISCH_TAC ``y IN ball (x,e)`` THEN REWRITE_TAC [IN_BALL] THEN 4607 DISCH_TAC THEN UNDISCH_TAC ``interior t = {}`` THEN 4608 GEN_REWR_TAC LAND_CONV [EXTENSION] THEN 4609 KNOW_TAC ``(!x e. ~(&0 < e /\ ball (x,e) SUBSET t)) 4610 ==> (?z. ~(z IN t) /\ ~(z = y) /\ dist (z,y) < d /\ dist (x,z) < e)`` THENL 4611 [ALL_TAC, SIMP_TAC std_ss [IN_INTERIOR, NOT_IN_EMPTY, NOT_EXISTS_THM]] THEN 4612 ABBREV_TAC ``k = min d (e - dist(x:real,y))`` THEN 4613 SUBGOAL_THEN ``&0 < k:real`` ASSUME_TAC THENL 4614 [METIS_TAC [min_def, REAL_SUB_LT], ALL_TAC] THEN 4615 SUBGOAL_THEN ``?w:real. dist(y,w) = k / &2`` CHOOSE_TAC THENL 4616 [ASM_SIMP_TAC std_ss [REAL_CHOOSE_DIST, REAL_HALF, REAL_LT_IMP_LE], ALL_TAC] THEN 4617 DISCH_THEN(MP_TAC o SPECL [``w:real``, ``k / &4:real``]) THEN 4618 ASM_SIMP_TAC arith_ss [SUBSET_DEF, NOT_FORALL_THM, REAL_LT_DIV, REAL_LT, 4619 NOT_IMP, IN_BALL] THEN DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN 4620 EXISTS_TAC ``z:real`` THEN POP_ASSUM MP_TAC THEN 4621 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN ASM_REWRITE_TAC[] THEN 4622 DISCH_TAC THEN REPEAT CONJ_TAC THENL 4623 [CCONTR_TAC THEN FULL_SIMP_TAC std_ss [DIST_SYM] THEN 4624 UNDISCH_TAC `` dist (w,y) < k / 4`` THEN ASM_REWRITE_TAC [REAL_NOT_LT, REAL_LE_LT] THEN 4625 DISJ1_TAC THEN KNOW_TAC ``k < k / 2 * 4:real`` THENL 4626 [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN 4627 REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN 4628 SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN 4629 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN 4630 ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN 4631 GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD], 4632 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``dist (z, w) + dist (w, y:real)`` THEN 4633 REWRITE_TAC [DIST_TRIANGLE] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN 4634 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d (e - dist (x,y))`` THEN 4635 ASM_REWRITE_TAC [REAL_MIN_LE1] THEN 4636 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN REWRITE_TAC [REAL_LT_RADD] THEN 4637 MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC ``k / 4:real`` THEN 4638 ASM_REWRITE_TAC [] THEN KNOW_TAC ``k < k / 2 * 4:real`` THENL 4639 [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN 4640 REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN 4641 SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN 4642 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN 4643 ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN 4644 GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD], 4645 Cases_on `d <= (e - dist (x,y))` THENL 4646 [ALL_TAC, FULL_SIMP_TAC std_ss [min_def] THEN 4647 FULL_SIMP_TAC std_ss [REAL_ARITH ``(a - b = c) = (a = c + b:real)``] THEN 4648 ONCE_REWRITE_TAC [REAL_ADD_SYM] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 4649 EXISTS_TAC ``dist (x, y) + dist (y, z:real)`` THEN 4650 REWRITE_TAC [DIST_TRIANGLE, REAL_LT_LADD] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 4651 EXISTS_TAC ``dist (y,w) + dist (w, z:real)`` THEN ASM_REWRITE_TAC [DIST_TRIANGLE] THEN 4652 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN REWRITE_TAC [REAL_LT_LADD] THEN 4653 MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC ``k / 4:real`` THEN 4654 ASM_REWRITE_TAC [] THEN KNOW_TAC ``k < k / 2 * 4:real`` THENL 4655 [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN 4656 REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN 4657 SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN 4658 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN 4659 ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN 4660 GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD]] THEN 4661 FULL_SIMP_TAC std_ss [min_def, REAL_LE_SUB_LADD] THEN 4662 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``d + dist (x,y)`` THEN 4663 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ADD_SYM] THEN 4664 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``dist (x, y) + dist (y, z:real)`` THEN 4665 REWRITE_TAC [DIST_TRIANGLE, REAL_LT_LADD] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 4666 EXISTS_TAC ``dist (y,w) + dist (w, z:real)`` THEN REWRITE_TAC [DIST_TRIANGLE] THEN 4667 ASM_REWRITE_TAC [] THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 4668 ASM_REWRITE_TAC [REAL_LT_LADD] THEN MATCH_MP_TAC REAL_LT_TRANS THEN 4669 EXISTS_TAC ``k / 4:real`` THEN ASM_REWRITE_TAC [] THEN 4670 KNOW_TAC ``k < k / 2 * 4:real`` THENL 4671 [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN 4672 REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN 4673 SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN 4674 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN 4675 ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN 4676 GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD]]); 4677 4678val INTERIOR_UNION_EQ_EMPTY = store_thm ("INTERIOR_UNION_EQ_EMPTY", 4679 ``!s t:real->bool. closed s \/ closed t 4680 ==> ((interior(s UNION t) = {}) <=> 4681 (interior s = {}) /\ (interior t = {}))``, 4682REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THENL 4683[ASM_MESON_TAC[SUBSET_UNION, SUBSET_INTERIOR, SUBSET_EMPTY], 4684 ASM_MESON_TAC[UNION_COMM, INTERIOR_CLOSED_UNION_EMPTY_INTERIOR]]); 4685 4686val INTERIOR_BIGUNION_OPEN_SUBSETS = store_thm ("INTERIOR_UNIONS_OPEN_SUBSETS", 4687 ``!s:real->bool. BIGUNION {t | open t /\ t SUBSET s} = interior s``, 4688 GEN_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN 4689 SIMP_TAC std_ss [OPEN_BIGUNION, GSPECIFICATION] THEN SET_TAC[]); 4690 4691(* ------------------------------------------------------------------------- *) 4692(* More variants of the Archimedian property and useful consequences. *) 4693(* ------------------------------------------------------------------------- *) 4694 4695val REAL_ARCH_INV = store_thm ("REAL_ARCH_INV", 4696 ``!e. &0 < e <=> ?n. ~(n = 0) /\ &0:real < inv(&n) /\ inv(&n) < e:real``, 4697 GEN_TAC THEN EQ_TAC THENL [ALL_TAC, MESON_TAC[REAL_LT_TRANS]] THEN 4698 DISCH_TAC THEN MP_TAC(SPEC ``inv(e:real)`` REAL_BIGNUM) THEN 4699 STRIP_TAC THEN EXISTS_TAC ``n:num`` THEN 4700 ASM_MESON_TAC[REAL_LT_INV, REAL_INV_INV, REAL_LT_INV_EQ, REAL_LT_TRANS, 4701 REAL_LT_ANTISYM]); 4702 4703val REAL_POW_LBOUND = store_thm ("REAL_POW_LBOUND", 4704 ``!x:real n. &0 <= x ==> &1 + &n * x <= (&1 + x) pow n``, 4705 GEN_TAC THEN SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN DISCH_TAC THEN 4706 INDUCT_TAC THEN 4707 REWRITE_TAC[pow, REAL_MUL_LZERO, REAL_ADD_RID, REAL_LE_REFL] THEN 4708 REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN 4709 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``(&1 + x) * (&1 + &n * x:real)`` THEN 4710 ASM_SIMP_TAC std_ss [REAL_LE_LMUL, REAL_ARITH ``&0 <= x:real ==> &0 <= &1 + x``, 4711 REAL_LE_MUL, REAL_LE_LMUL_IMP, REAL_POS, pow, REAL_ARITH 4712 ``&1 + (n + &1) * x:real <= (&1 + x) * (&1 + n * x) <=> &0 <= n * x * x``]); 4713 4714val REAL_ARCH_POW = store_thm ("REAL_ARCH_POW", 4715 ``!x:real y. &1 < x ==> ?n. y < x pow n``, 4716 REPEAT STRIP_TAC THEN 4717 MP_TAC(SPEC ``x:real - &1`` REAL_ARCH) THEN ASM_REWRITE_TAC[REAL_SUB_LT] THEN 4718 DISCH_THEN(MP_TAC o SPEC ``y:real``) THEN STRIP_TAC THEN 4719 EXISTS_TAC ``n:num`` THEN MATCH_MP_TAC REAL_LTE_TRANS THEN 4720 EXISTS_TAC ``&1 + &n * (x:real - &1)`` THEN 4721 ASM_SIMP_TAC std_ss [REAL_ARITH ``x:real < y ==> x < &1 + y``] THEN 4722 ASM_MESON_TAC[REAL_POW_LBOUND, REAL_SUB_ADD2, REAL_ARITH 4723 ``&1 < x:real ==> &0 <= x - &1``]); 4724 4725val REAL_ARCH_POW2 = store_thm ("REAL_ARCH_POW2", 4726 ``!x:real. ?n. x < &2:real pow n``, 4727 SIMP_TAC std_ss [REAL_ARCH_POW, REAL_ARITH ``1 < 2:real``]); 4728 4729val REAL_ARCH_POW_INV = store_thm ("REAL_ARCH_POW_INV", 4730 ``!x:real y. &0 < y /\ x < &1 ==> ?n. x pow n < y``, 4731 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``&0 < x:real`` THENL 4732 [ALL_TAC, ASM_MESON_TAC[POW_1, REAL_LET_TRANS, REAL_NOT_LT]] THEN 4733 SUBGOAL_THEN ``inv(&1) < inv(x:real)`` MP_TAC THENL 4734 [ASM_SIMP_TAC std_ss [REAL_LT_INV], REWRITE_TAC[REAL_INV1]] THEN 4735 DISCH_THEN(MP_TAC o SPEC ``inv(y:real)`` o MATCH_MP REAL_ARCH_POW) THEN 4736 STRIP_TAC THEN EXISTS_TAC ``n:num`` THEN 4737 GEN_REWR_TAC BINOP_CONV [GSYM REAL_INV_INV] THEN 4738 ASM_SIMP_TAC std_ss [GSYM REAL_POW_INV, REAL_LT_INV_EQ, REAL_LT_INV]); 4739 4740val FORALL_POS_MONO = store_thm ("FORALL_POS_MONO", 4741 ``!P. (!d e:real. d < e /\ P d ==> P e) /\ (!n. ~(n = 0) ==> P(inv(&n))) 4742 ==> !e. &0 < e ==> P e``, 4743 MESON_TAC[REAL_ARCH_INV, REAL_LT_TRANS]); 4744 4745val FORALL_SUC = store_thm ("FORALL_SUC", 4746 ``(!n. n <> 0 ==> P n) <=> !n. P (SUC n)``, 4747 EQ_TAC THENL [RW_TAC arith_ss [SUC_NOT, REAL_OF_NUM_EQ], 4748 METIS_TAC [REAL_NZ_IMP_LT, SUC_PRE, REAL_LT, REAL_OF_NUM_EQ]]); 4749 4750val LT_NZ = store_thm ("LT_NZ", 4751 ``!n:num. 0 < n <=> ~(n = 0)``, 4752 INDUCT_TAC THEN ASM_SIMP_TAC std_ss [NOT_SUC, LT, EQ_SYM_EQ] THEN 4753 TAUT_TAC); 4754 4755val REAL_ARCH_RDIV_EQ_0 = store_thm ("REAL_ARCH_RDIV_EQ_0", 4756 ``!x c:real. &0 <= x /\ &0 <= c /\ (!m. 0 < m ==> &m * x <= c) ==> (x = &0)``, 4757 SIMP_TAC std_ss [GSYM REAL_LE_ANTISYM, GSYM REAL_NOT_LT] THEN REPEAT STRIP_TAC THEN 4758 POP_ASSUM (STRIP_ASSUME_TAC o SPEC ``c:real`` o MATCH_MP REAL_ARCH) THEN 4759 ASM_CASES_TAC ``n=0:num`` THENL 4760 [POP_ASSUM SUBST_ALL_TAC THEN 4761 RULE_ASSUM_TAC (REWRITE_RULE [REAL_MUL_LZERO]) THEN 4762 ASM_MESON_TAC [REAL_LET_ANTISYM], 4763 ASM_MESON_TAC [REAL_LET_ANTISYM, REAL_MUL_SYM, LT_NZ]]); 4764 4765(* ------------------------------------------------------------------------- *) 4766(* Closure of a set. *) 4767(* ------------------------------------------------------------------------- *) 4768 4769val closure = new_definition ("closure", 4770 ``closure s = s UNION {x | x limit_point_of s}``); 4771 4772val CLOSURE_APPROACHABLE = store_thm ("CLOSURE_APPROACHABLE", 4773 ``!x s. x IN closure(s) <=> !e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e``, 4774 SIMP_TAC std_ss [closure, LIMPT_APPROACHABLE, IN_UNION, GSPECIFICATION] THEN 4775 MESON_TAC[DIST_REFL]); 4776 4777val CLOSURE_NONEMPTY_OPEN_INTER = store_thm ("CLOSURE_NONEMPTY_OPEN_INTER", 4778 ``!s x:real. x IN closure s <=> !t. x IN t /\ open t ==> ~(s INTER t = {})``, 4779 REPEAT GEN_TAC THEN SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION] THEN 4780 REWRITE_TAC[limit_point_of] THEN SET_TAC[]); 4781 4782val CLOSURE_INTERIOR = store_thm ("CLOSURE_INTERIOR", 4783 ``!s:real->bool. closure s = UNIV DIFF (interior (UNIV DIFF s))``, 4784 SIMP_TAC std_ss [EXTENSION, closure, IN_UNION, IN_DIFF, IN_UNIV, interior, 4785 GSPECIFICATION, limit_point_of, SUBSET_DEF] THEN 4786 MESON_TAC[]); 4787 4788val INTERIOR_CLOSURE = store_thm ("INTERIOR_CLOSURE", 4789 ``!s:real->bool. interior s = UNIV DIFF (closure (UNIV DIFF s))``, 4790 REWRITE_TAC[CLOSURE_INTERIOR, SET_RULE ``!s t. UNIV DIFF (UNIV DIFF t) = t``]); 4791 4792val CLOSED_CLOSURE = store_thm ("CLOSED_CLOSURE", 4793 ``!s. closed(closure s)``, 4794 REWRITE_TAC[closed_def, CLOSURE_INTERIOR, SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``, 4795 OPEN_INTERIOR]); 4796 4797val CLOSURE_HULL = store_thm ("CLOSURE_HULL", 4798 ``!s. closure s = closed hull s``, 4799 GEN_TAC THEN MATCH_MP_TAC(GSYM HULL_UNIQUE) THEN 4800 REWRITE_TAC[CLOSED_CLOSURE, SUBSET_DEF] THEN 4801 SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION, CLOSED_LIMPT] THEN 4802 MESON_TAC[limit_point_of]); 4803 4804val CLOSURE_EQ = store_thm ("CLOSURE_EQ", 4805 ``!s. (closure s = s) <=> closed s``, 4806 SIMP_TAC std_ss [CLOSURE_HULL, HULL_EQ, CLOSED_BIGINTER]); 4807 4808val CLOSURE_CLOSED = store_thm ("CLOSURE_CLOSED", 4809 ``!s. closed s ==> (closure s = s)``, 4810 MESON_TAC[CLOSURE_EQ]); 4811 4812val CLOSURE_CLOSURE = store_thm ("CLOSURE_CLOSURE", 4813 ``!s. closure(closure s) = closure s``, 4814 REWRITE_TAC[CLOSURE_HULL, HULL_HULL]); 4815 4816val CLOSURE_SUBSET = store_thm ("CLOSURE_SUBSET", 4817 ``!s. s SUBSET (closure s)``, 4818 REWRITE_TAC[CLOSURE_HULL, HULL_SUBSET]); 4819 4820val SUBSET_CLOSURE = store_thm ("SUBSET_CLOSURE", 4821 ``!s t. s SUBSET t ==> (closure s) SUBSET (closure t)``, 4822 REWRITE_TAC[CLOSURE_HULL, HULL_MONO]); 4823 4824val CLOSURE_UNION = store_thm ("CLOSURE_UNION", 4825 ``!s t:real->bool. closure(s UNION t) = closure s UNION closure t``, 4826 REWRITE_TAC[LIMIT_POINT_UNION, closure] THEN SET_TAC[]); 4827 4828val CLOSURE_INTER_SUBSET = store_thm ("CLOSURE_INTER_SUBSET", 4829 ``!s t. closure(s INTER t) SUBSET closure(s) INTER closure(t)``, 4830 REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET_INTER] THEN 4831 CONJ_TAC THEN MATCH_MP_TAC SUBSET_CLOSURE THEN SET_TAC[]); 4832 4833val CLOSURE_BIGINTER_SUBSET = store_thm ("CLOSURE_BIGINTER_SUBSET", 4834 ``!f. closure(BIGINTER f) SUBSET BIGINTER (IMAGE closure f)``, 4835 REWRITE_TAC[SET_RULE ``s SUBSET BIGINTER f <=> !t. t IN f ==> s SUBSET t``] THEN 4836 REWRITE_TAC[FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN 4837 MATCH_MP_TAC SUBSET_CLOSURE THEN ASM_SET_TAC[]); 4838 4839val CLOSURE_MINIMAL = store_thm ("CLOSURE_MINIMAL", 4840 ``!s t. s SUBSET t /\ closed t ==> (closure s) SUBSET t``, 4841 REWRITE_TAC[HULL_MINIMAL, CLOSURE_HULL]); 4842 4843val CLOSURE_MINIMAL_EQ = store_thm ("CLOSURE_MINIMAL_EQ", 4844 ``!s t:real->bool. closed t ==> (closure s SUBSET t <=> s SUBSET t)``, 4845 MESON_TAC[SUBSET_TRANS, CLOSURE_SUBSET, CLOSURE_MINIMAL]); 4846 4847val CLOSURE_UNIQUE = store_thm ("CLOSURE_UNIQUE", 4848 ``!s t. s SUBSET t /\ closed t /\ 4849 (!t'. s SUBSET t' /\ closed t' ==> t SUBSET t') 4850 ==> (closure s = t)``, 4851 REWRITE_TAC[CLOSURE_HULL, HULL_UNIQUE]); 4852 4853val CLOSURE_EMPTY = store_thm ("CLOSURE_EMPTY", 4854 ``closure {} = {}``, 4855 SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_EMPTY]); 4856 4857val CLOSURE_UNIV = store_thm ("CLOSURE_UNIV", 4858 ``closure univ(:real) = univ(:real)``, 4859 SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_UNIV]); 4860 4861val CLOSURE_BIGUNION = store_thm ("CLOSURE_BIGUNION", 4862 ``!f. FINITE f ==> (closure(BIGUNION f) = BIGUNION {closure s | s IN f})``, 4863 KNOW_TAC ``!f. (closure(BIGUNION f) = BIGUNION {closure s | s IN f}) = 4864 (\f. closure(BIGUNION f) = BIGUNION {closure s | s IN f}) f`` THENL 4865 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 4866 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 4867 SIMP_TAC std_ss [BIGUNION_EMPTY, BIGUNION_INSERT, SET_RULE ``{f x | x IN {}} = {}``, 4868 SET_RULE ``{f x | x IN a INSERT s} = (f a) INSERT {f x | x IN s}``] THEN 4869 SIMP_TAC std_ss [CLOSURE_EMPTY, CLOSURE_UNION]); 4870 4871val CLOSURE_EQ_EMPTY = store_thm ("CLOSURE_EQ_EMPTY", 4872 ``!s. (closure s = {}) <=> (s = {})``, 4873 GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CLOSURE_EMPTY] THEN 4874 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (t = {}) ==> (s = {})``) THEN 4875 REWRITE_TAC[CLOSURE_SUBSET]); 4876 4877val CLOSURE_SUBSET_EQ = store_thm ("CLOSURE_SUBSET_EQ", 4878 ``!s:real->bool. closure s SUBSET s <=> closed s``, 4879 GEN_TAC THEN REWRITE_TAC[GSYM CLOSURE_EQ] THEN 4880 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN SET_TAC[]); 4881 4882val OPEN_INTER_CLOSURE_EQ_EMPTY = store_thm ("OPEN_INTER_CLOSURE_EQ_EMPTY", 4883 ``!s t:real->bool. 4884 open s ==> ((s INTER (closure t) = {}) <=> (s INTER t = {}))``, 4885 REPEAT STRIP_TAC THEN EQ_TAC THENL 4886 [MP_TAC(ISPEC ``t:real->bool`` CLOSURE_SUBSET) THEN SET_TAC[], ALL_TAC] THEN 4887 DISCH_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN 4888 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (s INTER (UNIV DIFF t) = {})``) THEN 4889 ASM_SIMP_TAC std_ss [OPEN_SUBSET_INTERIOR] THEN 4890 REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]); 4891 4892val CLOSURE_OPEN_IN_INTER_CLOSURE = store_thm ("CLOSURE_OPEN_IN_INTER_CLOSURE", 4893 ``!s t u:real->bool. 4894 open_in (subtopology euclidean u) s /\ t SUBSET u 4895 ==> (closure(s INTER closure t) = closure(s INTER t))``, 4896 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 4897 SIMP_TAC std_ss [CLOSURE_SUBSET, SUBSET_CLOSURE, SET_RULE 4898 ``t SUBSET u ==> s INTER t SUBSET s INTER u``] THEN 4899 REWRITE_TAC[SUBSET_DEF, CLOSURE_APPROACHABLE] THEN 4900 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 4901 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 4902 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 4903 ASM_REWRITE_TAC[REAL_LT_HALF1, IN_INTER, CLOSURE_APPROACHABLE] THEN 4904 DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN 4905 UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN 4906 REWRITE_TAC [open_in] THEN REWRITE_TAC[SUBSET_DEF] THEN 4907 DISCH_THEN(CONJUNCTS_THEN(MP_TAC o SPEC ``y:real``)) THEN 4908 ASM_REWRITE_TAC[] THEN 4909 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN DISCH_TAC THEN 4910 UNDISCH_TAC ``!e. 0 < e ==> ?y'. y' IN t /\ dist (y',y) < e`` THEN 4911 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``min d (e / &2:real)``) THEN 4912 ASM_REWRITE_TAC[REAL_LT_HALF1, REAL_LT_MIN] THEN 4913 DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN 4914 POP_ASSUM MP_TAC THEN 4915 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF]) THEN ASM_SIMP_TAC std_ss [] THEN 4916 STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 4917 EXISTS_TAC ``dist(z,y) + dist(y,x)`` THEN REWRITE_TAC [DIST_TRIANGLE] THEN 4918 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 4919 MATCH_MP_TAC REAL_LT_ADD2 THEN ASM_REWRITE_TAC []); 4920 4921val CLOSURE_OPEN_INTER_CLOSURE = store_thm ("CLOSURE_OPEN_INTER_CLOSURE", 4922 ``!s t:real->bool. 4923 open s ==> (closure(s INTER closure t) = closure(s INTER t))``, 4924 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_OPEN_IN_INTER_CLOSURE THEN 4925 EXISTS_TAC ``univ(:real)`` THEN 4926 ASM_REWRITE_TAC[SUBSET_UNIV, GSYM OPEN_IN, SUBTOPOLOGY_UNIV]); 4927 4928val OPEN_INTER_CLOSURE_SUBSET = store_thm ("OPEN_INTER_CLOSURE_SUBSET", 4929 ``!s t:real->bool. 4930 open s ==> (s INTER (closure t)) SUBSET closure(s INTER t)``, 4931 REPEAT STRIP_TAC THEN 4932 SIMP_TAC std_ss [SUBSET_DEF, IN_INTER, closure, IN_UNION, GSPECIFICATION] THEN 4933 X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 4934 DISJ2_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN 4935 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 4936 UNDISCH_TAC ``open s`` THEN REWRITE_TAC [open_def] THEN 4937 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 4938 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 4939 UNDISCH_TAC ``x limit_point_of t`` THEN REWRITE_TAC [LIMPT_APPROACHABLE] THEN 4940 DISCH_THEN(MP_TAC o SPEC ``min d e:real``) THEN 4941 ASM_REWRITE_TAC[REAL_LT_MIN, IN_INTER] THEN STRIP_TAC THEN 4942 EXISTS_TAC ``x':real`` THEN ASM_MESON_TAC[]); 4943 4944val CLOSURE_OPEN_INTER_SUPERSET = store_thm ("CLOSURE_OPEN_INTER_SUPERSET", 4945 ``!s t:real->bool. 4946 open s /\ s SUBSET closure t ==> (closure(s INTER t) = closure s)``, 4947 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 4948 SIMP_TAC std_ss [SUBSET_CLOSURE, INTER_SUBSET] THEN 4949 MATCH_MP_TAC CLOSURE_MINIMAL THEN REWRITE_TAC[CLOSED_CLOSURE] THEN 4950 W(MP_TAC o PART_MATCH (rand o rand) OPEN_INTER_CLOSURE_SUBSET o rand o snd) THEN 4951 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] SUBSET_TRANS) THEN 4952 ASM_SET_TAC[]); 4953 4954val CLOSURE_COMPLEMENT = store_thm ("CLOSURE_COMPLEMENT", 4955 ``!s:real->bool. closure(UNIV DIFF s) = UNIV DIFF interior(s)``, 4956 REWRITE_TAC[SET_RULE ``(s = UNIV DIFF t) <=> (UNIV DIFF s = t)``] THEN 4957 REWRITE_TAC[GSYM INTERIOR_CLOSURE]); 4958 4959val INTERIOR_COMPLEMENT = store_thm ("INTERIOR_COMPLEMENT", 4960 ``!s:real->bool. interior(UNIV DIFF s) = UNIV DIFF closure(s)``, 4961 REWRITE_TAC[SET_RULE ``(s = UNIV DIFF t) <=> (UNIV DIFF s = t)``] THEN 4962 REWRITE_TAC[GSYM CLOSURE_INTERIOR]); 4963 4964val CONNECTED_INTERMEDIATE_CLOSURE = store_thm ("CONNECTED_INTERMEDIATE_CLOSURE", 4965 ``!s t:real->bool. 4966 connected s /\ s SUBSET t /\ t SUBSET closure s ==> connected t``, 4967 REPEAT GEN_TAC THEN 4968 KNOW_TAC ``(!e1 e2. 4969 ~(open e1 /\ open e2 /\ 4970 s SUBSET e1 UNION e2 /\ (e1 INTER e2 INTER s = {}) /\ 4971 ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))) /\ 4972 s SUBSET t /\ t SUBSET closure s 4973 ==> (!e1 e2. 4974 ~(open e1 /\ open e2 /\ 4975 t SUBSET e1 UNION e2 /\ (e1 INTER e2 INTER t = {}) /\ 4976 ~(e1 INTER t = {}) /\ ~(e2 INTER t = {})))`` THENL 4977 [ALL_TAC, SIMP_TAC std_ss [connected, NOT_EXISTS_THM]] THEN 4978 STRIP_TAC THEN MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 4979 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL [``u:real->bool``, ``v:real->bool``]) THEN 4980 ASM_REWRITE_TAC[] THEN ASSUME_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN 4981 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 4982 REWRITE_TAC[GSYM DE_MORGAN_THM] THEN STRIP_TAC THENL 4983 [SUBGOAL_THEN ``(closure s) SUBSET (univ(:real) DIFF u)`` MP_TAC THENL 4984 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED], ALL_TAC], 4985 SUBGOAL_THEN ``(closure s) SUBSET (univ(:real) DIFF v)`` MP_TAC THENL 4986 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED], 4987 ALL_TAC]] THEN ASM_SET_TAC[]); 4988 4989val CONNECTED_CLOSURE = store_thm ("CONNECTED_CLOSURE", 4990 ``!s:real->bool. connected s ==> connected(closure s)``, 4991 MESON_TAC[CONNECTED_INTERMEDIATE_CLOSURE, CLOSURE_SUBSET, SUBSET_REFL]); 4992 4993val CONNECTED_UNION_STRONG = store_thm ("CONNECTED_UNION_STRONG", 4994 ``!s t:real->bool. 4995 connected s /\ connected t /\ ~(closure s INTER t = {}) 4996 ==> connected(s UNION t)``, 4997 REPEAT STRIP_TAC THEN 4998 POP_ASSUM (MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 4999 DISCH_THEN(X_CHOOSE_TAC ``p:real``) THEN 5000 SUBGOAL_THEN ``s UNION t = ((p:real) INSERT s) UNION t`` SUBST1_TAC THENL 5001 [ASM_SET_TAC[], ALL_TAC] THEN 5002 MATCH_MP_TAC CONNECTED_UNION THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL 5003 [MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN 5004 EXISTS_TAC ``s:real->bool`` THEN ASM_REWRITE_TAC[] THEN 5005 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[], 5006 ASM_SET_TAC[]]); 5007 5008val INTERIOR_DIFF = store_thm ("INTERIOR_DIFF", 5009 ``!s t. interior(s DIFF t) = interior(s) DIFF closure(t)``, 5010 ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN 5011 REWRITE_TAC[INTERIOR_INTER, CLOSURE_INTERIOR] THEN SET_TAC[]); 5012 5013val LIMPT_OF_CLOSURE = store_thm ("LIMPT_OF_CLOSURE", 5014 ``!x:real s. x limit_point_of closure s <=> x limit_point_of s``, 5015 SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION, LIMIT_POINT_UNION] THEN 5016 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT `(q ==> p) ==> (p \/ q <=> p)`) THEN 5017 REWRITE_TAC[LIMPT_OF_LIMPTS]); 5018 5019val CLOSED_IN_LIMPT = store_thm ("CLOSED_IN_LIMPT", 5020 ``!s t. closed_in (subtopology euclidean t) s <=> 5021 s SUBSET t /\ !x:real. x limit_point_of s /\ x IN t ==> x IN s``, 5022 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN EQ_TAC THENL 5023 [DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 5024 ASM_SIMP_TAC std_ss [IN_INTER] THEN 5025 ASM_MESON_TAC[CLOSED_LIMPT, LIMPT_SUBSET, INTER_SUBSET], 5026 STRIP_TAC THEN EXISTS_TAC ``closure s :real->bool`` THEN 5027 REWRITE_TAC[CLOSED_CLOSURE] THEN REWRITE_TAC[closure] THEN 5028 ASM_SET_TAC[]]); 5029 5030val CLOSED_IN_INTER_CLOSURE = store_thm ("CLOSED_IN_INTER_CLOSURE", 5031 ``!s t:real->bool. 5032 closed_in (subtopology euclidean s) t <=> (s INTER closure t = t)``, 5033 REWRITE_TAC[closure, CLOSED_IN_LIMPT] THEN SET_TAC[]); 5034 5035val INTERIOR_CLOSURE_IDEMP = store_thm ("INTERIOR_CLOSURE_IDEMP", 5036 ``!s:real->bool. 5037 interior(closure(interior(closure s))) = interior(closure s)``, 5038 GEN_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN 5039 ASM_MESON_TAC[OPEN_INTERIOR, CLOSURE_SUBSET, CLOSURE_CLOSURE, SUBSET_TRANS, 5040 OPEN_SUBSET_INTERIOR, SUBSET_CLOSURE, INTERIOR_SUBSET]); 5041 5042val CLOSURE_INTERIOR_IDEMP = store_thm ("CLOSURE_INTERIOR_IDEMP", 5043 ``!s:real->bool. 5044 closure(interior(closure(interior s))) = closure(interior s)``, 5045 GEN_TAC THEN 5046 ONCE_REWRITE_TAC[SET_RULE ``(s = t) <=> (UNIV DIFF s = UNIV DIFF t)``] THEN 5047 REWRITE_TAC[GSYM INTERIOR_COMPLEMENT, GSYM CLOSURE_COMPLEMENT] THEN 5048 REWRITE_TAC[INTERIOR_CLOSURE_IDEMP]); 5049 5050val NOWHERE_DENSE_UNION = store_thm ("NOWHERE_DENSE_UNION", 5051 ``!s t:real->bool. 5052 (interior(closure(s UNION t)) = {}) <=> 5053 (interior(closure s) = {}) /\ (interior(closure t) = {})``, 5054 SIMP_TAC std_ss [CLOSURE_UNION, INTERIOR_UNION_EQ_EMPTY, CLOSED_CLOSURE]); 5055 5056val NOWHERE_DENSE = store_thm ("NOWHERE_DENSE", 5057 ``!s:real->bool. (interior(closure s) = {}) <=> 5058 !t. open t /\ ~(t = {}) 5059 ==> ?u. open u /\ ~(u = {}) /\ u SUBSET t /\ (u INTER s = {})``, 5060 GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY_ALT] THEN EQ_TAC THEN 5061 DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN STRIP_TAC THENL 5062 [EXISTS_TAC ``t DIFF closure s:real->bool`` THEN 5063 ASM_SIMP_TAC std_ss [OPEN_DIFF, CLOSED_CLOSURE] THEN 5064 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN SET_TAC[], 5065 FIRST_X_ASSUM(MP_TAC o SPEC ``t:real->bool``) THEN ASM_REWRITE_TAC[] THEN 5066 DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 5067 MP_TAC(ISPECL [``u:real->bool``, ``s:real->bool``] 5068 OPEN_INTER_CLOSURE_EQ_EMPTY) THEN ASM_SET_TAC[]]); 5069 5070val INTERIOR_CLOSURE_INTER_OPEN = store_thm ("INTERIOR_CLOSURE_INTER_OPEN", 5071 ``!s t:real->bool. open s /\ open t 5072 ==> (interior(closure(s INTER t)) = 5073 interior(closure s) INTER interior(closure t))``, 5074 REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE 5075 ``(u = s INTER t) <=> s INTER t SUBSET u /\ u SUBSET s /\ u SUBSET t``] THEN 5076 SIMP_TAC std_ss [SUBSET_INTERIOR, SUBSET_CLOSURE, INTER_SUBSET] THEN 5077 MATCH_MP_TAC INTERIOR_MAXIMAL THEN SIMP_TAC std_ss [OPEN_INTER, OPEN_INTERIOR] THEN 5078 REWRITE_TAC[SET_RULE ``s SUBSET t <=> (s INTER (UNIV DIFF t) = {})``, 5079 GSYM INTERIOR_COMPLEMENT] THEN 5080 REWRITE_TAC[GSYM INTERIOR_INTER] THEN 5081 REWRITE_TAC[INTERIOR_EQ_EMPTY] THEN 5082 X_GEN_TAC ``u:real->bool`` THEN STRIP_TAC THEN 5083 MP_TAC(ISPECL [``u INTER s:real->bool``, ``t:real->bool``] 5084 OPEN_INTER_CLOSURE_EQ_EMPTY) THEN 5085 MP_TAC(ISPECL [``u:real->bool``, ``s:real->bool``] 5086 OPEN_INTER_CLOSURE_EQ_EMPTY) THEN 5087 ASM_SIMP_TAC std_ss [OPEN_INTER] THEN ASM_SET_TAC[]); 5088 5089val CLOSURE_INTERIOR_UNION_CLOSED = store_thm ("CLOSURE_INTERIOR_UNION_CLOSED", 5090 ``!s t:real->bool. closed s /\ closed t 5091 ==> (closure (interior (s UNION t)) = 5092 closure (interior s) UNION closure(interior t))``, 5093 REPEAT GEN_TAC THEN REWRITE_TAC[closed_def] THEN 5094 DISCH_THEN(MP_TAC o MATCH_MP INTERIOR_CLOSURE_INTER_OPEN) THEN 5095 REWRITE_TAC[CLOSURE_COMPLEMENT, INTERIOR_COMPLEMENT, 5096 SET_RULE ``(UNIV DIFF s) INTER (UNIV DIFF t) = UNIV DIFF (s UNION t)``] THEN 5097 SET_TAC[]); 5098 5099val REGULAR_OPEN_INTER = store_thm ("REGULAR_OPEN_INTER", 5100 ``!s t:real->bool. 5101 (interior(closure s) = s) /\ (interior(closure t) = t) 5102 ==> (interior(closure(s INTER t)) = s INTER t)``, 5103 MESON_TAC[INTERIOR_CLOSURE_INTER_OPEN, OPEN_INTERIOR]); 5104 5105val REGULAR_CLOSED_UNION = store_thm ("REGULAR_CLOSED_UNION", 5106 ``!s t:real->bool. 5107 (closure(interior s) = s) /\ (closure(interior t) = t) 5108 ==> (closure(interior(s UNION t)) = s UNION t)``, 5109 MESON_TAC[CLOSURE_INTERIOR_UNION_CLOSED, CLOSED_CLOSURE]); 5110 5111val REGULAR_CLOSED_BIGUNION = store_thm ("REGULAR_CLOSED_BIGUNION", 5112 ``!f:(real->bool)->bool. 5113 FINITE f /\ (!t. t IN f ==> (closure(interior t) = t)) 5114 ==> (closure(interior(BIGUNION f)) = BIGUNION f)``, 5115 REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 5116 KNOW_TAC ``!f. ((!t. t IN f ==> (closure(interior t) = t)) 5117 ==> (closure(interior(BIGUNION f)) = BIGUNION f)) = 5118 (\f. (!t. t IN f ==> (closure(interior t) = t)) 5119 ==> (closure(interior(BIGUNION f)) = BIGUNION f)) f`` THENL 5120 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 5121 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 5122 REWRITE_TAC[BIGUNION_INSERT, BIGUNION_EMPTY, INTERIOR_EMPTY, CLOSURE_EMPTY] THEN 5123 SIMP_TAC std_ss [FORALL_IN_INSERT, REGULAR_CLOSED_UNION]); 5124 5125val DIFF_CLOSURE_SUBSET = store_thm ("DIFF_CLOSURE_SUBSET", 5126 ``!s t:real->bool. closure(s) DIFF closure t SUBSET closure(s DIFF t)``, 5127 REPEAT GEN_TAC THEN 5128 MP_TAC(ISPECL [``univ(:real) DIFF closure t``, ``s:real->bool``] 5129 OPEN_INTER_CLOSURE_SUBSET) THEN 5130 REWRITE_TAC[SET_RULE ``(UNIV DIFF t) INTER s = s DIFF t``] THEN 5131 REWRITE_TAC[GSYM closed_def, CLOSED_CLOSURE] THEN 5132 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS) THEN 5133 MATCH_MP_TAC SUBSET_CLOSURE THEN 5134 MATCH_MP_TAC(SET_RULE ``t SUBSET u ==> s DIFF u SUBSET s DIFF t``) THEN 5135 REWRITE_TAC[CLOSURE_SUBSET]); 5136 5137val DENSE_OPEN_INTER = store_thm ("DENSE_OPEN_INTER", 5138 ``!s t u:real->bool. 5139 (open_in (subtopology euclidean u) s /\ t SUBSET u \/ 5140 open_in (subtopology euclidean u) t /\ s SUBSET u) 5141 ==> (u SUBSET closure (s INTER t) <=> 5142 u SUBSET closure s /\ u SUBSET closure t)``, 5143 KNOW_TAC ``((!s t u. 5144 (u SUBSET closure (s INTER t) <=> 5145 u SUBSET closure s /\ u SUBSET closure t) 5146 ==> (u SUBSET closure (t INTER s) <=> 5147 u SUBSET closure t /\ u SUBSET closure s)) /\ 5148 (!s t u. 5149 open_in (subtopology euclidean u) s /\ t SUBSET u 5150 ==> (u SUBSET closure (s INTER t) <=> 5151 u SUBSET closure s /\ u SUBSET closure t)))`` THENL 5152 [ALL_TAC, METIS_TAC []] THEN CONJ_TAC THENL 5153 [SIMP_TAC std_ss [INTER_COMM, CONJ_ACI], ALL_TAC] THEN 5154 REPEAT GEN_TAC THEN STRIP_TAC THEN EQ_TAC THENL 5155 [ASM_MESON_TAC[SUBSET_TRANS, SUBSET_CLOSURE, INTER_SUBSET], ALL_TAC] THEN 5156 REWRITE_TAC[SUBSET_DEF, CLOSURE_APPROACHABLE] THEN DISCH_TAC THEN 5157 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 5158 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 5159 FIRST_X_ASSUM(CONJUNCTS_THEN2 (MP_TAC o SPEC ``x:real``) ASSUME_TAC) THEN 5160 ASM_REWRITE_TAC[] THEN 5161 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN 5162 DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN 5163 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN 5164 UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN REWRITE_TAC [open_in] THEN 5165 REWRITE_TAC[SUBSET_DEF, IN_INTER] THEN 5166 DISCH_THEN(CONJUNCTS_THEN (MP_TAC o SPEC ``y:real``)) THEN 5167 ASM_REWRITE_TAC[] THEN 5168 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN DISCH_TAC THEN 5169 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min d (e / &2):real``) THEN 5170 ASM_REWRITE_TAC[REAL_HALF, REAL_LT_MIN] THEN 5171 DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN 5172 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF]) THEN ASM_SIMP_TAC std_ss [] THEN 5173 POP_ASSUM MP_TAC THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 5174 EXISTS_TAC ``dist(z,y) + dist(y,x)`` THEN REWRITE_TAC [DIST_TRIANGLE] THEN 5175 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 5176 MATCH_MP_TAC REAL_LT_ADD2 THEN ASM_REWRITE_TAC []); 5177 5178(* ------------------------------------------------------------------------- *) 5179(* Frontier (aka boundary). *) 5180(* ------------------------------------------------------------------------- *) 5181 5182val frontier = new_definition ("frontier", 5183 ``frontier s = (closure s) DIFF (interior s)``); 5184 5185val FRONTIER_CLOSED = store_thm ("FRONTIER_CLOSED", 5186 ``!s. closed(frontier s)``, 5187 SIMP_TAC std_ss [frontier, CLOSED_DIFF, CLOSED_CLOSURE, OPEN_INTERIOR]); 5188 5189val FRONTIER_CLOSURES = store_thm ("FRONTIER_CLOSURES", 5190 ``!s:real->bool. frontier s = (closure s) INTER (closure(UNIV DIFF s))``, 5191 REWRITE_TAC[frontier, INTERIOR_CLOSURE, 5192 SET_RULE ``s DIFF (UNIV DIFF t) = s INTER t``]); 5193 5194val FRONTIER_STRADDLE = store_thm ("FRONTIER_STRADDLE", 5195 ``!a:real s. 5196 a IN frontier s <=> !e. &0 < e ==> (?x. x IN s /\ dist(a,x) < e) /\ 5197 (?x. ~(x IN s) /\ dist(a,x) < e)``, 5198 REPEAT GEN_TAC THEN REWRITE_TAC[FRONTIER_CLOSURES, IN_INTER] THEN 5199 SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION, limit_point_of, 5200 IN_UNIV, IN_DIFF] THEN 5201 ASM_MESON_TAC[IN_BALL, SUBSET_DEF, OPEN_CONTAINS_BALL, 5202 CENTRE_IN_BALL, OPEN_BALL, DIST_REFL]); 5203 5204val FRONTIER_SUBSET_CLOSED = store_thm ("FRONTIER_SUBSET_CLOSED", 5205 ``!s. closed s ==> (frontier s) SUBSET s``, 5206 METIS_TAC[frontier, CLOSURE_CLOSED, DIFF_SUBSET]); 5207 5208val FRONTIER_EMPTY = store_thm ("FRONTIER_EMPTY", 5209 ``frontier {} = {}``, 5210 REWRITE_TAC[frontier, CLOSURE_EMPTY, EMPTY_DIFF]); 5211 5212val FRONTIER_UNIV = store_thm ("FRONTIER_UNIV", 5213 ``frontier univ(:real) = {}``, 5214 REWRITE_TAC[frontier, CLOSURE_UNIV, INTERIOR_UNIV] THEN SET_TAC[]); 5215 5216val FRONTIER_SUBSET_EQ = store_thm ("FRONTIER_SUBSET_EQ", 5217 ``!s:real->bool. (frontier s) SUBSET s <=> closed s``, 5218 GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [FRONTIER_SUBSET_CLOSED] THEN 5219 REWRITE_TAC[frontier] THEN 5220 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE 5221 ``s DIFF t SUBSET u ==> t SUBSET u ==> s SUBSET u``)) THEN 5222 REWRITE_TAC[INTERIOR_SUBSET, CLOSURE_SUBSET_EQ]); 5223 5224val FRONTIER_COMPLEMENT = store_thm ("FRONTIER_COMPLEMENT", 5225 ``!s:real->bool. frontier(UNIV DIFF s) = frontier s``, 5226 REWRITE_TAC[frontier, CLOSURE_COMPLEMENT, INTERIOR_COMPLEMENT] THEN 5227 SET_TAC[]); 5228 5229val FRONTIER_DISJOINT_EQ = store_thm ("FRONTIER_DISJOINT_EQ", 5230 ``!s. ((frontier s) INTER s = {}) <=> open s``, 5231 ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT, OPEN_CLOSED] THEN 5232 REWRITE_TAC[GSYM FRONTIER_SUBSET_EQ] THEN SET_TAC[]); 5233 5234val FRONTIER_INTER_SUBSET = store_thm ("FRONTIER_INTER_SUBSET", 5235 ``!s t. frontier(s INTER t) SUBSET frontier(s) UNION frontier(t)``, 5236 REPEAT GEN_TAC THEN REWRITE_TAC[frontier, INTERIOR_INTER] THEN 5237 MATCH_MP_TAC(SET_RULE ``cst SUBSET cs INTER ct 5238 ==> cst DIFF (s INTER t) SUBSET (cs DIFF s) UNION (ct DIFF t)``) THEN 5239 REWRITE_TAC[CLOSURE_INTER_SUBSET]); 5240 5241val FRONTIER_UNION_SUBSET = store_thm ("FRONTIER_UNION_SUBSET", 5242 ``!s t:real->bool. frontier(s UNION t) SUBSET frontier s UNION frontier t``, 5243 ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN 5244 REWRITE_TAC[SET_RULE ``u DIFF (s UNION t) = (u DIFF s) INTER (u DIFF t)``] THEN 5245 REWRITE_TAC[FRONTIER_INTER_SUBSET]); 5246 5247val FRONTIER_INTERIORS = store_thm ("FRONTIER_INTERIORS", 5248 ``!s. frontier s = univ(:real) DIFF interior(s) DIFF interior(univ(:real) DIFF s)``, 5249 REWRITE_TAC[frontier, CLOSURE_INTERIOR] THEN SET_TAC[]); 5250 5251val FRONTIER_FRONTIER_SUBSET = store_thm ("FRONTIER_FRONTIER_SUBSET", 5252 ``!s:real->bool. frontier(frontier s) SUBSET frontier s``, 5253 GEN_TAC THEN GEN_REWR_TAC LAND_CONV [frontier] THEN 5254 SIMP_TAC std_ss [CLOSURE_CLOSED, FRONTIER_CLOSED] THEN SET_TAC[]); 5255 5256val INTERIOR_FRONTIER = store_thm ("INTERIOR_FRONTIER", 5257 ``!s:real->bool. 5258 interior(frontier s) = interior(closure s) DIFF closure(interior s)``, 5259 ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN 5260 REWRITE_TAC[GSYM INTERIOR_COMPLEMENT, GSYM INTERIOR_INTER, frontier] THEN 5261 GEN_TAC THEN AP_TERM_TAC THEN SET_TAC[]); 5262 5263val INTERIOR_FRONTIER_EMPTY = store_thm ("INTERIOR_FRONTIER_EMPTY", 5264 ``!s:real->bool. open s \/ closed s ==> (interior(frontier s) = {})``, 5265 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[INTERIOR_FRONTIER] THEN 5266 ASM_SIMP_TAC std_ss [CLOSURE_CLOSED, INTERIOR_OPEN] THEN 5267 REWRITE_TAC[SET_RULE ``(s DIFF t = {}) <=> s SUBSET t``] THEN 5268 REWRITE_TAC[INTERIOR_SUBSET, CLOSURE_SUBSET]); 5269 5270val FRONTIER_FRONTIER = store_thm ("FRONTIER_FRONTIER", 5271 ``!s:real->bool. open s \/ closed s ==> (frontier(frontier s) = frontier s)``, 5272 GEN_TAC THEN GEN_REWR_TAC (RAND_CONV o LAND_CONV) [frontier] THEN STRIP_TAC THEN 5273 ASM_SIMP_TAC std_ss [INTERIOR_FRONTIER_EMPTY, CLOSURE_CLOSED, FRONTIER_CLOSED] THEN 5274 REWRITE_TAC[DIFF_EMPTY]); 5275 5276val FRONTIER_FRONTIER_FRONTIER = store_thm ("FRONTIER_FRONTIER_FRONTIER", 5277 ``!s:real->bool. frontier(frontier(frontier s)) = frontier(frontier s)``, 5278 SIMP_TAC std_ss [FRONTIER_FRONTIER, FRONTIER_CLOSED]); 5279 5280val lemma = prove ( 5281 ``!s t x. x IN frontier s /\ x IN interior t ==> x IN frontier(s INTER t)``, 5282 REWRITE_TAC[FRONTIER_STRADDLE, IN_INTER, IN_INTERIOR, SUBSET_DEF, IN_BALL] THEN 5283 REPEAT GEN_TAC THEN 5284 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_TAC ``d:real``)) THEN 5285 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 5286 FIRST_X_ASSUM(MP_TAC o SPEC ``min d e:real``) THEN 5287 ASM_REWRITE_TAC[REAL_LT_MIN] THEN ASM_MESON_TAC[]); 5288 5289val UNION_FRONTIER = store_thm ("UNION_FRONTIER", 5290 ``!s t:real->bool. frontier(s) UNION frontier(t) = 5291 frontier(s UNION t) UNION frontier(s INTER t) UNION 5292 frontier(s) INTER frontier(t)``, 5293 REWRITE_TAC[SET_EQ_SUBSET, UNION_SUBSET, 5294 FRONTIER_UNION_SUBSET, FRONTIER_INTER_SUBSET, 5295 SET_RULE ``s INTER t SUBSET s UNION t``] THEN 5296 REWRITE_TAC[GSYM UNION_SUBSET] THEN REWRITE_TAC[SUBSET_DEF, IN_UNION] THEN 5297 KNOW_TAC ``((!s t x. x IN frontier s 5298 ==> x IN frontier (s UNION t) \/ 5299 x IN frontier (s INTER t) \/ 5300 x IN frontier s INTER frontier t) /\ 5301 (!s t x. 5302 x IN frontier (s UNION t) \/ 5303 x IN frontier (s INTER t) \/ 5304 x IN frontier s INTER frontier t <=> 5305 x IN frontier (t UNION s) \/ 5306 x IN frontier (t INTER s) \/ 5307 x IN frontier t INTER frontier s))`` THENL 5308 [ALL_TAC, METIS_TAC []] THEN CONJ_TAC THENL 5309 [REPEAT STRIP_TAC, SIMP_TAC std_ss [UNION_COMM, INTER_COMM]] THEN 5310 ASM_CASES_TAC ``(x:real) IN frontier t`` THEN ASM_REWRITE_TAC[IN_INTER] THEN 5311 POP_ASSUM MP_TAC THEN GEN_REWR_TAC (LAND_CONV o RAND_CONV o RAND_CONV) 5312 [FRONTIER_INTERIORS] THEN 5313 REWRITE_TAC[DE_MORGAN_THM, IN_DIFF, IN_UNIV] THEN 5314 GEN_REWR_TAC RAND_CONV [DISJ_SYM] THEN MATCH_MP_TAC MONO_OR THEN 5315 ASM_SIMP_TAC std_ss [lemma] THEN 5316 POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN 5317 SIMP_TAC std_ss [lemma, SET_RULE 5318 ``UNIV DIFF (s UNION t) = (UNIV DIFF s) INTER (UNIV DIFF t)``]); 5319 5320val CONNECTED_INTER_FRONTIER = store_thm ("CONNECTED_INTER_FRONTIER", 5321 ``!s t:real->bool. 5322 connected s /\ ~(s INTER t = {}) /\ ~(s DIFF t = {}) 5323 ==> ~(s INTER frontier t = {})``, 5324 REWRITE_TAC[FRONTIER_INTERIORS] THEN REPEAT STRIP_TAC THEN 5325 UNDISCH_TAC ``connected s`` THEN REWRITE_TAC [CONNECTED_OPEN_IN] THEN 5326 MAP_EVERY EXISTS_TAC 5327 [``s INTER interior t:real->bool``, 5328 ``s INTER (interior(univ(:real) DIFF t))``] THEN 5329 SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_INTERIOR] THEN 5330 MAP_EVERY (MP_TAC o C ISPEC INTERIOR_SUBSET) 5331 [``t:real->bool``, ``univ(:real) DIFF t``] THEN 5332 ASM_SET_TAC[]); 5333 5334val INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER = store_thm ("INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER", 5335 ``!s:real->bool. closed s /\ (interior s = {}) <=> 5336 ?t. open t /\ (s = frontier t)``, 5337 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL 5338 [EXISTS_TAC ``univ(:real) DIFF s`` THEN 5339 ASM_SIMP_TAC std_ss [OPEN_DIFF, OPEN_UNIV, FRONTIER_COMPLEMENT] THEN 5340 ASM_SIMP_TAC std_ss [frontier, CLOSURE_CLOSED, DIFF_EMPTY], 5341 ASM_SIMP_TAC std_ss [FRONTIER_CLOSED, INTERIOR_FRONTIER_EMPTY]]); 5342 5343val FRONTIER_UNION = store_thm ("FRONTIER_UNION", 5344 ``!s t:real->bool. (closure s INTER closure t = {}) 5345 ==> (frontier(s UNION t) = frontier(s) UNION frontier(t))``, 5346 REPEAT STRIP_TAC THEN 5347 MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[FRONTIER_UNION_SUBSET] THEN 5348 GEN_REWR_TAC RAND_CONV [frontier] THEN 5349 REWRITE_TAC[CLOSURE_UNION] THEN MATCH_MP_TAC(SET_RULE 5350 ``(fs SUBSET cs /\ ft SUBSET ct) /\ (k INTER fs = {}) /\ (k INTER ft = {}) 5351 ==> (fs UNION ft) SUBSET (cs UNION ct) DIFF k``) THEN 5352 CONJ_TAC THENL [REWRITE_TAC[frontier] THEN SET_TAC[], ALL_TAC] THEN 5353 CONJ_TAC THENL [ALL_TAC, 5354 ONCE_REWRITE_TAC[UNION_COMM] THEN 5355 RULE_ASSUM_TAC(ONCE_REWRITE_RULE[INTER_COMM])] THEN 5356 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE 5357 ``(s INTER t = {}) ==> s' SUBSET s /\ (s' INTER u INTER (UNIV DIFF t) = {}) 5358 ==> (u INTER s' = {})``)) THEN 5359 REWRITE_TAC[frontier, DIFF_SUBSET, GSYM INTERIOR_COMPLEMENT] THENL 5360 [KNOW_TAC ``(closure s DIFF interior s) INTER 5361 interior (s UNION t) INTER 5362 interior (univ(:real) DIFF t) = 5363 (closure s DIFF interior s) INTER 5364 interior ((s UNION t) INTER (univ(:real) DIFF t))`` THENL 5365 [METIS_TAC [INTERIOR_INTER, INTER_ASSOC], ALL_TAC] THEN DISC_RW_KILL, 5366 KNOW_TAC ``(closure t DIFF interior t) INTER 5367 interior (t UNION s) INTER 5368 interior (univ(:real) DIFF s) = 5369 (closure t DIFF interior t) INTER 5370 interior ((t UNION s) INTER (univ(:real) DIFF s))`` THENL 5371 [METIS_TAC [INTERIOR_INTER, INTER_ASSOC], ALL_TAC] THEN DISC_RW_KILL] THEN 5372 REWRITE_TAC[SET_RULE ``(s UNION t) INTER (UNIV DIFF t) = s DIFF t``] THEN 5373 MATCH_MP_TAC(SET_RULE 5374 ``ti SUBSET si ==> ((c DIFF si) INTER ti = {})``) THEN 5375 SIMP_TAC std_ss [SUBSET_INTERIOR, DIFF_SUBSET]); 5376 5377val CLOSURE_UNION_FRONTIER = store_thm ("CLOSURE_UNION_FRONTIER", 5378 ``!s:real->bool. closure s = s UNION frontier s``, 5379 GEN_TAC THEN REWRITE_TAC[frontier] THEN 5380 MP_TAC(ISPEC ``s:real->bool`` INTERIOR_SUBSET) THEN 5381 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN 5382 SET_TAC[]); 5383 5384val FRONTIER_INTERIOR_SUBSET = store_thm ("FRONTIER_INTERIOR_SUBSET", 5385 ``!s:real->bool. frontier(interior s) SUBSET frontier s``, 5386 GEN_TAC THEN REWRITE_TAC[frontier, INTERIOR_INTERIOR] THEN 5387 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> s DIFF u SUBSET t DIFF u``) THEN 5388 SIMP_TAC std_ss [SUBSET_CLOSURE, INTERIOR_SUBSET]); 5389 5390val FRONTIER_CLOSURE_SUBSET = store_thm ("FRONTIER_CLOSURE_SUBSET", 5391 ``!s:real->bool. frontier(closure s) SUBSET frontier s``, 5392 GEN_TAC THEN REWRITE_TAC[frontier, CLOSURE_CLOSURE] THEN 5393 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> u DIFF t SUBSET u DIFF s``) THEN 5394 SIMP_TAC std_ss [SUBSET_INTERIOR, CLOSURE_SUBSET]); 5395 5396val SET_DIFF_FRONTIER = store_thm ("SET_DIFF_FRONTIER", 5397 ``!s:real->bool. s DIFF frontier s = interior s``, 5398 GEN_TAC THEN REWRITE_TAC[frontier] THEN 5399 MP_TAC(ISPEC ``s:real->bool`` INTERIOR_SUBSET) THEN 5400 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN 5401 SET_TAC[]); 5402 5403val FRONTIER_INTER_SUBSET_INTER = store_thm ("FRONTIER_INTER_SUBSET_INTER", 5404 ``!s t:real->bool. 5405 frontier(s INTER t) SUBSET closure s INTER frontier t UNION 5406 frontier s INTER closure t``, 5407 REPEAT GEN_TAC THEN REWRITE_TAC[frontier, INTERIOR_INTER] THEN 5408 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] 5409 CLOSURE_INTER_SUBSET) THEN SET_TAC[]); 5410 5411(* ------------------------------------------------------------------------- *) 5412(* A variant of nets (slightly non-standard but good for our purposes). *) 5413(* ------------------------------------------------------------------------- *) 5414 5415val isnet = new_definition("isnet", 5416 ``!g. isnet g = !x y. (!z. g z x ==> g z y) \/ 5417 (!z. g z y ==> g z x)``); 5418 5419val net_tydef = new_type_definition 5420 ("net", 5421 prove (``?(g:'a->'a->bool). isnet g``, 5422 EXISTS_TAC ``\x:'a y:'a. F`` THEN REWRITE_TAC[isnet])); 5423 5424val net_ty_bij = define_new_type_bijections 5425 {name="net_tybij", 5426 ABS="mk_net", REP="netord",tyax=net_tydef}; 5427 5428val net_tybij = store_thm ("net_tybij", 5429 ``(!a. mk_net (netord a) = a) /\ 5430 (!r. (!x y. (!z. r z x ==> r z y) \/ (!z. r z y ==> r z x)) <=> 5431 (netord (mk_net r) = r))``, 5432 SIMP_TAC std_ss [net_ty_bij, GSYM isnet]); 5433 5434val NET = store_thm ("NET", 5435 ``!n x y. (!z. netord n z x ==> netord n z y) \/ 5436 (!z. netord n z y ==> netord n z x)``, 5437 REWRITE_TAC[net_tybij, ETA_AX]); 5438 5439val OLDNET = store_thm ("OLDNET", 5440 ``!n x y. netord n x x /\ netord n y y 5441 ==> ?z. netord n z z /\ 5442 !w. netord n w z ==> netord n w x /\ netord n w y``, 5443 MESON_TAC[NET]); 5444 5445val NET_DILEMMA = store_thm ("NET_DILEMMA", 5446 ``!net. (?a. (?x. netord net x a) /\ (!x. netord net x a ==> P x)) /\ 5447 (?b. (?x. netord net x b) /\ (!x. netord net x b ==> Q x)) 5448 ==> ?c. (?x. netord net x c) /\ (!x. netord net x c ==> P x /\ Q x)``, 5449 MESON_TAC[NET]); 5450 5451(* ------------------------------------------------------------------------- *) 5452(* Common nets and the "within" modifier for nets. *) 5453(* ------------------------------------------------------------------------- *) 5454 5455val _ = set_fixity "within" (Infix(NONASSOC, 450)); 5456val _ = set_fixity "in_direction" (Infix(NONASSOC, 450)); 5457 5458val at = new_definition ("at", 5459 ``at a = mk_net(\x y. &0 < dist(x,a) /\ dist(x,a) <= dist(y,a))``); 5460 5461val at_infinity = new_definition ("at_infinity", 5462 ``at_infinity = mk_net(\x y. abs(x) >= abs(y))``); 5463 5464val at_posinfinity = new_definition ("at_posinfinity", 5465 ``at_posinfinity = mk_net(\x y:real. x >= y)``); 5466 5467val at_neginfinity = new_definition ("at_neginfinity", 5468 ``at_neginfinity = mk_net(\x y:real. x <= y)``); 5469 5470val sequentially = new_definition ("sequentially", 5471 ``sequentially = mk_net(\m:num n. m >= n)``); 5472 5473val within = new_definition ("within", 5474 ``net within s = mk_net(\x y. netord net x y /\ x IN s)``); 5475 5476val in_direction = new_definition ("in_direction", 5477 ``a in_direction v = (at a) within {b | ?c. &0 <= c /\ (b - a = c * v)}``); 5478 5479(* ------------------------------------------------------------------------- *) 5480(* Prove that they are all nets. *) 5481(* ------------------------------------------------------------------------- *) 5482 5483fun NET_PROVE_TAC [def] = 5484 SIMP_TAC std_ss [GSYM FUN_EQ_THM, def] THEN 5485 REWRITE_TAC [ETA_AX] THEN 5486 ASM_SIMP_TAC std_ss [GSYM(CONJUNCT2 net_tybij)]; 5487 5488val AT = store_thm ("AT", 5489 ``!a:real x y. 5490 netord(at a) x y <=> &0 < dist(x,a) /\ dist(x,a) <= dist(y,a)``, 5491 GEN_TAC THEN NET_PROVE_TAC[at] THEN 5492 METIS_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS, REAL_LET_TRANS]); 5493 5494val AT_INFINITY = store_thm ("AT_INFINITY", 5495 ``!x y. netord at_infinity x y <=> abs(x) >= abs(y)``, 5496 NET_PROVE_TAC[at_infinity] THEN 5497 REWRITE_TAC[real_ge, REAL_LE_REFL] THEN 5498 MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]); 5499 5500val AT_POSINFINITY = store_thm ("AT_POSINFINITY", 5501 ``!x y. netord at_posinfinity x y <=> x >= y``, 5502 NET_PROVE_TAC[at_posinfinity] THEN 5503 REWRITE_TAC[real_ge, REAL_LE_REFL] THEN 5504 MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]); 5505 5506val AT_NEGINFINITY = store_thm ("AT_NEGINFINITY", 5507 ``!x y. netord at_neginfinity x y <=> x <= y``, 5508 NET_PROVE_TAC[at_neginfinity] THEN 5509 REWRITE_TAC[real_ge, REAL_LE_REFL] THEN 5510 MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]); 5511 5512val SEQUENTIALLY = store_thm ("SEQUENTIALLY", 5513 ``!m n. netord sequentially m n <=> m >= n``, 5514 NET_PROVE_TAC[sequentially] THEN REWRITE_TAC[GREATER_EQ, LESS_EQ_REFL] THEN 5515 MESON_TAC[LESS_EQ_CASES, LESS_EQ_REFL, LESS_EQ_TRANS]); 5516 5517val WITHIN = store_thm ("WITHIN", 5518 ``!n s x y. netord(n within s) x y <=> netord n x y /\ x IN s``, 5519 GEN_TAC THEN GEN_TAC THEN SIMP_TAC std_ss [within, GSYM FUN_EQ_THM] THEN 5520 REWRITE_TAC[GSYM(CONJUNCT2 net_tybij), ETA_AX] THEN 5521 METIS_TAC[NET]); 5522 5523val IN_DIRECTION = store_thm ("IN_DIRECTION", 5524 ``!a v x y. netord(a in_direction v) x y <=> 5525 &0 < dist(x,a) /\ dist(x,a) <= dist(y,a) /\ 5526 ?c. &0 <= c /\ (x - a = c * v)``, 5527 SIMP_TAC std_ss [WITHIN, AT, in_direction, GSPECIFICATION] THEN METIS_TAC []); 5528 5529val WITHIN_UNIV = store_thm ("WITHIN_UNIV", 5530 ``!x:real. at x within UNIV = at x``, 5531 REWRITE_TAC[within, at, IN_UNIV] THEN REWRITE_TAC[ETA_AX, net_tybij]); 5532 5533val WITHIN_WITHIN = store_thm ("WITHIN_WITHIN", 5534 ``!net s t. (net within s) within t = net within (s INTER t)``, 5535 ONCE_REWRITE_TAC[within] THEN 5536 REWRITE_TAC[WITHIN, IN_INTER, GSYM CONJ_ASSOC]); 5537 5538(* ------------------------------------------------------------------------- *) 5539(* Identify trivial limits, where we can't approach arbitrarily closely. *) 5540(* ------------------------------------------------------------------------- *) 5541 5542val trivial_limit = new_definition ("trivial_limit", 5543 ``trivial_limit net <=> 5544 (!a:'a b. a = b) \/ 5545 ?a:'a b. ~(a = b) /\ !x. ~(netord(net) x a) /\ ~(netord(net) x b)``); 5546 5547val TRIVIAL_LIMIT_WITHIN = store_thm ("TRIVIAL_LIMIT_WITHIN", 5548 ``!a:real. trivial_limit (at a within s) <=> ~(a limit_point_of s)``, 5549 REWRITE_TAC[trivial_limit, LIMPT_APPROACHABLE_LE, WITHIN, AT, DIST_NZ] THEN 5550 REPEAT GEN_TAC THEN EQ_TAC THENL 5551 [DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL 5552 [MESON_TAC[REAL_LT_01, REAL_LT_REFL, REAL_CHOOSE_DIST, 5553 DIST_REFL, REAL_LT_IMP_LE], 5554 DISCH_THEN(X_CHOOSE_THEN ``b:real`` (X_CHOOSE_THEN ``c:real`` 5555 STRIP_ASSUME_TAC)) THEN 5556 SUBGOAL_THEN ``&0 < dist(a,b:real) \/ &0 < dist(a,c:real)`` MP_TAC THEN 5557 ASM_MESON_TAC[DIST_TRIANGLE, DIST_SYM, GSYM DIST_NZ, GSYM DIST_EQ_0, 5558 REAL_ARITH ``x:real <= &0 + &0 ==> ~(&0 < x)``]], 5559 KNOW_TAC ``!e. (0 < e ==> ?x'. x' IN s /\ 0 < dist (x',a) /\ dist (x',a) <= e) = 5560 (\e. 0 < e ==> ?x'. x' IN s /\ 0 < dist (x',a) /\ dist (x',a) <= e) e`` THENL 5561 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 5562 REWRITE_TAC[NOT_FORALL_THM] THEN BETA_TAC THEN REWRITE_TAC [NOT_IMP] THEN 5563 SIMP_TAC std_ss [GSYM LEFT_EXISTS_IMP_THM] THEN 5564 STRIP_TAC THEN DISJ2_TAC THEN 5565 EXISTS_TAC ``a:real`` THEN 5566 SUBGOAL_THEN ``?b:real. dist(a,b) = x`` MP_TAC THENL 5567 [ASM_SIMP_TAC std_ss [REAL_CHOOSE_DIST, REAL_LT_IMP_LE], ALL_TAC] THEN 5568 STRIP_TAC THEN EXISTS_TAC ``b:real`` THEN POP_ASSUM MP_TAC THEN 5569 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN 5570 ASM_MESON_TAC[REAL_NOT_LE, DIST_REFL, DIST_NZ, DIST_SYM]]); 5571 5572val TRIVIAL_LIMIT_AT = store_thm ("TRIVIAL_LIMIT_AT", 5573 ``!a. ~(trivial_limit (at a))``, 5574 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 5575 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN, LIMPT_UNIV]); 5576 5577val TRIVIAL_LIMIT_AT_INFINITY = store_thm ("TRIVIAL_LIMIT_AT_INFINITY", 5578 ``~(trivial_limit at_infinity)``, 5579 REWRITE_TAC[trivial_limit, AT_INFINITY, real_ge] THEN 5580 MESON_TAC[REAL_LE_REFL, REAL_CHOOSE_SIZE, REAL_LT_01, REAL_LT_LE]); 5581 5582val TRIVIAL_LIMIT_AT_POSINFINITY = store_thm ("TRIVIAL_LIMIT_AT_POSINFINITY", 5583 ``~(trivial_limit at_posinfinity)``, 5584 REWRITE_TAC[trivial_limit, AT_POSINFINITY, DE_MORGAN_THM] THEN 5585 CONJ_TAC THENL 5586 [DISCH_THEN(MP_TAC o SPECL [``&0:real``, ``&1:real``]) THEN REAL_ARITH_TAC, ALL_TAC] THEN 5587 REWRITE_TAC[DE_MORGAN_THM, NOT_EXISTS_THM, real_ge, REAL_NOT_LE] THEN 5588 MESON_TAC[REAL_LT_TOTAL, REAL_LT_ANTISYM]); 5589 5590val TRIVIAL_LIMIT_AT_NEGINFINITY = store_thm ("TRIVIAL_LIMIT_AT_NEGINFINITY", 5591 ``~(trivial_limit at_neginfinity)``, 5592 REWRITE_TAC[trivial_limit, AT_NEGINFINITY, DE_MORGAN_THM] THEN 5593 CONJ_TAC THENL 5594 [DISCH_THEN(MP_TAC o SPECL [``&0:real``, ``&1:real``]) THEN REAL_ARITH_TAC, ALL_TAC] THEN 5595 REWRITE_TAC[DE_MORGAN_THM, NOT_EXISTS_THM, real_ge, REAL_NOT_LE] THEN 5596 MESON_TAC[REAL_LT_TOTAL, REAL_LT_ANTISYM]); 5597 5598val TRIVIAL_LIMIT_SEQUENTIALLY = store_thm ("TRIVIAL_LIMIT_SEQUENTIALLY", 5599 ``~(trivial_limit sequentially)``, 5600 REWRITE_TAC[trivial_limit, SEQUENTIALLY] THEN 5601 MESON_TAC[GREATER_EQ, LESS_EQ_REFL, SUC_NOT]); 5602 5603val LIM_WITHIN_CLOSED_TRIVIAL = store_thm ("LIM_WITHIN_CLOSED_TRIVIAL", 5604 ``!a s. closed s /\ ~(a IN s) ==> trivial_limit (at a within s)``, 5605 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN MESON_TAC[CLOSED_LIMPT]); 5606 5607val NONTRIVIAL_LIMIT_WITHIN = store_thm ("NONTRIVIAL_LIMIT_WITHIN", 5608 ``!net s. trivial_limit net ==> trivial_limit(net within s)``, 5609 REWRITE_TAC[trivial_limit, WITHIN] THEN MESON_TAC[]); 5610 5611(* ------------------------------------------------------------------------- *) 5612(* Some property holds "sufficiently close" to the limit point. *) 5613(* ------------------------------------------------------------------------- *) 5614 5615val eventually = new_definition ("eventually", 5616 ``eventually p net <=> 5617 trivial_limit net \/ 5618 ?y. (?x. netord net x y) /\ (!x. netord net x y ==> p x)``); 5619 5620val EVENTUALLY_HAPPENS = store_thm ("EVENTUALLY_HAPPENS", 5621 ``!net p. eventually p net ==> trivial_limit net \/ ?x. p x``, 5622 REWRITE_TAC[eventually] THEN MESON_TAC[]); 5623 5624val EVENTUALLY_WITHIN_LE = store_thm ("EVENTUALLY_WITHIN_LE", 5625 ``!s a:real p. 5626 eventually p (at a within s) <=> 5627 ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d ==> p(x)``, 5628 REWRITE_TAC[eventually, AT, WITHIN, TRIVIAL_LIMIT_WITHIN] THEN 5629 REWRITE_TAC[LIMPT_APPROACHABLE_LE, DIST_NZ] THEN 5630 REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LTE_TRANS], ALL_TAC] THEN 5631 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 5632 MATCH_MP_TAC(TAUT `(a ==> b) ==> ~a \/ b`) THEN DISCH_TAC THEN 5633 SUBGOAL_THEN ``?b:real. dist(a,b) = d`` MP_TAC THENL 5634 [ASM_SIMP_TAC std_ss [REAL_CHOOSE_DIST, REAL_LT_IMP_LE], ALL_TAC] THEN 5635 STRIP_TAC THEN EXISTS_TAC ``b:real`` THEN POP_ASSUM MP_TAC THEN 5636 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN 5637 ASM_MESON_TAC[REAL_NOT_LE, DIST_REFL, DIST_NZ, DIST_SYM]); 5638 5639val EVENTUALLY_WITHIN = store_thm ("EVENTUALLY_WITHIN", 5640 ``!s a:real p. 5641 eventually p (at a within s) <=> 5642 ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)``, 5643 REWRITE_TAC[EVENTUALLY_WITHIN_LE] THEN 5644 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN 5645 SIMP_TAC std_ss [APPROACHABLE_LT_LE]); 5646 5647val EVENTUALLY_AT = store_thm ("EVENTUALLY_AT", 5648 ``!a p. eventually p (at a) <=> 5649 ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)``, 5650 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 5651 REWRITE_TAC[EVENTUALLY_WITHIN, IN_UNIV]); 5652 5653val EVENTUALLY_SEQUENTIALLY = store_thm ("EVENTUALLY_SEQUENTIALLY", 5654 ``!p. eventually p sequentially <=> ?N. !n. N <= n ==> p n``, 5655 REWRITE_TAC[eventually, SEQUENTIALLY, GREATER_EQ, LESS_EQ_REFL, 5656 TRIVIAL_LIMIT_SEQUENTIALLY] THEN MESON_TAC[LESS_EQ_REFL]); 5657 5658val EVENTUALLY_AT_INFINITY = store_thm ("EVENTUALLY_AT_INFINITY", 5659 ``!p. eventually p at_infinity <=> ?b. !x. abs(x) >= b ==> p x``, 5660 SIMP_TAC std_ss [eventually, AT_INFINITY, TRIVIAL_LIMIT_AT_INFINITY] THEN 5661 REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LE_REFL], ALL_TAC] THEN 5662 MESON_TAC[real_ge, REAL_LE_REFL, REAL_CHOOSE_SIZE, 5663 REAL_ARITH ``&0 <= b:real \/ (!x. x >= &0 ==> x >= b)``]); 5664 5665val EVENTUALLY_AT_POSINFINITY = store_thm ("EVENTUALLY_AT_POSINFINITY", 5666 ``!p. eventually p at_posinfinity <=> ?b. !x. x >= b ==> p x``, 5667 REWRITE_TAC[eventually, TRIVIAL_LIMIT_AT_POSINFINITY, AT_POSINFINITY] THEN 5668 MESON_TAC[REAL_ARITH ``x >= x``]); 5669 5670val EVENTUALLY_AT_NEGINFINITY = store_thm ("EVENTUALLY_AT_NEGINFINITY", 5671 ``!p. eventually p at_neginfinity <=> ?b. !x. x <= b ==> p x``, 5672 REWRITE_TAC[eventually, TRIVIAL_LIMIT_AT_NEGINFINITY, AT_NEGINFINITY] THEN 5673 MESON_TAC[REAL_LE_REFL]); 5674 5675val EVENTUALLY_AT_INFINITY_POS = store_thm ("EVENTUALLY_AT_INFINITY_POS", 5676 ``!p:real->bool. 5677 eventually p at_infinity <=> ?b. &0 < b /\ !x. abs x >= b ==> p x``, 5678 GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT_INFINITY, real_ge] THEN 5679 MESON_TAC[REAL_ARITH ``&0 < abs b + &1 /\ (abs b + &1 <= x ==> b <= x:real)``]); 5680 5681val ALWAYS_EVENTUALLY = store_thm ("ALWAYS_EVENTUALLY", 5682 ``(!x. p x) ==> eventually p net``, 5683 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[eventually, trivial_limit] THEN 5684 MESON_TAC[]); 5685 5686(* ------------------------------------------------------------------------- *) 5687(* Combining theorems for "eventually". *) 5688(* ------------------------------------------------------------------------- *) 5689 5690val EVENTUALLY_AND = store_thm ("EVENTUALLY_AND", 5691 ``!net:('a net) p q. 5692 eventually (\x. p x /\ q x) net <=> 5693 eventually p net /\ eventually q net``, 5694 REPEAT GEN_TAC THEN REWRITE_TAC[eventually] THEN 5695 ASM_CASES_TAC ``trivial_limit(net:('a net))`` THEN ASM_REWRITE_TAC[] THEN 5696 EQ_TAC THEN SIMP_TAC std_ss [NET_DILEMMA] THENL [MESON_TAC [], ALL_TAC] THEN 5697 DISCH_TAC THEN MATCH_MP_TAC NET_DILEMMA THEN METIS_TAC []); 5698 5699val EVENTUALLY_MONO = store_thm ("EVENTUALLY_MONO", 5700 ``!net:('a net) p q. 5701 (!x. p x ==> q x) /\ eventually p net 5702 ==> eventually q net``, 5703 REWRITE_TAC[eventually] THEN MESON_TAC[]); 5704 5705val EVENTUALLY_MP = store_thm ("EVENTUALLY_MP", 5706 ``!net:('a net) p q. 5707 eventually (\x. p x ==> q x) net /\ eventually p net 5708 ==> eventually q net``, 5709 REWRITE_TAC[GSYM EVENTUALLY_AND] THEN 5710 REWRITE_TAC[eventually] THEN MESON_TAC[]); 5711 5712val EVENTUALLY_FALSE = store_thm ("EVENTUALLY_FALSE", 5713 ``!net. eventually (\x. F) net <=> trivial_limit net``, 5714 REWRITE_TAC[eventually] THEN MESON_TAC[]); 5715 5716val EVENTUALLY_TRUE = store_thm ("EVENTUALLY_TRUE", 5717 ``!net. eventually (\x. T) net <=> T``, 5718 REWRITE_TAC[eventually, trivial_limit] THEN MESON_TAC[]); 5719 5720val NOT_EVENTUALLY = store_thm ("NOT_EVENTUALLY", 5721 ``!net p. (!x. ~(p x)) /\ ~(trivial_limit net) ==> ~(eventually p net)``, 5722 REWRITE_TAC[eventually] THEN MESON_TAC[]); 5723 5724val EVENTUALLY_FORALL = store_thm ("EVENTUALLY_FORALL", 5725 ``!net:('a net) p s:'b->bool. 5726 FINITE s /\ ~(s = {}) 5727 ==> (eventually (\x. !a. a IN s ==> p a x) net <=> 5728 !a. a IN s ==> eventually (p a) net)``, 5729 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 5730 KNOW_TAC ``!s:'b->bool. (s <> ({} :'b -> bool) ==> 5731 (eventually (\(x :'a). !(a :'b). a IN s ==> (p :'b -> 'a -> bool) a x) 5732 (net :'a net) <=> !(a :'b). a IN s ==> eventually (p a) net)) = 5733 (\s. s <> ({} :'b -> bool) ==> 5734 (eventually (\(x :'a). !(a :'b). a IN s ==> (p :'b -> 'a -> bool) a x) 5735 (net :'a net) <=> !(a :'b). a IN s ==> eventually (p a) net)) s`` THENL 5736 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 5737 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 5738 SIMP_TAC std_ss [FORALL_IN_INSERT, EVENTUALLY_AND, ETA_AX] THEN 5739 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 5740 MAP_EVERY X_GEN_TAC [``t:'b->bool``, ``b:'b``] THEN 5741 ASM_CASES_TAC ``t:'b->bool = {}`` THEN 5742 ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, EVENTUALLY_TRUE] THEN METIS_TAC []); 5743 5744val FORALL_EVENTUALLY = store_thm ("FORALL_EVENTUALLY", 5745 ``!net:('a net) p s:'b->bool. 5746 FINITE s /\ ~(s = {}) 5747 ==> ((!a. a IN s ==> eventually (p a) net) <=> 5748 eventually (\x. !a. a IN s ==> p a x) net)``, 5749 SIMP_TAC std_ss [EVENTUALLY_FORALL]); 5750 5751(* ------------------------------------------------------------------------- *) 5752(* Limits, defined as vacuously true when the limit is trivial. *) 5753(* ------------------------------------------------------------------------- *) 5754 5755val _ = hide "-->"; 5756 5757val tendsto = new_infixr_definition("tendsto", 5758 ``$--> f l net = !e. &0 < e ==> eventually (\x. dist(f(x),l) < e) net``,750); 5759 5760val lim_def = new_definition ("lim_def", 5761 ``lim_def net f = @l. (f --> l) net``); 5762 5763val _ = overload_on ("lim",``lim_def``); 5764 5765val LIM = store_thm ("LIM", 5766 ``(f --> l) net <=> 5767 trivial_limit net \/ 5768 !e. &0 < e ==> ?y. (?x. netord(net) x y) /\ 5769 !x. netord(net) x y ==> dist(f(x),l) < e``, 5770 REWRITE_TAC[tendsto, eventually] THEN MESON_TAC[]); 5771 5772(* ------------------------------------------------------------------------- *) 5773(* Show that they yield usual definitions in the various cases. *) 5774(* ------------------------------------------------------------------------- *) 5775 5776val LIM_WITHIN_LE = store_thm ("LIM_WITHIN_LE", 5777 ``!f:real->real l a s. 5778 (f --> l)(at a within s) <=> 5779 !e. &0 < e ==> ?d. &0 < d /\ 5780 !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d 5781 ==> dist(f(x),l) < e``, 5782 SIMP_TAC std_ss [tendsto, EVENTUALLY_WITHIN_LE]); 5783 5784val LIM_WITHIN = store_thm ("LIM_WITHIN", 5785 ``!f:real->real l a s. 5786 (f --> l) (at a within s) <=> 5787 !e. &0 < e 5788 ==> ?d. &0 < d /\ 5789 !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d 5790 ==> dist(f(x),l) < e``, 5791 SIMP_TAC std_ss [tendsto, EVENTUALLY_WITHIN] THEN MESON_TAC[]); 5792 5793val LIM_AT_LE = store_thm ("LIM_AT_LE", 5794 ``!f l a. (f --> l) (at a) <=> 5795 !e. &0 < e 5796 ==> ?d. &0 < d /\ 5797 !x. &0 < dist(x,a) /\ dist(x,a) <= d 5798 ==> dist (f x,l) < e``, 5799 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 5800 REWRITE_TAC[LIM_WITHIN_LE, IN_UNIV]); 5801 5802val LIM_AT = store_thm ("LIM_AT", 5803 ``!f l:real a:real. 5804 (f --> l) (at a) <=> 5805 !e. &0 < e 5806 ==> ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d 5807 ==> dist(f(x),l) < e``, 5808 REWRITE_TAC[tendsto, EVENTUALLY_AT] THEN MESON_TAC[]); 5809 5810val LIM_AT_INFINITY = store_thm ("LIM_AT_INFINITY", 5811 ``!f l. (f --> l) at_infinity <=> 5812 !e. &0 < e ==> ?b. !x. abs(x) >= b ==> dist(f(x),l) < e``, 5813 SIMP_TAC std_ss [tendsto, EVENTUALLY_AT_INFINITY] THEN MESON_TAC[]); 5814 5815val LIM_AT_INFINITY_POS = store_thm ("LIM_AT_INFINITY_POS", 5816 ``!f l. (f --> l) at_infinity <=> 5817 !e. &0 < e ==> ?b. &0 < b /\ !x. abs x >= b ==> dist(f x,l) < e``, 5818 REPEAT GEN_TAC THEN SIMP_TAC std_ss [LIM_AT_INFINITY] THEN 5819 METIS_TAC[REAL_ARITH ``&0 < abs b + &1 /\ (x >= abs b + &1 ==> x >= b)``]); 5820 5821val LIM_AT_POSINFINITY = store_thm ("LIM_AT_POSINFINITY", 5822 ``!f l. (f --> l) at_posinfinity <=> 5823 !e. &0 < e ==> ?b. !x. x >= b ==> dist(f(x),l) < e``, 5824 REWRITE_TAC[tendsto, EVENTUALLY_AT_POSINFINITY] THEN MESON_TAC[]); 5825 5826val LIM_AT_NEGINFINITY = store_thm ("LIM_AT_NEGINFINITY", 5827 ``!f l. (f --> l) at_neginfinity <=> 5828 !e. &0 < e ==> ?b. !x. x <= b ==> dist(f(x),l) < e``, 5829 REWRITE_TAC[tendsto, EVENTUALLY_AT_NEGINFINITY] THEN MESON_TAC[]); 5830 5831val LIM_SEQUENTIALLY = store_thm ("LIM_SEQUENTIALLY", 5832 ``!s l. (s --> l) sequentially <=> 5833 !e. &0 < e ==> ?N. !n. N <= n ==> dist(s(n),l) < e``, 5834 REWRITE_TAC[tendsto, EVENTUALLY_SEQUENTIALLY] THEN MESON_TAC[]); 5835 5836val LIM_EVENTUALLY = store_thm ("LIM_EVENTUALLY", 5837 ``!net f l. eventually (\x. f x = l) net ==> (f --> l) net``, 5838 REWRITE_TAC[eventually, LIM] THEN MESON_TAC[DIST_REFL]); 5839 5840val LIM_POSINFINITY_SEQUENTIALLY = store_thm ("LIM_POSINFINITY_SEQUENTIALLY", 5841 ``!f l. (f --> l) at_posinfinity ==> ((\n. f(&n)) --> l) sequentially``, 5842 REPEAT GEN_TAC THEN 5843 REWRITE_TAC[LIM_AT_POSINFINITY, LIM_SEQUENTIALLY] THEN 5844 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 5845 FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN 5846 DISCH_THEN(X_CHOOSE_TAC ``B:real``) THEN 5847 MP_TAC(ISPEC ``B:real`` SIMP_REAL_ARCH) THEN 5848 DISCH_THEN(X_CHOOSE_THEN ``N:num`` STRIP_ASSUME_TAC) THEN 5849 EXISTS_TAC ``N:num`` THEN POP_ASSUM MP_TAC THEN 5850 REPEAT STRIP_TAC THEN BETA_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 5851 RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN 5852 METIS_TAC [real_ge, REAL_LE_TRANS]); 5853 5854val LIM_INFINITY_POSINFINITY = store_thm ("LIM_INFINITY_POSINFINITY", 5855 ``!f l:real. (f --> l) at_infinity ==> (f --> l) at_posinfinity``, 5856 SIMP_TAC std_ss [LIM_AT_INFINITY, LIM_AT_POSINFINITY, o_THM] THEN 5857 METIS_TAC[dist, REAL_ARITH ``x >= b ==> abs(x) >= b:real``]); 5858 5859(* ------------------------------------------------------------------------- *) 5860(* The expected monotonicity property. *) 5861(* ------------------------------------------------------------------------- *) 5862 5863val LIM_WITHIN_EMPTY = store_thm ("LIM_WITHIN_EMPTY", 5864 ``!f l x. (f --> l) (at x within {})``, 5865 REWRITE_TAC[LIM_WITHIN, NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]); 5866 5867val LIM_WITHIN_SUBSET = store_thm ("LIM_WITHIN_SUBSET", 5868 ``!f l a s. 5869 (f --> l) (at a within s) /\ t SUBSET s ==> (f --> l) (at a within t)``, 5870 REWRITE_TAC[LIM_WITHIN, SUBSET_DEF] THEN MESON_TAC[]); 5871 5872val LIM_UNION = store_thm ("LIM_UNION", 5873 ``!f x l s t. 5874 (f --> l) (at x within s) /\ (f --> l) (at x within t) 5875 ==> (f --> l) (at x within (s UNION t))``, 5876 REPEAT GEN_TAC THEN REWRITE_TAC[LIM_WITHIN, IN_UNION] THEN 5877 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN STRIP_TAC THEN 5878 X_GEN_TAC ``e:real`` THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 5879 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN 5880 DISCH_THEN(CONJUNCTS_THEN2 5881 (X_CHOOSE_TAC ``d1:real``) (X_CHOOSE_TAC ``d2:real``)) THEN 5882 EXISTS_TAC ``min d1 d2:real`` THEN ASM_MESON_TAC[REAL_LT_MIN]); 5883 5884val LIM_UNION_UNIV = store_thm ("LIM_UNION_UNIV", 5885 ``!f x l s t. 5886 (f --> l) (at x within s) /\ (f --> l) (at x within t) /\ 5887 (s UNION t = univ(:real)) ==> (f --> l) (at x)``, 5888 MESON_TAC[LIM_UNION, WITHIN_UNIV]); 5889 5890(* ------------------------------------------------------------------------- *) 5891(* Composition of limits. *) 5892(* ------------------------------------------------------------------------- *) 5893 5894val LIM_COMPOSE_WITHIN = store_thm ("LIM_COMPOSE_WITHIN", 5895 ``!net f:'a->real g:real->real s y z. 5896 (f --> y) net /\ 5897 eventually (\w. f w IN s /\ ((f w = y) ==> (g y = z))) net /\ 5898 (g --> z) (at y within s) 5899 ==> ((g o f) --> z) net``, 5900 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto, CONJ_ASSOC] THEN 5901 KNOW_TAC ``(!e. (&0 < e ==> eventually (\x. dist ((f:'a->real) x,y) < e) net) /\ 5902 eventually (\w. f w IN s /\ ((f w = y) ==> ((g:real->real) y = z))) net) /\ 5903 (!e. &0 < e ==> eventually (\x. dist (g x,z) < e) (at y within s)) 5904 ==> (!e. &0 < e ==> eventually (\x. dist ((g o f) x,z) < e) net)`` THENL 5905 [ALL_TAC, SIMP_TAC std_ss [LEFT_AND_FORALL_THM]] THEN 5906 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 5907 STRIP_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 5908 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN 5909 REWRITE_TAC[EVENTUALLY_WITHIN, GSYM DIST_NZ, o_DEF] THEN 5910 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 5911 UNDISCH_TAC ``!e. (0 < e ==> eventually (\x. dist (f x,y) < e) net) /\ 5912 eventually (\w. f w IN s /\ ((f:'a->real w = y) ==> (g:real->real y = z))) net`` THEN 5913 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``d:real``) THEN 5914 ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN BETA_TAC THEN 5915 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 5916 ASM_MESON_TAC[DIST_REFL]); 5917 5918val LIM_COMPOSE_AT = store_thm ("LIM_COMPOSE_AT", 5919 ``!net f:'a->real g:real->real y z. 5920 (f --> y) net /\ 5921 eventually (\w. (f w = y) ==> (g y = z)) net /\ 5922 (g --> z) (at y) 5923 ==> ((g o f) --> z) net``, 5924 REPEAT STRIP_TAC THEN 5925 MP_TAC(ISPECL [``net:('a)net``, ``f:'a->real``, ``g:real->real``, 5926 ``univ(:real)``, ``y:real``, ``z:real``] 5927 LIM_COMPOSE_WITHIN) THEN 5928 ASM_REWRITE_TAC[IN_UNIV, WITHIN_UNIV]); 5929 5930(* ------------------------------------------------------------------------- *) 5931(* Interrelations between restricted and unrestricted limits. *) 5932(* ------------------------------------------------------------------------- *) 5933 5934val LIM_AT_WITHIN = store_thm ("LIM_AT_WITHIN", 5935 ``!f l a s. (f --> l)(at a) ==> (f --> l)(at a within s)``, 5936 REWRITE_TAC[LIM_AT, LIM_WITHIN] THEN MESON_TAC[]); 5937 5938val LIM_WITHIN_OPEN = store_thm ("LIM_WITHIN_OPEN", 5939 ``!f l a:real s. 5940 a IN s /\ open s ==> ((f --> l)(at a within s) <=> (f --> l)(at a))``, 5941 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [LIM_AT_WITHIN] THEN 5942 REWRITE_TAC[LIM_AT, LIM_WITHIN] THEN 5943 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 5944 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN 5945 DISCH_THEN(X_CHOOSE_THEN ``d1:real`` STRIP_ASSUME_TAC) THEN 5946 UNDISCH_TAC ``open s`` THEN GEN_REWR_TAC LAND_CONV [open_def] THEN 5947 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``a:real``) THEN 5948 ASM_REWRITE_TAC[] THEN 5949 DISCH_THEN(X_CHOOSE_THEN ``d2:real`` STRIP_ASSUME_TAC) THEN 5950 MP_TAC(SPECL [``d1:real``, ``d2:real``] REAL_DOWN2) THEN ASM_REWRITE_TAC[] THEN 5951 ASM_MESON_TAC[REAL_LT_TRANS]); 5952 5953(* ------------------------------------------------------------------------- *) 5954(* Segment of natural numbers starting at a specific number. *) 5955(* ------------------------------------------------------------------------- *) 5956 5957val from = new_definition ("from", 5958 ``from n = {m:num | n <= m}``); 5959 5960val FROM_0 = store_thm ("FROM_0", 5961 ``from 0 = univ(:num)``, 5962 REWRITE_TAC[from, ZERO_LESS_EQ] THEN SET_TAC[]); 5963 5964val IN_FROM = store_thm ("IN_FROM", 5965 ``!m n. m IN from n <=> n <= m``, 5966 SIMP_TAC std_ss [from, GSPECIFICATION]); 5967 5968val FROM_INTER_NUMSEG_GEN = store_thm ("FROM_INTER_NUMSEG_GEN", 5969 ``!k m n. (from k) INTER (m..n) = (if m < k then k..n else m..n)``, 5970 REPEAT GEN_TAC THEN COND_CASES_TAC THEN POP_ASSUM MP_TAC THEN 5971 SIMP_TAC std_ss [from, GSPECIFICATION, IN_INTER, IN_NUMSEG, EXTENSION] THEN 5972 ARITH_TAC); 5973 5974val FROM_INTER_NUMSEG_MAX = store_thm ("FROM_INTER_NUMSEG_MAX", 5975 ``!m n p. from p INTER (m..n) = (MAX p m..n)``, 5976 SIMP_TAC arith_ss [EXTENSION, IN_INTER, IN_NUMSEG, IN_FROM] THEN ARITH_TAC); 5977 5978val FROM_INTER_NUMSEG = store_thm ("FROM_INTER_NUMSEG", 5979 ``!k n. (from k) INTER (0:num..n) = k..n``, 5980 SIMP_TAC std_ss [from, GSPECIFICATION, IN_INTER, IN_NUMSEG, EXTENSION] THEN 5981 ARITH_TAC); 5982 5983val INFINITE_FROM = store_thm ("INFINITE_FROM", 5984 ``!n. INFINITE(from n)``, 5985 GEN_TAC THEN KNOW_TAC ``from n = univ(:num) DIFF {i | i < n}`` THENL 5986 [SIMP_TAC std_ss [EXTENSION, from, IN_DIFF, IN_UNIV, GSPECIFICATION] THEN 5987 ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 5988 MATCH_MP_TAC INFINITE_DIFF_FINITE THEN 5989 REWRITE_TAC [FINITE_NUMSEG_LT, num_INFINITE]]); 5990 5991(* ------------------------------------------------------------------------- *) 5992(* More limit point characterizations. *) 5993(* ------------------------------------------------------------------------- *) 5994 5995val WLOG_LT = store_thm ("WLOG_LT", 5996 ``(!m:num. P m m) /\ (!m n. P m n <=> P n m) /\ (!m n. m < n ==> P m n) 5997 ==> !m y. P m y``, 5998 METIS_TAC[LESS_LESS_CASES]); 5999 6000val LT_EXISTS = store_thm ("LT_EXISTS", 6001 ``!m n. (m < n) <=> (?d. n = m + SUC d)``, 6002 GEN_TAC THEN INDUCT_TAC THEN SIMP_TAC std_ss [LESS_THM, ADD_CLAUSES, SUC_NOT] THEN 6003 ASM_REWRITE_TAC[INV_SUC_EQ] THEN EQ_TAC THENL 6004 [DISCH_THEN(DISJ_CASES_THEN2 SUBST1_TAC MP_TAC) THENL 6005 [EXISTS_TAC ``0:num`` THEN REWRITE_TAC[ADD_CLAUSES], 6006 DISCH_THEN(X_CHOOSE_THEN ``d:num`` SUBST1_TAC) THEN 6007 EXISTS_TAC ``SUC d`` THEN REWRITE_TAC[ADD_CLAUSES]], 6008 SIMP_TAC std_ss [LEFT_EXISTS_IMP_THM] THEN 6009 KNOW_TAC ``((?d. n = m + d) ==> (m = n) \/ ?d. n = m + SUC d) = 6010 (!d. (n = m + d) ==> (m = n) \/ ?d. n = m + SUC d)`` THENL 6011 [EQ_TAC THENL [SIMP_TAC std_ss [LEFT_EXISTS_IMP_THM], 6012 STRIP_TAC THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN 6013 POP_ASSUM (MP_TAC o Q.SPEC `d:num`) THEN FULL_SIMP_TAC std_ss []], 6014 ALL_TAC] THEN DISC_RW_KILL THEN 6015 INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES, INV_SUC_EQ] THEN 6016 DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[] THEN DISJ2_TAC THEN 6017 EXISTS_TAC ``d:num`` THEN METIS_TAC[INV_SUC_EQ, ADD_COMM]]); 6018 6019val TRANSITIVE_STEPWISE_LT_EQ = store_thm ("TRANSITIVE_STEPWISE_LT_EQ", 6020 ``!R. (!x y z. R x y /\ R y z ==> R x z) 6021 ==> ((!m n. m < n ==> R m n) <=> (!n. R n (SUC n)))``, 6022 REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC std_ss [LESS_THM] THEN 6023 DISCH_TAC THEN SIMP_TAC std_ss [LT_EXISTS] THEN 6024 KNOW_TAC ``(!m n. (?d. n = m + SUC d) ==> R m n) = 6025 (!m d n. (n = m + SUC d) ==> R m (m + SUC d))`` THENL 6026 [METIS_TAC [LEFT_EXISTS_IMP_THM, SWAP_FORALL_THM], ALL_TAC] THEN 6027 DISC_RW_KILL THEN GEN_TAC THEN 6028 SIMP_TAC std_ss [LEFT_FORALL_IMP_THM, EXISTS_REFL, ADD_CLAUSES] THEN 6029 INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES] THEN ASM_MESON_TAC[]); 6030 6031val TRANSITIVE_STEPWISE_LT = store_thm ("TRANSITIVE_STEPWISE_LT", 6032 ``!R. (!x y z. R x y /\ R y z ==> R x z) /\ (!n. R n (SUC n)) 6033 ==> !m n. m < n ==> R m n``, 6034 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT 6035 `(a ==> (c <=> b)) ==> a /\ b ==> c`) THEN 6036 MATCH_ACCEPT_TAC TRANSITIVE_STEPWISE_LT_EQ); 6037 6038val LIMPT_SEQUENTIAL_INJ = store_thm ("LIMPT_SEQUENTIAL_INJ", 6039 ``!x:real s. 6040 x limit_point_of s <=> 6041 ?f. (!n. f(n) IN (s DELETE x)) /\ 6042 (!m n. (f m = f n) <=> (m = n)) /\ 6043 (f --> x) sequentially``, 6044 REPEAT GEN_TAC THEN 6045 REWRITE_TAC[LIMPT_APPROACHABLE, LIM_SEQUENTIALLY, IN_DELETE] THEN 6046 EQ_TAC THENL [ALL_TAC, MESON_TAC[GREATER_EQ, LESS_EQ_REFL]] THEN 6047 KNOW_TAC ``(!e. 0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e) = 6048 (!e. ?x'. &0 < e ==> x' IN s /\ ~(x' = x) /\ dist (x',x) < e)`` THENL 6049 [SIMP_TAC std_ss [GSYM RIGHT_EXISTS_IMP_THM], ALL_TAC] THEN DISC_RW_KILL THEN 6050 SIMP_TAC std_ss [SKOLEM_THM] THEN STRIP_TAC THEN 6051 KNOW_TAC ``?z. (z 0 = f (&1)) /\ 6052 (!n. z (SUC n):real = f (min (inv(&2 pow (SUC n))) (dist(z n,x))))`` THENL 6053 [RW_TAC real_ss [num_Axiom], ALL_TAC] THEN STRIP_TAC THEN 6054 EXISTS_TAC ``z:num->real`` THEN 6055 SUBGOAL_THEN 6056 ``!n. z(n) IN s /\ ~(z n:real = x) /\ dist(z n,x) < inv(&2 pow n)`` 6057 ASSUME_TAC THENL 6058 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THENL [REWRITE_TAC [pow, REAL_INV1] THEN 6059 ASM_SIMP_TAC std_ss [REAL_LT_01], FIRST_X_ASSUM(MP_TAC o SPEC 6060 ``min (inv(&2 pow (SUC n))) (dist(z n:real,x))``) THEN 6061 ASM_SIMP_TAC std_ss [REAL_LT_MIN, REAL_LT_INV_EQ, REAL_POW_LT, DIST_POS_LT, 6062 REAL_ARITH ``0:real < 2``]], 6063 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL 6064 [KNOW_TAC ``!m:num n. (((z:num->real) m = z n) <=> (m = n)) = 6065 (\m n. ((z m = z n) <=> (m = n))) m n`` THENL 6066 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 6067 MATCH_MP_TAC WLOG_LT THEN BETA_TAC THEN SIMP_TAC std_ss [EQ_SYM_EQ] THEN 6068 SUBGOAL_THEN ``!m n:num. m < n ==> dist(z n:real,x) < dist(z m,x)`` 6069 (fn th => MESON_TAC[th, REAL_LT_REFL, LESS_REFL]) THEN 6070 KNOW_TAC ``!m n:num. (dist (z n,x) < dist (z m,x)) = 6071 (\m n. dist (z n,x) < dist (z m,x)) m n`` THENL 6072 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 6073 MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN BETA_TAC THEN 6074 CONJ_TAC THENL [REAL_ARITH_TAC, GEN_TAC THEN ASM_REWRITE_TAC[]] THEN 6075 FIRST_X_ASSUM(MP_TAC o SPEC 6076 ``min (inv(&2 pow (SUC n))) (dist(z n:real,x))``) THEN 6077 ASM_SIMP_TAC std_ss [REAL_LT_MIN, REAL_LT_INV_EQ, REAL_POW_LT, 6078 REAL_ARITH ``0:real < 2``, DIST_POS_LT], 6079 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6080 MP_TAC(ISPECL [``inv(&2:real)``, ``e:real``] REAL_ARCH_POW_INV) THEN 6081 ASM_SIMP_TAC std_ss [REAL_INV_1OVER, REAL_HALF_BETWEEN] THEN 6082 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 6083 FULL_SIMP_TAC std_ss [GSYM REAL_INV_1OVER, REAL_POW_INV] THEN 6084 X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LT_TRANS THEN 6085 EXISTS_TAC ``inv (2:real pow N)`` THEN ASM_REWRITE_TAC [] THEN 6086 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``inv(&2:real pow n)`` THEN 6087 ASM_REWRITE_TAC [] THEN REWRITE_TAC [REAL_INV_1OVER] THEN 6088 SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_POW_LT, REAL_ARITH ``0 < 2:real``] THEN 6089 ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN 6090 REWRITE_TAC [GSYM REAL_INV_1OVER, GSYM real_div] THEN SIMP_TAC std_ss [REAL_LE_RDIV_EQ, 6091 REAL_POW_LT, REAL_MUL_LID, REAL_ARITH ``0 < 2:real``] THEN 6092 FULL_SIMP_TAC std_ss [REAL_LE_LT, LESS_OR_EQ] THEN DISJ1_TAC THEN 6093 MATCH_MP_TAC REAL_POW_MONO_LT THEN ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC]]); 6094 6095val LIMPT_SEQUENTIAL = store_thm ("LIMPT_SEQUENTIAL", 6096 ``!x:real s. 6097 x limit_point_of s <=> 6098 ?f. (!n. f(n) IN (s DELETE x)) /\ (f --> x) sequentially``, 6099 REPEAT GEN_TAC THEN EQ_TAC THENL 6100 [REWRITE_TAC[LIMPT_SEQUENTIAL_INJ] THEN MESON_TAC[], 6101 REWRITE_TAC[LIMPT_APPROACHABLE, LIM_SEQUENTIALLY, IN_DELETE] THEN 6102 MESON_TAC[GREATER_EQ, LESS_EQ_REFL]]); 6103 6104val INFINITE_SUPERSET = store_thm ("INFINITE_SUPERSET", 6105 ``!s t. INFINITE s /\ s SUBSET t ==> INFINITE t``, 6106 REWRITE_TAC[] THEN MESON_TAC[SUBSET_FINITE_I]); 6107 6108val LIMPT_INFINITE_OPEN_BALL_CBALL = store_thm ("LIMPT_INFINITE_OPEN_BALL_CBALL", 6109 ``(!s x:real. 6110 x limit_point_of s <=> !t. x IN t /\ open t ==> INFINITE(s INTER t)) /\ 6111 (!s x:real. 6112 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER ball(x,e))) /\ 6113 (!s x:real. 6114 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER cball(x,e)))``, 6115 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT 6116 `(q ==> p) /\ (r ==> s) /\ (s ==> q) /\ (p ==> r) 6117 ==> (p <=> q) /\ (p <=> r) /\ (p <=> s)`) THEN 6118 REPEAT CONJ_TAC THENL 6119 [REWRITE_TAC[limit_point_of, SET_RULE 6120 ``(?y. ~(y = x) /\ y IN s /\ y IN t) <=> ~(s INTER t SUBSET {x})``] THEN 6121 MESON_TAC[SUBSET_FINITE_I, FINITE_SING], 6122 MESON_TAC[INFINITE_SUPERSET, BALL_SUBSET_CBALL, 6123 SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``], 6124 MESON_TAC[INFINITE_SUPERSET, OPEN_CONTAINS_CBALL, 6125 SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``], 6126 REWRITE_TAC[LIMPT_SEQUENTIAL_INJ, IN_DELETE, FORALL_AND_THM] THEN 6127 DISCH_THEN(X_CHOOSE_THEN ``f:num->real`` STRIP_ASSUME_TAC) THEN 6128 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6129 UNDISCH_TAC ``(f --> x) sequentially`` THEN 6130 GEN_REWR_TAC LAND_CONV [LIM_SEQUENTIALLY] THEN 6131 DISCH_THEN(MP_TAC o SPEC ``e:real``) THEN 6132 ASM_REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] IN_BALL)] THEN 6133 DISCH_THEN(X_CHOOSE_TAC ``N:num``) THEN 6134 MATCH_MP_TAC INFINITE_SUPERSET THEN 6135 EXISTS_TAC ``IMAGE (f:num->real) (from N)`` THEN 6136 ASM_SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE, IN_FROM, IN_INTER] THEN 6137 ASM_MESON_TAC[IMAGE_11_INFINITE, INFINITE_FROM]]); 6138 6139val LIMPT_INFINITE_OPEN = store_thm ("LIMPT_INFINITE_OPEN", 6140 ``(!s x:real. 6141 x limit_point_of s <=> !t. x IN t /\ open t ==> INFINITE(s INTER t))``, 6142 SIMP_TAC std_ss [LIMPT_INFINITE_OPEN_BALL_CBALL]); 6143 6144val LIMPT_INFINITE_BALL = store_thm ("LIMPT_INFINITE_BALL", 6145 ``(!s x:real. 6146 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER ball(x,e)))``, 6147 METIS_TAC [LIMPT_INFINITE_OPEN_BALL_CBALL]); 6148 6149val LIMPT_INFINITE_CBALL = store_thm ("LIMPT_INFINITE_CBALL", 6150 ``(!s x:real. 6151 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER cball(x,e)))``, 6152 METIS_TAC [LIMPT_INFINITE_OPEN_BALL_CBALL]); 6153 6154val INFINITE_OPEN_IN = store_thm ("INFINITE_OPEN_IN", 6155 ``!u s:real->bool. 6156 open_in (subtopology euclidean u) s /\ (?x. x IN s /\ x limit_point_of u) 6157 ==> INFINITE s``, 6158 REPEAT STRIP_TAC THEN 6159 UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN 6160 REWRITE_TAC [OPEN_IN_OPEN] THEN 6161 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 6162 UNDISCH_TAC ``x limit_point_of u`` THEN REWRITE_TAC [LIMPT_INFINITE_OPEN] THEN 6163 FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM_SET_TAC[]); 6164 6165(* ------------------------------------------------------------------------- *) 6166(* Condensation points. *) 6167(* ------------------------------------------------------------------------- *) 6168 6169val _ = set_fixity "condensation_point_of" (Infix(NONASSOC, 450)); 6170 6171val condensation_point_of = new_definition ("condensation_point_of", 6172 ``x condensation_point_of s <=> 6173 !t. x IN t /\ open t ==> ~COUNTABLE(s INTER t)``); 6174 6175val CONDENSATION_POINT_OF_SUBSET = store_thm ("CONDENSATION_POINT_OF_SUBSET", 6176 ``!x:real s t. 6177 x condensation_point_of s /\ s SUBSET t ==> x condensation_point_of t``, 6178 REPEAT GEN_TAC THEN 6179 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 6180 REWRITE_TAC[condensation_point_of] THEN 6181 DISCH_TAC THEN X_GEN_TAC ``t':real->bool`` THEN 6182 POP_ASSUM (MP_TAC o Q.SPEC `t':real->bool`) THEN 6183 MATCH_MP_TAC MONO_IMP THEN 6184 REWRITE_TAC[GSYM MONO_NOT_EQ] THEN 6185 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] COUNTABLE_SUBSET) THEN 6186 ASM_SET_TAC[]); 6187 6188val CONDENSATION_POINT_IMP_LIMPT = store_thm ("CONDENSATION_POINT_IMP_LIMPT", 6189 ``!x s. x condensation_point_of s ==> x limit_point_of s``, 6190 REWRITE_TAC[condensation_point_of, LIMPT_INFINITE_OPEN] THEN 6191 MESON_TAC[FINITE_IMP_COUNTABLE]); 6192 6193val CONDENSATION_POINT_INFINITE_BALL_CBALL = store_thm ("CONDENSATION_POINT_INFINITE_BALL_CBALL", 6194 ``(!s x:real. 6195 x condensation_point_of s <=> 6196 !e. &0 < e ==> ~COUNTABLE(s INTER ball(x,e))) /\ 6197 (!s x:real. 6198 x condensation_point_of s <=> 6199 !e. &0 < e ==> ~COUNTABLE(s INTER cball(x,e)))``, 6200 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT 6201 `(p ==> q) /\ (q ==> r) /\ (r ==> p) 6202 ==> (p <=> q) /\ (p <=> r)`) THEN 6203 REWRITE_TAC[condensation_point_of] THEN REPEAT CONJ_TAC THENL 6204 [MESON_TAC[OPEN_BALL, CENTRE_IN_BALL], 6205 MESON_TAC[BALL_SUBSET_CBALL, COUNTABLE_SUBSET, 6206 SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``], 6207 MESON_TAC[COUNTABLE_SUBSET, OPEN_CONTAINS_CBALL, 6208 SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``]]); 6209 6210val CONDENSATION_POINT_INFINITE_BALL = store_thm ("CONDENSATION_POINT_INFINITE_BALL", 6211 ``(!s x:real. 6212 x condensation_point_of s <=> 6213 !e. &0 < e ==> ~COUNTABLE(s INTER ball(x,e)))``, 6214 METIS_TAC [CONDENSATION_POINT_INFINITE_BALL_CBALL]); 6215 6216val CONDENSATION_POINT_INFINITE_CBALL = store_thm ("CONDENSATION_POINT_INFINITE_CBALL", 6217 ``(!s x:real. 6218 x condensation_point_of s <=> 6219 !e. &0 < e ==> ~COUNTABLE(s INTER cball(x,e)))``, 6220 METIS_TAC [CONDENSATION_POINT_INFINITE_BALL_CBALL]); 6221 6222(* ------------------------------------------------------------------------- *) 6223(* Basic arithmetical combining theorems for limits. *) 6224(* ------------------------------------------------------------------------- *) 6225 6226val LIM_LINEAR = store_thm ("LIM_LINEAR", 6227 ``!net:('a)net h f l. 6228 (f --> l) net /\ linear h ==> ((\x. h(f x)) --> h l) net``, 6229 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN 6230 ASM_CASES_TAC ``trivial_limit (net:('a)net)`` THEN ASM_REWRITE_TAC[] THEN 6231 STRIP_TAC THEN FIRST_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o 6232 MATCH_MP LINEAR_BOUNDED_POS) THEN 6233 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6234 UNDISCH_TAC ``!e. 0 < e ==> ?y. (?x. netord net x y) /\ 6235 !x. netord net x y ==> dist (f x,l) < e`` THEN DISCH_TAC THEN 6236 FIRST_X_ASSUM(MP_TAC o SPEC ``e / B:real``) THEN 6237 ASM_SIMP_TAC std_ss [REAL_LT_DIV, dist, GSYM LINEAR_SUB, REAL_LT_RDIV_EQ] THEN 6238 ASM_MESON_TAC[REAL_LET_TRANS, REAL_MUL_SYM]); 6239 6240val LIM_CONST = store_thm ("LIM_CONST", 6241 ``!net a:real. ((\x. a) --> a) net``, 6242 SIMP_TAC std_ss [LIM, DIST_REFL, trivial_limit] THEN MESON_TAC[]); 6243 6244val LIM_CMUL = store_thm ("LIM_CMUL", 6245 ``!f l c. (f --> l) net ==> ((\x. c * f x) --> (c * l)) net``, 6246 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_LINEAR THEN 6247 ASM_SIMP_TAC std_ss [REWRITE_RULE[ETA_AX] 6248 (MATCH_MP LINEAR_COMPOSE_CMUL LINEAR_ID)] THEN 6249 REWRITE_TAC [linear] THEN REAL_ARITH_TAC); 6250 6251val LIM_CMUL_EQ = store_thm ("LIM_CMUL_EQ", 6252 ``!net f l c. 6253 ~(c = &0) ==> (((\x. c * f x) --> (c * l)) net <=> (f --> l) net)``, 6254 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [LIM_CMUL] THEN 6255 DISCH_THEN(MP_TAC o SPEC ``inv c:real`` o MATCH_MP LIM_CMUL) THEN 6256 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID, ETA_AX]); 6257 6258val LIM_NEG = store_thm ("LIM_NEG", 6259 ``!net f l:real. (f --> l) net ==> ((\x. -(f x)) --> -l) net``, 6260 REPEAT GEN_TAC THEN REWRITE_TAC[LIM, dist] THEN 6261 SIMP_TAC std_ss [REAL_ARITH ``-x - -y = -(x - y:real)``, ABS_NEG]); 6262 6263val LIM_NEG_EQ = store_thm ("LIM_NEG_EQ", 6264 ``!net f l:real. ((\x. -(f x)) --> -l) net <=> (f --> l) net``, 6265 REPEAT GEN_TAC THEN EQ_TAC THEN 6266 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN 6267 SIMP_TAC std_ss [REAL_NEG_NEG, ETA_AX]); 6268 6269val LIM_ADD = store_thm ("LIM_ADD", 6270 ``!net:('a)net f g l m. 6271 (f --> l) net /\ (g --> m) net ==> ((\x. f(x) + g(x)) --> (l + m)) net``, 6272 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN 6273 ASM_CASES_TAC ``trivial_limit (net:('a)net)`` THEN 6274 ASM_SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN 6275 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6276 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN 6277 KNOW_TAC ``!x y. (dist(f x, l) < e / 2:real) = 6278 (\x. (dist(f x, l) < e / 2:real)) x`` THENL 6279 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 6280 KNOW_TAC ``!x y. (dist(g x, m) < e / 2:real) = 6281 (\x. (dist(g x, m) < e / 2:real)) x`` THENL 6282 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 6283 DISCH_THEN(MP_TAC o MATCH_MP NET_DILEMMA) THEN BETA_TAC THEN 6284 STRIP_TAC THEN EXISTS_TAC ``c:'a`` THEN CONJ_TAC THENL [METIS_TAC [], ALL_TAC] THEN 6285 GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN REPEAT STRIP_TAC THEN 6286 FULL_SIMP_TAC std_ss [] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 6287 EXISTS_TAC ``dist (f x', l) + dist (g x', m)`` THEN 6288 METIS_TAC[REAL_LT_HALF1, REAL_LT_ADD2, DIST_TRIANGLE_ADD, GSYM REAL_HALF_DOUBLE]); 6289 6290val lemma = prove ( 6291 ``abs(x - y) <= abs(a - b) ==> dist(a,b) < e ==> dist(x,y) < e``, 6292 REWRITE_TAC [dist] THEN REAL_ARITH_TAC); 6293 6294val LIM_ABS = store_thm ("LIM_ABS", 6295 ``!net:('a)net f:'a->real l. 6296 (f --> l) net 6297 ==> ((\x. abs(f(x))) --> (abs(l)):real) net``, 6298 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN 6299 ASM_CASES_TAC ``trivial_limit (net:('a)net)`` THEN ASM_REWRITE_TAC[] THEN 6300 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 6301 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN 6302 STRIP_TAC THEN EXISTS_TAC ``y:'a`` THEN POP_ASSUM MP_TAC THEN 6303 POP_ASSUM MP_TAC THEN REWRITE_TAC [AND_IMP_INTRO] THEN 6304 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN 6305 STRIP_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x:'a`` THEN ASM_REWRITE_TAC [], 6306 ALL_TAC] THEN DISCH_TAC THEN GEN_TAC THEN 6307 POP_ASSUM (MP_TAC o Q.SPEC `x:'a`) THEN 6308 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN 6309 MATCH_MP_TAC lemma THEN BETA_TAC THEN 6310 REAL_ARITH_TAC); 6311 6312val LIM_SUB = store_thm ("LIM_SUB", 6313 ``!net:('a)net f g l m. 6314 (f --> l) net /\ (g --> m) net ==> ((\x. f(x) - g(x)) --> (l - m)) net``, 6315 REWRITE_TAC[real_sub] THEN ASM_SIMP_TAC std_ss [LIM_ADD, LIM_NEG]); 6316 6317val LIM_MAX = store_thm ("LIM_MAX", 6318 ``!net:('a)net f g l:real m:real. 6319 (f --> l) net /\ (g --> m) net 6320 ==> ((\x. max (f(x)) (g(x))) 6321 --> (max (l) (m)):real) net``, 6322 REPEAT GEN_TAC THEN DISCH_TAC THEN 6323 FIRST_ASSUM(MP_TAC o MATCH_MP LIM_ADD) THEN 6324 FIRST_ASSUM(MP_TAC o MATCH_MP LIM_SUB) THEN 6325 DISCH_THEN(MP_TAC o MATCH_MP LIM_ABS) THEN 6326 REWRITE_TAC[AND_IMP_INTRO] THEN 6327 DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN 6328 DISCH_THEN(MP_TAC o SPEC ``inv(&2:real)`` o MATCH_MP LIM_CMUL) THEN 6329 MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN BINOP_TAC THEN 6330 SIMP_TAC std_ss [FUN_EQ_THM, max_def, abs] THEN 6331 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN ONCE_REWRITE_TAC [GSYM real_div] THEN 6332 SIMP_TAC arith_ss [REAL_EQ_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 6333 ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN (RW_TAC arith_ss [REAL_SUB_LE] THENL 6334 [REPEAT (POP_ASSUM MP_TAC) THEN RW_TAC std_ss [AND_IMP_INTRO, REAL_LE_ANTISYM, REAL_SUB_REFL, 6335 REAL_ADD_LID] THEN REWRITE_TAC [GSYM REAL_DOUBLE], 6336 REWRITE_TAC [REAL_ARITH ``a - b + (a + b) = a + a - b + b:real``, REAL_SUB_ADD, REAL_DOUBLE], 6337 REWRITE_TAC [REAL_ARITH ``-(a - b) + (a + b) = b + b - a + a:real``, 6338 REAL_SUB_ADD, REAL_DOUBLE], 6339 FULL_SIMP_TAC real_ss [REAL_NOT_LE] THEN METIS_TAC [REAL_LT_ANTISYM]])); 6340 6341val LIM_MIN = store_thm ("LIM_MIN", 6342 ``!net:('a)net f g l:real m:real. 6343 (f --> l) net /\ (g --> m) net 6344 ==> ((\x. min (f(x)) (g(x))) 6345 --> (min (l) (m)):real) net``, 6346 REPEAT GEN_TAC THEN 6347 DISCH_THEN(CONJUNCTS_THEN(MP_TAC o MATCH_MP LIM_NEG)) THEN 6348 REWRITE_TAC[AND_IMP_INTRO] THEN 6349 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG o MATCH_MP LIM_MAX) THEN 6350 MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN 6351 Reverse BINOP_TAC >- PROVE_TAC [GSYM REAL_MIN_MAX, REAL_MIN_ACI] THEN 6352 SIMP_TAC std_ss [FUN_EQ_THM] THEN 6353 GEN_TAC >> PROVE_TAC [GSYM REAL_MIN_MAX, REAL_MIN_ACI]); 6354 6355val LIM_NULL = store_thm ("LIM_NULL", 6356 ``!net f l. (f --> l) net <=> ((\x. f(x) - l) --> 0) net``, 6357 SIMP_TAC arith_ss [LIM, dist, REAL_SUB_RZERO]); 6358 6359val LIM_NULL_ABS = store_thm ("LIM_NULL_ABS", 6360 ``!net f. (f --> 0) net <=> ((\x. (abs(f x))) --> 0) net``, 6361 SIMP_TAC std_ss [LIM, dist, REAL_SUB_RZERO, ABS_ABS]); 6362 6363val LIM_NULL_CMUL_EQ = store_thm ("LIM_NULL_CMUL_EQ", 6364 ``!net f c. 6365 ~(c = &0) ==> (((\x. c * f x) --> 0) net <=> (f --> 0) net)``, 6366 METIS_TAC[LIM_CMUL_EQ, REAL_MUL_RZERO]); 6367 6368val LIM_NULL_CMUL = store_thm ("LIM_NULL_CMUL", 6369 ``!net f c. (f --> 0) net ==> ((\x. c * f x) --> 0) net``, 6370 REPEAT GEN_TAC THEN ASM_CASES_TAC ``c = &0:real`` THEN 6371 ASM_SIMP_TAC std_ss [LIM_NULL_CMUL_EQ, REAL_MUL_LZERO, LIM_CONST]); 6372 6373val LIM_NULL_ADD = store_thm ("LIM_NULL_ADD", 6374 ``!net f g:'a->real. 6375 (f --> 0) net /\ (g --> 0) net 6376 ==> ((\x. f x + g x) --> 0) net``, 6377 REPEAT GEN_TAC THEN 6378 DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN 6379 REWRITE_TAC[REAL_ADD_LID]); 6380 6381val LIM_NULL_SUB = store_thm ("LIM_NULL_SUB", 6382 ``!net f g:'a->real. 6383 (f --> 0) net /\ (g --> 0) net 6384 ==> ((\x. f x - g x) --> 0) net``, 6385 REPEAT GEN_TAC THEN 6386 DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN 6387 REWRITE_TAC[REAL_SUB_RZERO]); 6388 6389val LIM_NULL_COMPARISON = store_thm ("LIM_NULL_COMPARISON", 6390 ``!net f g. eventually (\x. abs(f x) <= g x) net /\ 6391 ((\x. (g x)) --> 0) net 6392 ==> (f --> 0) net``, 6393 REPEAT GEN_TAC THEN SIMP_TAC std_ss [tendsto, RIGHT_AND_FORALL_THM] THEN 6394 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 6395 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [GSYM EVENTUALLY_AND] THEN 6396 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 6397 SIMP_TAC arith_ss [dist, REAL_SUB_RZERO] THEN REAL_ARITH_TAC); 6398 6399val LIM_COMPONENT = store_thm ("LIM_COMPONENT", 6400 ``!net f i l:real. (f --> l) net 6401 ==> ((\a. f(a)) --> l) net``, 6402 REWRITE_TAC[LIM, dist] THEN 6403 METIS_TAC[REAL_LET_TRANS]); 6404 6405val LIM_TRANSFORM_BOUND = store_thm ("LIM_TRANSFORM_BOUND", 6406 ``!f g. eventually (\n. abs(f n) <= abs(g n)) net /\ (g --> 0) net 6407 ==> (f --> 0) net``, 6408 REPEAT GEN_TAC THEN 6409 SIMP_TAC std_ss [tendsto, RIGHT_AND_FORALL_THM] THEN 6410 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 6411 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [GSYM EVENTUALLY_AND] THEN 6412 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 6413 SIMP_TAC arith_ss [dist, REAL_SUB_RZERO] THEN REAL_ARITH_TAC); 6414 6415val LIM_NULL_CMUL_BOUNDED = store_thm ("LIM_NULL_CMUL_BOUNDED", 6416 ``!f g:'a->real B. 6417 eventually (\a. (g a = 0) \/ abs(f a) <= B) net /\ 6418 (g --> 0) net 6419 ==> ((\n. f n * g n) --> 0) net``, 6420 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN STRIP_TAC THEN 6421 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6422 FIRST_X_ASSUM(MP_TAC o SPEC ``e / (abs B + &1:real)``) THEN 6423 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_ARITH ``&0 < abs x + &1:real``] THEN 6424 UNDISCH_TAC ``eventually 6425 (\(a :'a). ((g :'a -> real) a = (0 :real)) \/ 6426 abs ((f :'a -> real) a) <= (B :real)) (net :'a net)`` THEN 6427 REWRITE_TAC[AND_IMP_INTRO, GSYM EVENTUALLY_AND] THEN 6428 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MP) THEN 6429 SIMP_TAC std_ss [dist, REAL_SUB_RZERO, o_THM, ABS_MUL] THEN 6430 MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC ``x:'a`` THEN BETA_TAC THEN 6431 ASM_CASES_TAC ``(g:'a->real) x = 0`` THEN 6432 ASM_SIMP_TAC std_ss [ABS_0, REAL_MUL_RZERO] THEN 6433 STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 6434 EXISTS_TAC ``B * e / (abs B + &1:real)`` THEN CONJ_TAC THENL 6435 [ONCE_REWRITE_TAC [real_div] THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN 6436 MATCH_MP_TAC REAL_LE_MUL2 THEN ONCE_REWRITE_TAC [GSYM real_div] THEN 6437 ASM_SIMP_TAC std_ss [REAL_ABS_POS, REAL_LT_IMP_LE], ALL_TAC] THEN 6438 SIMP_TAC std_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``&0 < abs x + &1:real``] THEN 6439 MATCH_MP_TAC(REAL_ARITH 6440 ``e * B <= e * abs B /\ &0 < e ==> B * e < e * (abs B + &1:real)``) THEN 6441 ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN REAL_ARITH_TAC); 6442 6443val LIM_SUM = store_thm ("LIM_SUM", 6444 ``!net f:'a->'b->real l s. 6445 FINITE s /\ (!i. i IN s ==> ((f i) --> (l i)) net) 6446 ==> ((\x. sum s (\i. f i x)) --> sum s l) net``, 6447 GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 6448 KNOW_TAC ``!s:'a->bool. ( (!(i :'a). i IN s ==> 6449 ((f :'a -> 'b -> real) i --> (l :'a -> real) i) (net :'b net)) ==> 6450 ((\(x :'b). sum s (\(i :'a). f i x)) --> sum s l) net) = 6451 (\s. (!(i :'a). i IN s ==> 6452 ((f :'a -> 'b -> real) i --> (l :'a -> real) i) (net :'b net)) ==> 6453 ((\(x :'b). sum s (\(i :'a). f i x)) --> sum s l) net) s`` THENL 6454 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 6455 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 6456 SIMP_TAC std_ss [SUM_CLAUSES, LIM_CONST, LIM_ADD, IN_INSERT, ETA_AX] THEN 6457 METIS_TAC [SUM_CLAUSES, LIM_CONST, LIM_ADD, IN_INSERT, ETA_AX]); 6458 6459val LIM_NULL_SUM = store_thm ("LIM_NULL_SUM", 6460 ``!net f:'a->'b->real s. 6461 FINITE s /\ (!a. a IN s ==> ((\x. f x a) --> 0) net) 6462 ==> ((\x. sum s (f x)) --> 0) net``, 6463 REPEAT GEN_TAC THEN 6464 ONCE_REWRITE_TAC [METIS [] ``!a. (\x. f x a) = (\a. (\x. f x a)) a``] THEN 6465 ONCE_REWRITE_TAC [METIS [] ``0:real = (\a. 0) (a:'b)``] THEN 6466 DISCH_THEN(MP_TAC o MATCH_MP LIM_SUM) THEN BETA_TAC THEN 6467 ONCE_REWRITE_TAC [METIS [] ``!i. (\i. f x i) = (\i. f x) i``] THEN 6468 METIS_TAC [SUM_0, ETA_AX]); 6469 6470(* ------------------------------------------------------------------------- *) 6471(* Deducing things about the limit from the elements. *) 6472(* ------------------------------------------------------------------------- *) 6473 6474val LIM_IN_CLOSED_SET = store_thm ("LIM_IN_CLOSED_SET", 6475 ``!net f:'a->real s l. 6476 closed s /\ eventually (\x. f(x) IN s) net /\ 6477 ~(trivial_limit net) /\ (f --> l) net 6478 ==> l IN s``, 6479 REWRITE_TAC[closed_def] THEN REPEAT STRIP_TAC THEN 6480 MATCH_MP_TAC(SET_RULE ``~(x IN (UNIV DIFF s)) ==> x IN s``) THEN 6481 DISCH_TAC THEN UNDISCH_TAC ``open (univ(:real) DIFF s)`` THEN 6482 GEN_REWR_TAC LAND_CONV [OPEN_CONTAINS_BALL] THEN DISCH_TAC THEN 6483 POP_ASSUM (MP_TAC o Q.SPEC `l:real`) THEN 6484 KNOW_TAC ``~(?e. &0 < e /\ (!x. dist (l,x) < e ==> 6485 x IN univ(:real) /\ ~(x IN s)))`` THENL 6486 [ALL_TAC, ASM_SIMP_TAC std_ss [SUBSET_DEF, IN_BALL, IN_DIFF, IN_UNION]] THEN 6487 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 6488 UNDISCH_TAC ``((f:'a->real) --> l) net`` THEN GEN_REWR_TAC LAND_CONV [tendsto] THEN 6489 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 6490 UNDISCH_TAC ``eventually (\x. (f:'a->real) x IN s) net`` THEN 6491 ASM_REWRITE_TAC[GSYM EVENTUALLY_AND, TAUT `a ==> ~b <=> ~(a /\ b)`] THEN 6492 MATCH_MP_TAC NOT_EVENTUALLY THEN ASM_MESON_TAC[DIST_SYM]); 6493 6494(* ------------------------------------------------------------------------- *) 6495(* Need to prove closed(cball(x,e)) before deducing this as a corollary. *) 6496(* ------------------------------------------------------------------------- *) 6497 6498val LIM_ABS_UBOUND = store_thm ("LIM_ABS_UBOUND", 6499 ``!net:('a)net f (l:real) b. 6500 ~(trivial_limit net) /\ (f --> l) net /\ 6501 eventually (\x. abs(f x) <= b) net 6502 ==> abs(l) <= b``, 6503 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6504 ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6505 ASM_REWRITE_TAC[eventually] THEN 6506 STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN 6507 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN 6508 SUBGOAL_THEN 6509 ``?x:'a. dist(f(x):real,l) < abs(l:real) - b /\ abs(f x) <= b`` 6510 (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET], ALL_TAC] THEN 6511 REWRITE_TAC[REAL_NOT_LT, REAL_LE_SUB_RADD, DE_MORGAN_THM, dist] THEN 6512 REAL_ARITH_TAC); 6513 6514val LIM_ABS_LBOUND = store_thm ("LIM_ABS_LBOUND", 6515 ``!net:('a)net f (l:real) b. 6516 ~(trivial_limit net) /\ (f --> l) net /\ 6517 eventually (\x. b <= abs(f x)) net 6518 ==> b <= abs(l)``, 6519 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6520 ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6521 ASM_REWRITE_TAC[eventually] THEN 6522 STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN 6523 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN 6524 SUBGOAL_THEN 6525 ``?x:'a. dist(f(x):real,l) < b - abs(l:real) /\ b <= abs(f x)`` 6526 (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET], ALL_TAC] THEN 6527 REWRITE_TAC[REAL_NOT_LT, REAL_LE_SUB_RADD, DE_MORGAN_THM, dist] THEN 6528 REAL_ARITH_TAC); 6529 6530(* ------------------------------------------------------------------------- *) 6531(* Uniqueness of the limit, when nontrivial. *) 6532(* ------------------------------------------------------------------------- *) 6533 6534val LIM_UNIQUE = store_thm ("LIM_UNIQUE", 6535 ``!net:('a)net f l:real l'. 6536 ~(trivial_limit net) /\ (f --> l) net /\ (f --> l') net ==> (l = l')``, 6537 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6538 DISCH_THEN(ASSUME_TAC o REWRITE_RULE[REAL_SUB_REFL] o MATCH_MP LIM_SUB) THEN 6539 SUBGOAL_THEN ``!e. &0 < e ==> abs(l:real - l') <= e`` MP_TAC THENL 6540 [GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC LIM_ABS_UBOUND THEN 6541 MAP_EVERY EXISTS_TAC [``net:('a)net``, ``\x:'a. 0:real``] THEN 6542 ASM_SIMP_TAC std_ss [ABS_0, REAL_LT_IMP_LE, eventually] THEN 6543 ASM_MESON_TAC[trivial_limit], 6544 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN REWRITE_TAC[DIST_NZ, dist] THEN 6545 DISCH_TAC THEN DISCH_THEN(MP_TAC o SPEC ``abs(l - l':real) / &2``) THEN 6546 ASM_SIMP_TAC arith_ss [REAL_LT_RDIV_EQ, REAL_LE_RDIV_EQ, REAL_LT] THEN 6547 UNDISCH_TAC ``&0 < abs(l - l':real)`` THEN REAL_ARITH_TAC]); 6548 6549val TENDSTO_LIM = store_thm ("TENDSTO_LIM", 6550 ``!net f l. ~(trivial_limit net) /\ (f --> l) net ==> (lim net f = l)``, 6551 REWRITE_TAC[lim_def] THEN METIS_TAC[LIM_UNIQUE]); 6552 6553val LIM_CONST_EQ = store_thm ("LIM_CONST_EQ", 6554 ``!net:('a net) c d:real. 6555 ((\x. c) --> d) net <=> trivial_limit net \/ (c = d)``, 6556 REPEAT GEN_TAC THEN 6557 ASM_CASES_TAC ``trivial_limit (net:'a net)`` THEN ASM_REWRITE_TAC[] THENL 6558 [ASM_REWRITE_TAC[LIM], ALL_TAC] THEN 6559 EQ_TAC THEN SIMP_TAC std_ss [LIM_CONST] THEN DISCH_TAC THEN 6560 MATCH_MP_TAC(SPEC ``net:'a net`` LIM_UNIQUE) THEN 6561 EXISTS_TAC ``(\x. c):'a->real`` THEN ASM_REWRITE_TAC[LIM_CONST]); 6562 6563(* ------------------------------------------------------------------------- *) 6564(* Some unwieldy but occasionally useful theorems about uniform limits. *) 6565(* ------------------------------------------------------------------------- *) 6566 6567val UNIFORM_LIM_ADD = store_thm ("UNIFORM_LIM_ADD", 6568 ``!net:('a)net P f g l m. 6569 (!e:real. &0 < e 6570 ==> eventually (\x. !n:'b. P n ==> abs(f n x - l n) < e) net) /\ 6571 (!e:real. &0 < e 6572 ==> eventually (\x. !n. P n ==> abs(g n x - m n) < e) net) 6573 ==> !e. &0 < e ==> eventually (\x. !n. P n 6574 ==> abs((f n x + g n x) - (l n + m n)) < e) net``, 6575 REPEAT GEN_TAC THEN SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN DISCH_TAC THEN 6576 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6577 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 6578 ASM_REWRITE_TAC[REAL_LT_HALF1, GSYM EVENTUALLY_AND] THEN 6579 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 6580 GEN_TAC THEN REWRITE_TAC[GSYM FORALL_AND_THM] THEN 6581 BETA_TAC THEN STRIP_TAC THEN X_GEN_TAC ``n:'b`` THEN 6582 POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN 6583 ASM_CASES_TAC ``(P:'b->bool) n`` THEN ASM_REWRITE_TAC[] THEN 6584 REPEAT STRIP_TAC THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 6585 REWRITE_TAC [REAL_ADD2_SUB2] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 6586 EXISTS_TAC ``abs ((f:'b->'a->real) n x - l n) + abs (-g n x - -m n):real`` THEN 6587 ASM_REAL_ARITH_TAC); 6588 6589val UNIFORM_LIM_SUB = store_thm ("UNIFORM_LIM_SUB", 6590 ``!net:('a)net P f g l m. 6591 (!e:real. &0 < e 6592 ==> eventually (\x. !n:'b. P n ==> abs(f n x - l n) < e) net) /\ 6593 (!e:real. &0 < e 6594 ==> eventually (\x. !n. P n ==> abs(g n x - m n) < e) net) 6595 ==> !e. &0 < e ==> eventually (\x. !n. P n 6596 ==> abs((f n x - g n x) - (l n - m n)) < e) net``, 6597 REPEAT GEN_TAC THEN SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN DISCH_TAC THEN 6598 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6599 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 6600 ASM_REWRITE_TAC[REAL_LT_HALF1, GSYM EVENTUALLY_AND] THEN 6601 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 6602 GEN_TAC THEN REWRITE_TAC[GSYM FORALL_AND_THM] THEN 6603 BETA_TAC THEN STRIP_TAC THEN X_GEN_TAC ``n:'b`` THEN 6604 POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN 6605 ASM_CASES_TAC ``(P:'b->bool) n`` THEN ASM_REWRITE_TAC[] THEN 6606 REPEAT STRIP_TAC THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 6607 REWRITE_TAC [REAL_ARITH ``abs (f n x - g n x - (l n - m n)):real = 6608 abs (f n x + -g n x - (l n + -m n))``] THEN 6609 REWRITE_TAC [REAL_ADD2_SUB2] THEN 6610 MATCH_MP_TAC REAL_LET_TRANS THEN 6611 EXISTS_TAC ``abs ((f:'b->'a->real) n x - l n) + abs (-g n x - -m n):real`` THEN 6612 REWRITE_TAC [ABS_TRIANGLE] THEN MATCH_MP_TAC REAL_LT_ADD2 THEN 6613 ASM_REWRITE_TAC [REAL_ARITH ``-a - -b = - (a - b):real``, ABS_NEG]); 6614 6615(* ------------------------------------------------------------------------- *) 6616(* Limit under bilinear function, uniform version first. *) 6617(* ------------------------------------------------------------------------- *) 6618 6619val UNIFORM_LIM_BILINEAR = store_thm ("UNIFORM_LIM_BILINEAR", 6620 ``!net:('a)net P (h:real->real->real) f g l m b1 b2. 6621 bilinear h /\ 6622 eventually (\x. !n. P n ==> abs(l n) <= b1) net /\ 6623 eventually (\x. !n. P n ==> abs(m n) <= b2) net /\ 6624 (!e. &0 < e 6625 ==> eventually (\x. !n:'b. P n ==> abs(f n x - l n) < e) net) /\ 6626 (!e. &0 < e 6627 ==> eventually (\x. !n. P n ==> abs(g n x - m n) < e) net) 6628 ==> !e. &0 < e 6629 ==> eventually (\x. !n. P n 6630 ==> abs(h (f n x) (g n x) - h (l n) (m n)) < e) net``, 6631 REPEAT GEN_TAC THEN 6632 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 6633 FIRST_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o MATCH_MP 6634 BILINEAR_BOUNDED_POS) THEN 6635 SIMP_TAC std_ss [GSYM FORALL_AND_THM, RIGHT_AND_FORALL_THM] THEN DISCH_TAC THEN 6636 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6637 FIRST_X_ASSUM(MP_TAC o SPEC 6638 ``min (abs b2 + &1:real) (e / &2 / (B * (abs b1 + abs b2 + &2)))``) THEN 6639 ASM_SIMP_TAC std_ss [REAL_LT_HALF1, REAL_LT_DIV, REAL_LT_MUL, REAL_LT_MIN, 6640 REAL_ARITH ``&0 < abs x + &1:real``, 6641 REAL_ARITH ``&0 < abs x + abs y + &2:real``] THEN 6642 REWRITE_TAC[GSYM EVENTUALLY_AND] THEN BETA_TAC THEN 6643 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN 6644 X_GEN_TAC ``x:'a`` THEN SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN 6645 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN 6646 ASM_CASES_TAC ``(P:'b->bool) n`` THEN ASM_REWRITE_TAC[] THEN 6647 STRIP_TAC THEN 6648 ONCE_REWRITE_TAC[REAL_ARITH 6649 ``h a b - h c d :real = (h a b - h a d) + (h a d - h c d)``] THEN 6650 ASM_SIMP_TAC std_ss [GSYM BILINEAR_LSUB, GSYM BILINEAR_RSUB] THEN 6651 MATCH_MP_TAC ABS_TRIANGLE_LT THEN 6652 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP 6653 (MESON[REAL_LE_ADD2, REAL_LET_TRANS] 6654 ``(!x y. abs(h x y:real) <= B * abs x * abs y) 6655 ==> B * abs a * abs b + B * abs c * abs d < e 6656 ==> abs(h a b) + abs(h c d) < e``)) THEN 6657 REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN 6658 MATCH_MP_TAC(METIS [REAL_LT_ADD2, REAL_HALF_DOUBLE, REAL_MUL_SYM] 6659 ``x * B < e / &2:real /\ y * B < e / &2:real ==> B * x + B * y < e``) THEN 6660 CONJ_TAC THEN ASM_SIMP_TAC std_ss [GSYM REAL_LT_RDIV_EQ] THENL 6661 [ONCE_REWRITE_TAC[REAL_MUL_SYM], ALL_TAC] THEN 6662 MATCH_MP_TAC REAL_LET_TRANS THEN 6663 EXISTS_TAC ``e / &2 / (B * (abs b1 + abs b2 + &2)) * 6664 (abs b1 + abs b2 + &1:real)`` THEN 6665 (CONJ_TAC THENL 6666 [MATCH_MP_TAC REAL_LE_MUL2 THEN 6667 ASM_SIMP_TAC std_ss [ABS_POS, REAL_LT_IMP_LE] THEN 6668 ASM_SIMP_TAC std_ss [REAL_ARITH ``a <= b2 ==> a <= abs b1 + abs b2 + &1:real``] THEN 6669 ASM_MESON_TAC[REAL_ARITH 6670 ``abs(f - l:real) < abs b2 + &1 /\ abs(l) <= b1 6671 ==> abs(f) <= abs b1 + abs b2 + &1``], 6672 ONCE_REWRITE_TAC[real_div] THEN 6673 KNOW_TAC ``(abs b1 + abs b2 + 2) <> 0:real`` THENL 6674 [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN 6675 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``2:real`` THEN 6676 REWRITE_TAC [REAL_LE_ADDL] THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN 6677 ONCE_REWRITE_TAC [REAL_ARITH ``0 = 0 + 0:real``] THEN MATCH_MP_TAC REAL_LE_ADD2 THEN 6678 REWRITE_TAC [ABS_POS], ALL_TAC] THEN DISCH_TAC THEN 6679 ASM_SIMP_TAC arith_ss [REAL_LT_LMUL, REAL_LT_HALF1, GSYM REAL_MUL_ASSOC, 6680 REAL_INV_MUL, REAL_LT_IMP_NE] THEN REWRITE_TAC [REAL_MUL_ASSOC] THEN 6681 REWRITE_TAC[METIS [real_div, REAL_MUL_RID, REAL_ARITH ``a * b * c = a * c * b:real``] 6682 ``B * inv x * y < B <=> B * y / x < B * &1:real``] THEN 6683 ASM_SIMP_TAC arith_ss [REAL_LT_INV_EQ, REAL_LT_LMUL, REAL_LT_LDIV_EQ, REAL_MUL_RID, 6684 REAL_ARITH ``&0 < abs x + abs y + &2:real``] THEN 6685 REAL_ARITH_TAC])); 6686 6687val LIM_BILINEAR = store_thm ("LIM_BILINEAR", 6688 ``!net:('a)net (h:real->real->real) f g l m. 6689 (f --> l) net /\ (g --> m) net /\ bilinear h 6690 ==> ((\x. h (f x) (g x)) --> (h l m)) net``, 6691 REPEAT STRIP_TAC THEN 6692 MP_TAC(ISPECL 6693 [``net:('a)net``, ``\x:one. T``, ``h:real->real->real``, 6694 ``\n:one. (f:'a->real)``, ``\n:one. (g:'a->real)``, 6695 ``\n:one. (l:real)``, ``\n:one. (m:real)``, 6696 ``abs(l:real)``, ``abs(m:real)``] 6697 UNIFORM_LIM_BILINEAR) THEN 6698 ASM_REWRITE_TAC[REAL_LE_REFL, EVENTUALLY_TRUE] THEN 6699 ASM_SIMP_TAC std_ss [GSYM dist, GSYM tendsto]); 6700 6701(* ------------------------------------------------------------------------- *) 6702(* These are special for limits out of the same vector space. *) 6703(* ------------------------------------------------------------------------- *) 6704 6705val LIM_WITHIN_ID = store_thm ("LIM_WITHIN_ID", 6706 ``!a s. ((\x. x) --> a) (at a within s)``, 6707 REWRITE_TAC[LIM_WITHIN] THEN MESON_TAC[]); 6708 6709val LIM_AT_ID = store_thm ("LIM_AT_ID", 6710 ``!a. ((\x. x) --> a) (at a)``, 6711 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN REWRITE_TAC[LIM_WITHIN_ID]); 6712 6713val LIM_AT_ZERO = store_thm ("LIM_AT_ZERO", 6714 ``!f:real->real l a. 6715 (f --> l) (at a) <=> ((\x. f(a + x)) --> l) (at(0))``, 6716 REPEAT GEN_TAC THEN REWRITE_TAC[LIM_AT] THEN 6717 AP_TERM_TAC THEN ABS_TAC THEN 6718 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN 6719 AP_TERM_TAC THEN ABS_TAC THEN 6720 ASM_CASES_TAC ``&0 < d:real`` THEN ASM_REWRITE_TAC[] THEN 6721 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``x:real`` THENL 6722 [FIRST_X_ASSUM(MP_TAC o SPEC ``a + x:real``) THEN 6723 SIMP_TAC std_ss [dist, REAL_ADD_SUB, REAL_SUB_RZERO], 6724 FIRST_X_ASSUM(MP_TAC o SPEC ``x - a:real``) THEN 6725 SIMP_TAC std_ss [dist, REAL_SUB_RZERO, REAL_SUB_ADD2]]); 6726 6727(* ------------------------------------------------------------------------- *) 6728(* It's also sometimes useful to extract the limit point from the net. *) 6729(* ------------------------------------------------------------------------- *) 6730 6731val netlimit = new_definition ("netlimit", 6732 ``netlimit net = @a. !x. ~(netord net x a)``); 6733 6734val NETLIMIT_WITHIN = store_thm ("NETLIMIT_WITHIN", 6735 ``!a:real s. ~(trivial_limit (at a within s)) 6736 ==> (netlimit (at a within s) = a)``, 6737 REWRITE_TAC[trivial_limit, netlimit, AT, WITHIN, DE_MORGAN_THM] THEN 6738 REPEAT STRIP_TAC THEN MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN 6739 SUBGOAL_THEN 6740 ``!x:real. ~(&0 < dist(x,a) /\ dist(x,a) <= dist(a,a) /\ x IN s)`` 6741 ASSUME_TAC THENL 6742 [ASM_MESON_TAC[DIST_REFL, REAL_NOT_LT], ASM_MESON_TAC[]]); 6743 6744val NETLIMIT_AT = store_thm ("NETLIMIT_AT", 6745 ``!a. netlimit(at a) = a``, 6746 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 6747 MATCH_MP_TAC NETLIMIT_WITHIN THEN 6748 SIMP_TAC std_ss [TRIVIAL_LIMIT_AT, WITHIN_UNIV]); 6749 6750(* ------------------------------------------------------------------------- *) 6751(* Transformation of limit. *) 6752(* ------------------------------------------------------------------------- *) 6753 6754val LIM_TRANSFORM = store_thm ("LIM_TRANSFORM", 6755 ``!net f g l. 6756 ((\x. f x - g x) --> 0) net /\ (f --> l) net ==> (g --> l) net``, 6757 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN 6758 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN MATCH_MP_TAC EQ_IMPLIES THEN 6759 AP_THM_TAC THEN BINOP_TAC THEN SIMP_TAC std_ss [FUN_EQ_THM] THEN 6760 REAL_ARITH_TAC); 6761 6762val LIM_TRANSFORM_EVENTUALLY = store_thm ("LIM_TRANSFORM_EVENTUALLY", 6763 ``!net f g l. 6764 eventually (\x. f x = g x) net /\ (f --> l) net ==> (g --> l) net``, 6765 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN STRIP_TAC THEN 6766 KNOW_TAC ``((\ (x:'a). f x - g x) --> (0:real)) net`` THENL 6767 [METIS_TAC [LIM_EVENTUALLY], ALL_TAC] THEN 6768 METIS_TAC[LIM_TRANSFORM]); 6769 6770val LIM_TRANSFORM_WITHIN = store_thm ("LIM_TRANSFORM_WITHIN", 6771 ``!f g x s d. &0 < d /\ 6772 (!x'. x' IN s /\ &0 < dist(x',x) /\ dist(x',x) < d ==> (f(x') = g(x'))) /\ 6773 (f --> l) (at x within s) ==> (g --> l) (at x within s)``, 6774 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 6775 DISCH_TAC THEN DISCH_TAC THEN 6776 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] LIM_TRANSFORM) THEN 6777 REWRITE_TAC[LIM_WITHIN] THEN REPEAT STRIP_TAC THEN EXISTS_TAC ``d:real`` THEN 6778 ASM_SIMP_TAC std_ss [REAL_SUB_REFL, DIST_REFL]); 6779 6780val LIM_TRANSFORM_AT = store_thm ("LIM_TRANSFORM_AT", 6781 ``!f g x d. &0 < d /\ 6782 (!x'. &0 < dist(x',x) /\ dist(x',x) < d ==> (f(x') = g(x'))) /\ 6783 (f --> l) (at x) ==> (g --> l) (at x)``, 6784 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN MESON_TAC[LIM_TRANSFORM_WITHIN]); 6785 6786val LIM_TRANSFORM_EQ = store_thm ("LIM_TRANSFORM_EQ", 6787 ``!net f:'a->real g l. 6788 ((\x. f x - g x) --> 0) net ==> ((f --> l) net <=> (g --> l) net)``, 6789 REPEAT STRIP_TAC THEN EQ_TAC THEN 6790 DISCH_TAC THEN MATCH_MP_TAC LIM_TRANSFORM THENL 6791 [EXISTS_TAC ``f:'a->real`` THEN ASM_REWRITE_TAC[], 6792 EXISTS_TAC ``g:'a->real`` THEN ASM_REWRITE_TAC[] THEN 6793 ONCE_REWRITE_TAC[GSYM LIM_NEG_EQ] THEN BETA_TAC THEN 6794 ASM_REWRITE_TAC[REAL_NEG_SUB, REAL_NEG_0]]); 6795 6796val LIM_TRANSFORM_WITHIN_SET = store_thm ("LIM_TRANSFORM_WITHIN_SET", 6797 ``!f a s t. 6798 eventually (\x. x IN s <=> x IN t) (at a) 6799 ==> ((f --> l) (at a within s) <=> (f --> l) (at a within t))``, 6800 REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT, LIM_WITHIN] THEN 6801 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 6802 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6803 FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN 6804 DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN 6805 EXISTS_TAC ``min d k:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 6806 ASM_MESON_TAC[]); 6807 6808val LIM_TRANSFORM_WITHIN_SET_IMP = store_thm ("LIM_TRANSFORM_WITHIN_SET_IMP", 6809 ``!f l a s t. 6810 eventually (\x. x IN t ==> x IN s) (at a) /\ (f --> l) (at a within s) 6811 ==> (f --> l) (at a within t)``, 6812 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO, EVENTUALLY_AT, LIM_WITHIN] THEN 6813 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 6814 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6815 FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN 6816 DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN 6817 EXISTS_TAC ``min d k:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 6818 ASM_MESON_TAC[]); 6819 6820(* ------------------------------------------------------------------------- *) 6821(* Common case assuming being away from some crucial point like 0. *) 6822(* ------------------------------------------------------------------------- *) 6823 6824val LIM_TRANSFORM_AWAY_WITHIN = store_thm ("LIM_TRANSFORM_AWAY_WITHIN", 6825 ``!f:real->real g a b s. ~(a = b) /\ 6826 (!x. x IN s /\ ~(x = a) /\ ~(x = b) ==> (f(x) = g(x))) /\ 6827 (f --> l) (at a within s) ==> (g --> l) (at a within s)``, 6828 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN 6829 MAP_EVERY EXISTS_TAC [``f:real->real``, ``dist(a:real,b)``] THEN 6830 ASM_REWRITE_TAC[GSYM DIST_NZ] THEN X_GEN_TAC ``y:real`` THEN 6831 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 6832 ASM_MESON_TAC[DIST_SYM, REAL_LT_REFL]); 6833 6834val LIM_TRANSFORM_AWAY_AT = store_thm ("LIM_TRANSFORM_AWAY_AT", 6835 ``!f:real->real g a b. ~(a = b) /\ 6836 (!x. ~(x = a) /\ ~(x = b) ==> (f(x) = g(x))) /\ 6837 (f --> l) (at a) ==> (g --> l) (at a)``, 6838 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 6839 MESON_TAC[LIM_TRANSFORM_AWAY_WITHIN]); 6840 6841(* ------------------------------------------------------------------------- *) 6842(* Alternatively, within an open set. *) 6843(* ------------------------------------------------------------------------- *) 6844 6845val LIM_TRANSFORM_WITHIN_OPEN = store_thm ("LIM_TRANSFORM_WITHIN_OPEN", 6846 ``!f g:real->real s a l. open s /\ a IN s /\ 6847 (!x. x IN s /\ ~(x = a) ==> (f x = g x)) /\ 6848 (f --> l) (at a) ==> (g --> l) (at a)``, 6849 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_AT THEN 6850 EXISTS_TAC ``f:real->real`` THEN ASM_REWRITE_TAC[] THEN 6851 UNDISCH_TAC ``open s`` THEN GEN_REWR_TAC LAND_CONV [OPEN_CONTAINS_BALL] THEN 6852 DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN ASM_REWRITE_TAC[] THEN 6853 STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN POP_ASSUM MP_TAC THEN 6854 REWRITE_TAC[SUBSET_DEF, IN_BALL] THEN ASM_MESON_TAC[DIST_NZ, DIST_SYM]); 6855 6856val LIM_TRANSFORM_WITHIN_OPEN_IN = store_thm ("LIM_TRANSFORM_WITHIN_OPEN_IN", 6857 ``!f g:real->real s t a l. 6858 open_in (subtopology euclidean t) s /\ a IN s /\ 6859 (!x. x IN s /\ ~(x = a) ==> (f x = g x)) /\ 6860 (f --> l) (at a within t) ==> (g --> l) (at a within t)``, 6861 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN 6862 EXISTS_TAC ``f:real->real`` THEN ASM_REWRITE_TAC[] THEN 6863 UNDISCH_TAC ``open_in (subtopology euclidean t) s`` THEN 6864 GEN_REWR_TAC LAND_CONV [OPEN_IN_CONTAINS_BALL] THEN 6865 DISCH_THEN(MP_TAC o SPEC ``a:real`` o CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN 6866 STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN POP_ASSUM MP_TAC THEN 6867 REWRITE_TAC[SUBSET_DEF, IN_INTER, IN_BALL] THEN ASM_MESON_TAC[DIST_NZ, DIST_SYM]); 6868 6869(* ------------------------------------------------------------------------- *) 6870(* Another quite common idiom of an explicit conditional in a sequence. *) 6871(* ------------------------------------------------------------------------- *) 6872 6873val LIM_CASES_FINITE_SEQUENTIALLY = store_thm ("LIM_CASES_FINITE_SEQUENTIALLY", 6874 ``!f g l. FINITE {n | P n} 6875 ==> (((\n. if P n then f n else g n) --> l) sequentially <=> 6876 (g --> l) sequentially)``, 6877 REPEAT STRIP_TAC THEN EQ_TAC THEN 6878 MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] LIM_TRANSFORM_EVENTUALLY) THEN 6879 FIRST_ASSUM(MP_TAC o SPEC ``\n:num. n`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN 6880 SIMP_TAC std_ss [GSPECIFICATION, LEFT_IMP_EXISTS_THM] THEN 6881 X_GEN_TAC ``N:num`` THEN DISCH_TAC THEN SIMP_TAC std_ss [EVENTUALLY_SEQUENTIALLY] THEN 6882 EXISTS_TAC ``N + 1:num`` THEN 6883 METIS_TAC[ARITH_PROVE ``~(x <= n:num /\ n + 1 <= x)``]); 6884 6885val lemma = prove ( 6886 ``(if p then x else y) = (if ~p then y else x)``, 6887 RW_TAC std_ss []); 6888 6889val LIM_CASES_COFINITE_SEQUENTIALLY = store_thm ("LIM_CASES_COFINITE_SEQUENTIALLY", 6890 ``!f g l. FINITE {n | ~P n} 6891 ==> (((\n. if P n then f n else g n) --> l) sequentially <=> 6892 (f --> l) sequentially)``, 6893 ONCE_REWRITE_TAC[lemma] THEN 6894 SIMP_TAC std_ss [LIM_CASES_FINITE_SEQUENTIALLY]); 6895 6896val LIM_CASES_SEQUENTIALLY = store_thm ("LIM_CASES_SEQUENTIALLY", 6897 ``!f g l m. (((\n. if m <= n then f n else g n) --> l) sequentially <=> 6898 (f --> l) sequentially) /\ 6899 (((\n. if m < n then f n else g n) --> l) sequentially <=> 6900 (f --> l) sequentially) /\ 6901 (((\n. if n <= m then f n else g n) --> l) sequentially <=> 6902 (g --> l) sequentially) /\ 6903 (((\n. if n < m then f n else g n) --> l) sequentially <=> 6904 (g --> l) sequentially)``, 6905 SIMP_TAC std_ss [LIM_CASES_FINITE_SEQUENTIALLY, LIM_CASES_COFINITE_SEQUENTIALLY, 6906 NOT_LESS, NOT_LESS_EQUAL, FINITE_NUMSEG_LT, FINITE_NUMSEG_LE]); 6907 6908(* ------------------------------------------------------------------------- *) 6909(* A congruence rule allowing us to transform limits assuming not at point. *) 6910(* ------------------------------------------------------------------------- *) 6911 6912val LIM_CONG_WITHIN = store_thm ("LIM_CONG_WITHIN", 6913 ``(!x. ~(x = a) ==> (f x = g x)) 6914 ==> (((\x. f x) --> l) (at a within s) <=> ((g --> l) (at a within s)))``, 6915 REWRITE_TAC[LIM_WITHIN, GSYM DIST_NZ] THEN SIMP_TAC std_ss []); 6916 6917val LIM_CONG_AT = store_thm ("LIM_CONG_AT", 6918 ``(!x. ~(x = a) ==> (f x = g x)) 6919 ==> (((\x. f x) --> l) (at a) <=> ((g --> l) (at a)))``, 6920 REWRITE_TAC[LIM_AT, GSYM DIST_NZ] THEN SIMP_TAC std_ss []); 6921 6922(* ------------------------------------------------------------------------- *) 6923(* Useful lemmas on closure and set of possible sequential limits. *) 6924(* ------------------------------------------------------------------------- *) 6925 6926val CLOSURE_SEQUENTIAL = store_thm ("CLOSURE_SEQUENTIAL", 6927 ``!s l:real. 6928 l IN closure(s) <=> ?x. (!n. x(n) IN s) /\ (x --> l) sequentially``, 6929 SIMP_TAC std_ss [closure, IN_UNION, LIMPT_SEQUENTIAL, GSPECIFICATION, IN_DELETE] THEN 6930 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT 6931 `((b ==> c) /\ (~a /\ c ==> b)) /\ (a ==> c) ==> (a \/ b <=> c)`) THEN 6932 CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN DISCH_TAC THEN 6933 EXISTS_TAC ``\n:num. l:real`` THEN ASM_REWRITE_TAC[LIM_CONST]); 6934 6935val CLOSED_CONTAINS_SEQUENTIAL_LIMIT = store_thm ("CLOSED_CONTAINS_SEQUENTIAL_LIMIT", 6936 ``!s x l:real. 6937 closed s /\ (!n. x n IN s) /\ (x --> l) sequentially ==> l IN s``, 6938 MESON_TAC[CLOSURE_SEQUENTIAL, CLOSURE_CLOSED]); 6939 6940val CLOSED_SEQUENTIAL_LIMITS = store_thm ("CLOSED_SEQUENTIAL_LIMITS", 6941 ``!s. closed s <=> 6942 !x l. (!n. x(n) IN s) /\ (x --> l) sequentially ==> l IN s``, 6943 MESON_TAC[CLOSURE_SEQUENTIAL, CLOSURE_CLOSED, 6944 CLOSED_LIMPT, LIMPT_SEQUENTIAL, IN_DELETE]); 6945 6946val CLOSED_APPROACHABLE = store_thm ("CLOSED_APPROACHABLE", 6947 ``!x s. closed s 6948 ==> ((!e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e) <=> x IN s)``, 6949 MESON_TAC[CLOSURE_CLOSED, CLOSURE_APPROACHABLE]); 6950 6951val IN_CLOSURE_DELETE = store_thm ("IN_CLOSURE_DELETE", 6952 ``!s x:real. x IN closure(s DELETE x) <=> x limit_point_of s``, 6953 SIMP_TAC std_ss [CLOSURE_APPROACHABLE, LIMPT_APPROACHABLE, IN_DELETE, CONJ_ASSOC]); 6954 6955val DENSE_IMP_PERFECT = store_thm ("DENSE_IMP_PERFECT", 6956 ``!s. (closure s = univ(:real)) ==> !x. x IN s ==> x limit_point_of s``, 6957 REPEAT STRIP_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN 6958 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 6959 KNOW_TAC ``~(!x'. ~(x' = x) /\ dist (x',x) < e ==> ~(x' IN s))`` THENL 6960 [ALL_TAC, METIS_TAC []] THEN DISCH_TAC THEN 6961 MP_TAC(ISPECL [``x:real``, ``e / &2:real``] REAL_CHOOSE_DIST) THEN 6962 KNOW_TAC ``~(?y. dist (x,y) = e / &2)`` THENL 6963 [ALL_TAC, ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE, REAL_LT_HALF1]] THEN 6964 DISCH_THEN(X_CHOOSE_TAC ``y:real``) THEN 6965 FIRST_ASSUM(MP_TAC o SPEC ``y:real`` o MATCH_MP (SET_RULE 6966 ``(s = UNIV) ==> !x. x IN s``)) THEN 6967 REWRITE_TAC[CLOSURE_APPROACHABLE] THEN 6968 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN 6969 ASM_SIMP_TAC std_ss [REAL_HALF, NOT_EXISTS_THM] THEN 6970 X_GEN_TAC ``z:real`` THEN FIRST_X_ASSUM(MP_TAC o SPEC ``z:real``) THEN 6971 ASM_CASES_TAC ``(z:real) IN s`` THEN ASM_REWRITE_TAC[] THEN 6972 SIMP_TAC std_ss [] THEN STRIP_TAC THENL 6973 [METIS_TAC [REAL_LE_LT, REAL_NOT_LT], ALL_TAC] THEN 6974 DISCH_TAC THEN UNDISCH_TAC ``~(dist (z,x) < e)`` THEN REWRITE_TAC [] THEN 6975 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN 6976 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``dist (z,y) + dist (y,x)`` THEN 6977 REWRITE_TAC [DIST_TRIANGLE] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN 6978 ASM_REWRITE_TAC [] THEN METIS_TAC [REAL_LT_RADD, DIST_SYM]); 6979 6980val DENSE_LIMIT_POINTS = store_thm ("DENSE_LIMIT_POINTS", 6981 ``!x. ({x | x limit_point_of s} = univ(:real)) <=> (closure s = univ(:real))``, 6982 GEN_TAC THEN EQ_TAC THENL [SIMP_TAC std_ss [closure] THEN SET_TAC[], DISCH_TAC] THEN 6983 FIRST_ASSUM(MP_TAC o MATCH_MP DENSE_IMP_PERFECT) THEN 6984 RULE_ASSUM_TAC(REWRITE_RULE[closure]) THEN ASM_SET_TAC[]); 6985 6986(* ------------------------------------------------------------------------- *) 6987(* Some other lemmas about sequences. *) 6988(* ------------------------------------------------------------------------- *) 6989 6990val SEQ_OFFSET = store_thm ("SEQ_OFFSET", 6991 ``!f l k. (f --> l) sequentially ==> ((\i. f(i + k)) --> l) sequentially``, 6992 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 6993 MESON_TAC[ARITH_PROVE ``N <= n ==> N <= n + k:num``]); 6994 6995val SEQ_OFFSET_NEG = store_thm ("SEQ_OFFSET_NEG", 6996 ``!f l k. (f --> l) sequentially ==> ((\i. f(i - k)) --> l) sequentially``, 6997 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 6998 MESON_TAC[ARITH_PROVE ``N + k <= n ==> N <= n - k:num``]); 6999 7000val SEQ_OFFSET_REV = store_thm ("SEQ_OFFSET_REV", 7001 ``!f l k. ((\i. f(i + k)) --> l) sequentially ==> (f --> l) sequentially``, 7002 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 7003 MESON_TAC[ARITH_PROVE ``N + k <= n ==> N <= n - k /\ ((n - k) + k = n:num)``]); 7004 7005val SEQ_HARMONIC_OFFSET = store_thm ("SEQ_HARMONIC_OFFSET", 7006 ``!a. ((\n. inv(&n + a)) --> 0) sequentially``, 7007 GEN_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN 7008 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 7009 ASSUME_TAC REAL_ARCH_INV THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 7010 ASM_REWRITE_TAC [] THEN DISCH_THEN (X_CHOOSE_THEN ``N:num`` STRIP_ASSUME_TAC) THEN 7011 X_CHOOSE_THEN ``M:num`` STRIP_ASSUME_TAC 7012 (SPEC ``-a:real`` SIMP_REAL_ARCH) THEN 7013 EXISTS_TAC ``M + N:num`` THEN REWRITE_TAC[DIST_0] THEN 7014 X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 7015 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``inv (&N:real)`` THEN 7016 KNOW_TAC ``(&n + a:real) <> 0`` THENL 7017 [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN 7018 UNDISCH_TAC ``-a <= &M:real`` THEN 7019 GEN_REWR_TAC LAND_CONV [GSYM REAL_LE_NEG] THEN REWRITE_TAC [REAL_NEG_NEG] THEN 7020 DISCH_TAC THEN FULL_SIMP_TAC arith_ss [GSYM REAL_LE, GSYM REAL_ADD] THEN 7021 KNOW_TAC ``&M + &N + (-&M) <= &n + a:real`` THENL 7022 [FULL_SIMP_TAC arith_ss [REAL_LE_ADD2], ALL_TAC] THEN 7023 REWRITE_TAC [GSYM real_sub] THEN ONCE_REWRITE_TAC [REAL_ADD_COMM] THEN 7024 REWRITE_TAC [REAL_ADD_SUB_ALT] THEN DISCH_TAC THEN 7025 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``&N:real`` THEN 7026 FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ], ALL_TAC] THEN DISCH_TAC THEN 7027 BETA_TAC THEN ASM_SIMP_TAC arith_ss [ABS_INV] THEN 7028 MATCH_MP_TAC REAL_LE_INV2 THEN FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ] THEN 7029 RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE, GSYM REAL_OF_NUM_ADD]) THEN 7030 ASM_REAL_ARITH_TAC); 7031 7032val SEQ_HARMONIC = store_thm ("SEQ_HARMONIC", 7033 ``((\n. inv(&n)) --> 0) sequentially``, 7034 MP_TAC(SPEC ``&0:real`` SEQ_HARMONIC_OFFSET) THEN REWRITE_TAC[REAL_ADD_RID]); 7035 7036(* ------------------------------------------------------------------------- *) 7037(* More properties of closed balls. *) 7038(* ------------------------------------------------------------------------- *) 7039 7040val CLOSED_CBALL = store_thm ("CLOSED_CBALL", 7041 ``!x:real e. closed(cball(x,e))``, 7042 REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS, IN_CBALL, dist] THEN 7043 GEN_TAC THEN GEN_TAC THEN X_GEN_TAC ``s:num->real`` THEN 7044 X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 7045 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_ABS_UBOUND) THEN 7046 EXISTS_TAC ``\n. x - (s:num->real) n`` THEN 7047 REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY, EVENTUALLY_SEQUENTIALLY] THEN 7048 ASM_SIMP_TAC std_ss [LIM_SUB, LIM_CONST, SEQUENTIALLY]); 7049 7050val IN_INTERIOR_CBALL = store_thm ("IN_INTERIOR_CBALL", 7051 ``!x s. x IN interior s <=> ?e. &0 < e /\ cball(x,e) SUBSET s``, 7052 SIMP_TAC std_ss [interior, GSPECIFICATION] THEN 7053 MESON_TAC[OPEN_CONTAINS_CBALL, SUBSET_TRANS, 7054 BALL_SUBSET_CBALL, CENTRE_IN_BALL, OPEN_BALL]); 7055 7056val LIMPT_BALL = store_thm ("LIMPT_BALL", 7057 ``!x:real y e. y limit_point_of ball(x,e) <=> &0 < e /\ y IN cball(x,e)``, 7058 REPEAT GEN_TAC THEN ASM_CASES_TAC ``&0 < e:real`` THENL 7059 [ALL_TAC, ASM_MESON_TAC[LIMPT_EMPTY, REAL_NOT_LT, BALL_EQ_EMPTY]] THEN 7060 ASM_REWRITE_TAC[] THEN EQ_TAC THENL 7061 [MESON_TAC[CLOSED_CBALL, CLOSED_LIMPT, LIMPT_SUBSET, BALL_SUBSET_CBALL], 7062 REWRITE_TAC[IN_CBALL, LIMPT_APPROACHABLE, IN_BALL]] THEN 7063 DISCH_TAC THEN X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN 7064 ASM_CASES_TAC ``y:real = x`` THEN ASM_REWRITE_TAC[DIST_NZ] THENL 7065 [MP_TAC(SPECL [``d:real``, ``e:real``] REAL_DOWN2) THEN 7066 ASM_REWRITE_TAC[] THEN 7067 GEN_MESON_TAC 0 40 1 [REAL_CHOOSE_DIST, DIST_SYM, REAL_LT_IMP_LE], 7068 ALL_TAC] THEN 7069 MP_TAC(SPECL [``abs(y:real - x)``, ``d:real``] REAL_DOWN2) THEN 7070 RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ, dist]) THEN ASM_REWRITE_TAC[] THEN 7071 DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN 7072 EXISTS_TAC ``(y:real) - (k / dist(y,x)) * (y - x)`` THEN 7073 REWRITE_TAC[dist, REAL_ARITH ``(y - c * z) - y = -c * z:real``] THEN 7074 ASM_SIMP_TAC std_ss [ABS_MUL, ABS_DIV, ABS_ABS, ABS_NEG, REAL_POS_NZ] THEN 7075 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN 7076 REWRITE_TAC[REAL_ARITH ``x - (y - k * (y - x)) = (&1 - k) * (x - y:real)``] THEN 7077 ASM_SIMP_TAC std_ss [REAL_ARITH ``&0 < k ==> &0 < abs k:real``, ABS_MUL] THEN 7078 ASM_SIMP_TAC std_ss [REAL_ARITH ``&0 < k /\ k < d ==> abs k < d:real``] THEN 7079 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``abs(x:real - y)`` THEN 7080 ASM_REWRITE_TAC[] THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN 7081 KNOW_TAC ``0:real < abs (x - y)`` THENL [ASM_MESON_TAC[ABS_SUB], ALL_TAC] THEN 7082 DISCH_TAC THEN ASM_SIMP_TAC std_ss [REAL_LT_RMUL] THEN 7083 MATCH_MP_TAC(REAL_ARITH ``&0 < k /\ k < &1 ==> abs(&1 - k) < &1:real``) THEN 7084 ASM_SIMP_TAC std_ss [REAL_LT_LDIV_EQ, REAL_LT_RDIV_EQ, REAL_MUL_LZERO, 7085 REAL_MUL_LID]); 7086 7087val CLOSURE_BALL = store_thm ("CLOSURE_BALL", 7088 ``!x:real e. &0 < e ==> (closure(ball(x,e)) = cball(x,e))``, 7089 SIMP_TAC std_ss [EXTENSION, closure, GSPECIFICATION, IN_UNION, LIMPT_BALL] THEN 7090 REWRITE_TAC[IN_BALL, IN_CBALL] THEN REAL_ARITH_TAC); 7091 7092val INTERIOR_BALL = store_thm ("INTERIOR_BALL", 7093 ``!a r. interior(ball(a,r)) = ball(a,r)``, 7094 SIMP_TAC std_ss [INTERIOR_OPEN, OPEN_BALL]); 7095 7096val INTERIOR_CBALL = store_thm ("INTERIOR_CBALL", 7097 ``!x:real e. interior(cball(x,e)) = ball(x,e)``, 7098 REPEAT GEN_TAC THEN ASM_CASES_TAC ``&0 <= e:real`` THENL 7099 [ALL_TAC, 7100 SUBGOAL_THEN ``(cball(x:real,e) = {}) /\ (ball(x:real,e) = {})`` 7101 (fn th => REWRITE_TAC[th, INTERIOR_EMPTY]) THEN 7102 REWRITE_TAC[IN_BALL, IN_CBALL, EXTENSION, NOT_IN_EMPTY] THEN 7103 CONJ_TAC THEN X_GEN_TAC ``y:real`` THEN 7104 MP_TAC(ISPECL [``x:real``, ``y:real``] DIST_POS_LE) THEN 7105 POP_ASSUM MP_TAC THEN REAL_ARITH_TAC] THEN 7106 MATCH_MP_TAC INTERIOR_UNIQUE THEN 7107 REWRITE_TAC[BALL_SUBSET_CBALL, OPEN_BALL] THEN 7108 X_GEN_TAC ``t:real->bool`` THEN 7109 SIMP_TAC std_ss [SUBSET_DEF, IN_CBALL, IN_BALL, REAL_LT_LE] THEN STRIP_TAC THEN 7110 X_GEN_TAC ``z:real`` THEN DISCH_TAC THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN 7111 UNDISCH_TAC ``open t`` THEN REWRITE_TAC [open_def] THEN 7112 DISCH_THEN(MP_TAC o SPEC ``z:real``) THEN 7113 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN ``d:real`` MP_TAC) THEN 7114 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 7115 ASM_CASES_TAC ``z:real = x`` THENL 7116 [FIRST_X_ASSUM SUBST_ALL_TAC THEN 7117 FIRST_X_ASSUM(X_CHOOSE_TAC ``k:real`` o MATCH_MP REAL_DOWN) THEN 7118 SUBGOAL_THEN ``?w:real. dist(w,x) = k`` STRIP_ASSUME_TAC THENL 7119 [ASM_MESON_TAC[REAL_CHOOSE_DIST, DIST_SYM, REAL_LT_IMP_LE], 7120 ASM_MESON_TAC[REAL_NOT_LE, DIST_REFL, DIST_SYM]], 7121 RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ]) THEN 7122 DISCH_THEN(MP_TAC o SPEC ``z + ((d / &2) / dist(z,x)) * (z - x:real)``) THEN 7123 FULL_SIMP_TAC arith_ss [dist, REAL_ADD_SUB, ABS_MUL, ABS_DIV, 7124 ABS_ABS, ABS_N, REAL_POS_NZ, REAL_ARITH ``0 < 2:real``] THEN 7125 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, GSYM dist, REAL_POS_NZ] THEN 7126 ASM_SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_LT] THEN 7127 ASM_REWRITE_TAC [REAL_ARITH ``abs d < d * &2 <=> &0 < d:real``] THEN 7128 DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN REWRITE_TAC[dist] THEN 7129 REWRITE_TAC[REAL_ARITH ``x - (z + k * (z - x)) = (&1 + k) * (x - z:real)``] THEN 7130 REWRITE_TAC[REAL_NOT_LE, ABS_MUL] THEN 7131 GEN_REWR_TAC LAND_CONV [GSYM REAL_MUL_LID] THEN 7132 ONCE_REWRITE_TAC[ABS_SUB] THEN 7133 ASM_SIMP_TAC std_ss [REAL_LT_RMUL, GSYM dist] THEN 7134 MATCH_MP_TAC(REAL_ARITH ``&0 < x ==> &1:real < abs(&1 + x)``) THEN 7135 ONCE_REWRITE_TAC[DIST_SYM] THEN 7136 ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT, dist]]); 7137 7138val FRONTIER_BALL = store_thm ("FRONTIER_BALL", 7139 ``!a e. &0 < e ==> (frontier(ball(a,e)) = sphere(a,e))``, 7140 SIMP_TAC std_ss [frontier, sphere, CLOSURE_BALL, INTERIOR_OPEN, OPEN_BALL, 7141 REAL_LT_IMP_LE] THEN 7142 SIMP_TAC std_ss [EXTENSION, IN_DIFF, GSPECIFICATION, IN_BALL, IN_CBALL] THEN 7143 REAL_ARITH_TAC); 7144 7145val FRONTIER_CBALL = store_thm ("FRONTIER_CBALL", 7146 ``!a e. (frontier(cball(a,e)) = sphere(a,e))``, 7147 SIMP_TAC std_ss [frontier, sphere, INTERIOR_CBALL, CLOSED_CBALL, CLOSURE_CLOSED, 7148 REAL_LT_IMP_LE] THEN 7149 SIMP_TAC std_ss [EXTENSION, IN_DIFF, SPECIFICATION, IN_BALL, IN_CBALL, dist] THEN 7150 GEN_REWR_TAC (QUANT_CONV o QUANT_CONV o QUANT_CONV o RAND_CONV) [GSYM SPECIFICATION] THEN 7151 SIMP_TAC std_ss [GSPECIFICATION] THEN REAL_ARITH_TAC); 7152 7153val CBALL_EQ_EMPTY = store_thm ("CBALL_EQ_EMPTY", 7154 ``!x e. (cball(x,e) = {}) <=> e < &0``, 7155 REWRITE_TAC[EXTENSION, IN_CBALL, NOT_IN_EMPTY, REAL_NOT_LE] THEN 7156 MESON_TAC[DIST_POS_LE, DIST_REFL, REAL_LTE_TRANS]); 7157 7158val CBALL_EMPTY = store_thm ("CBALL_EMPTY", 7159 ``!x e. e < &0 ==> (cball(x,e) = {})``, 7160 REWRITE_TAC[CBALL_EQ_EMPTY]); 7161 7162val CBALL_EQ_SING = store_thm ("CBALL_EQ_SING", 7163 ``!x:real e. (cball(x,e) = {x}) <=> (e = &0)``, 7164 REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION, IN_CBALL, IN_SING] THEN 7165 EQ_TAC THENL [ALL_TAC, MESON_TAC[DIST_LE_0]] THEN 7166 DISCH_THEN(fn th => MP_TAC(SPEC ``x + (e / &2) * 1:real`` th) THEN 7167 MP_TAC(SPEC ``x:real`` th)) THEN 7168 REWRITE_TAC[dist, REAL_ARITH ``x - (x + e):real = -e``, 7169 REAL_ARITH ``(x + e = x) <=> (e:real = 0)``] THEN 7170 REWRITE_TAC[ABS_NEG, ABS_MUL, REAL_ENTIRE, ABS_0, REAL_SUB_REFL] THEN 7171 SIMP_TAC std_ss [ABS_1, REAL_ARITH ``~(1 = 0:real)``] THEN 7172 SIMP_TAC arith_ss [REAL_MUL_RID, REAL_EQ_LDIV_EQ, 7173 REAL_ARITH ``0 < 2:real``, REAL_MUL_LZERO] THEN 7174 GEN_REWR_TAC LAND_CONV [REAL_LE_LT] THEN RW_TAC arith_ss [] THEN 7175 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN ASM_REWRITE_TAC [abs] THEN 7176 COND_CASES_TAC THENL 7177 [FULL_SIMP_TAC std_ss [REAL_LE_LT] THEN DISJ1_TAC THEN 7178 ASM_SIMP_TAC std_ss [REAL_LT_HALF2], ALL_TAC] THEN 7179 UNDISCH_TAC ``0 < e:real`` THEN GEN_REWR_TAC LAND_CONV [GSYM REAL_LT_HALF1] THEN 7180 DISCH_TAC THEN FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN METIS_TAC [REAL_LT_ANTISYM]); 7181 7182val CBALL_SING = store_thm ("CBALL_SING", 7183 ``!x e. (e = &0) ==> (cball(x,e) = {x})``, 7184 REWRITE_TAC[CBALL_EQ_SING]); 7185 7186val SPHERE_SING = store_thm ("SPHERE_SING", 7187 ``!x e. (e = &0) ==> (sphere(x,e) = {x})``, 7188 SIMP_TAC std_ss [sphere, DIST_EQ_0, GSPEC_EQ, GSPEC_EQ2]); 7189 7190val SPHERE_EQ_SING = store_thm ("SPHERE_EQ_SING", 7191 ``!a:real r x. (sphere(a,r) = {x}) <=> (x = a) /\ (r = &0)``, 7192 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [SPHERE_SING] THEN 7193 ASM_CASES_TAC ``r < &0:real`` THEN ASM_SIMP_TAC std_ss [SPHERE_EMPTY, NOT_INSERT_EMPTY] THEN 7194 ASM_CASES_TAC ``r = &0:real`` THEN ASM_SIMP_TAC std_ss [SPHERE_SING] THENL 7195 [ASM_SET_TAC[], ALL_TAC] THEN 7196 MATCH_MP_TAC(SET_RULE 7197 ``!y. (x IN s ==> y IN s /\ ~(y = x)) ==> ~(s = {x})``) THEN 7198 EXISTS_TAC ``a - (x - a):real`` THEN REWRITE_TAC[IN_SPHERE] THEN 7199 REWRITE_TAC [dist] THEN REPEAT(POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC); 7200 7201(* ------------------------------------------------------------------------- *) 7202(* For points in the interior, localization of limits makes no difference. *) 7203(* ------------------------------------------------------------------------- *) 7204 7205val EVENTUALLY_WITHIN_INTERIOR = store_thm ("EVENTUALLY_WITHIN_INTERIOR", 7206 ``!p s x. 7207 x IN interior s 7208 ==> (eventually p (at x within s) <=> eventually p (at x))``, 7209 REWRITE_TAC[EVENTUALLY_WITHIN, EVENTUALLY_AT, IN_INTERIOR] THEN 7210 REPEAT GEN_TAC THEN SIMP_TAC std_ss [SUBSET_DEF, IN_BALL] THEN 7211 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 7212 EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 7213 EXISTS_TAC ``min (d:real) e`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 7214 ASM_MESON_TAC[DIST_SYM]); 7215 7216val LIM_WITHIN_INTERIOR = store_thm ("LIM_WITHIN_INTERIOR", 7217 ``!f l s x. x IN interior s 7218 ==> ((f --> l) (at x within s) <=> (f --> l) (at x))``, 7219 SIMP_TAC std_ss [tendsto, EVENTUALLY_WITHIN_INTERIOR]); 7220 7221val NETLIMIT_WITHIN_INTERIOR = store_thm ("NETLIMIT_WITHIN_INTERIOR", 7222 ``!s x:real. x IN interior s ==> (netlimit(at x within s) = x)``, 7223 REPEAT STRIP_TAC THEN MATCH_MP_TAC NETLIMIT_WITHIN THEN 7224 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN 7225 FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[OPEN_CONTAINS_BALL] 7226 (SPEC_ALL OPEN_INTERIOR))) THEN 7227 ASM_MESON_TAC[LIMPT_SUBSET, LIMPT_BALL, CENTRE_IN_CBALL, REAL_LT_IMP_LE, 7228 SUBSET_TRANS, INTERIOR_SUBSET]); 7229 7230(* ------------------------------------------------------------------------- *) 7231(* A non-singleton connected set is perfect (i.e. has no isolated points). *) 7232(* ------------------------------------------------------------------------- *) 7233 7234val CONNECTED_IMP_PERFECT = store_thm ("CONNECTED_IMP_PERFECT", 7235 ``!s x:real. 7236 connected s /\ ~(?a. s = {a}) /\ x IN s ==> x limit_point_of s``, 7237 REPEAT STRIP_TAC THEN REWRITE_TAC[limit_point_of] THEN 7238 X_GEN_TAC ``t:real->bool`` THEN STRIP_TAC THEN 7239 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN 7240 KNOW_TAC ``open t`` THENL [ASM_REWRITE_TAC [], ALL_TAC] THEN 7241 GEN_REWR_TAC LAND_CONV [OPEN_CONTAINS_CBALL] THEN 7242 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x:real`) THEN 7243 ASM_REWRITE_TAC[] THEN 7244 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 7245 UNDISCH_TAC ``connected s`` THEN GEN_REWR_TAC LAND_CONV [CONNECTED_CLOPEN] THEN 7246 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `{x:real}`) THEN 7247 REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL 7248 [REWRITE_TAC[OPEN_IN_OPEN] THEN EXISTS_TAC ``t:real->bool`` THEN 7249 ASM_SET_TAC[], 7250 REWRITE_TAC[CLOSED_IN_CLOSED] THEN 7251 EXISTS_TAC ``cball(x:real,e)`` THEN REWRITE_TAC[CLOSED_CBALL] THEN 7252 REWRITE_TAC[EXTENSION, IN_INTER, IN_SING] THEN 7253 ASM_MESON_TAC[CENTRE_IN_CBALL, SUBSET_DEF, REAL_LT_IMP_LE], 7254 ASM_SET_TAC[]]); 7255 7256val CONNECTED_IMP_PERFECT_CLOSED = store_thm ("CONNECTED_IMP_PERFECT_CLOSED", 7257 ``!s x. connected s /\ closed s /\ ~(?a. s = {a}) 7258 ==> (x limit_point_of s <=> x IN s)``, 7259 MESON_TAC[CONNECTED_IMP_PERFECT, CLOSED_LIMPT]); 7260 7261(* ------------------------------------------------------------------------- *) 7262(* Boundedness. *) 7263(* ------------------------------------------------------------------------- *) 7264 7265val bounded_def = new_definition ("bounded_def", 7266 ``bounded_def s <=> ?a. !x:real. x IN s ==> abs(x) <= a``); 7267 7268val _ = overload_on ("bounded",``bounded_def``); 7269 7270val BOUNDED_EMPTY = store_thm ("BOUNDED_EMPTY", 7271 ``bounded {}``, 7272 REWRITE_TAC[bounded_def, NOT_IN_EMPTY]); 7273 7274val BOUNDED_SUBSET = store_thm ("BOUNDED_SUBSET", 7275 ``!s t. bounded t /\ s SUBSET t ==> bounded s``, 7276 MESON_TAC[bounded_def, SUBSET_DEF]); 7277 7278val BOUNDED_INTERIOR = store_thm ("BOUNDED_INTERIOR", 7279 ``!s:real->bool. bounded s ==> bounded(interior s)``, 7280 MESON_TAC[BOUNDED_SUBSET, INTERIOR_SUBSET]); 7281 7282val BOUNDED_CLOSURE = store_thm ("BOUNDED_CLOSURE", 7283 ``!s:real->bool. bounded s ==> bounded(closure s)``, 7284 REWRITE_TAC[bounded_def, CLOSURE_SEQUENTIAL] THEN 7285 GEN_TAC THEN STRIP_TAC THEN EXISTS_TAC ``a:real`` THEN 7286 GEN_TAC THEN 7287 METIS_TAC[REWRITE_RULE[eventually] LIM_ABS_UBOUND, 7288 TRIVIAL_LIMIT_SEQUENTIALLY, trivial_limit]); 7289 7290val BOUNDED_CLOSURE_EQ = store_thm ("BOUNDED_CLOSURE_EQ", 7291 ``!s:real->bool. bounded(closure s) <=> bounded s``, 7292 GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSURE] THEN 7293 MESON_TAC[BOUNDED_SUBSET, CLOSURE_SUBSET]); 7294 7295val BOUNDED_CBALL = store_thm ("BOUNDED_CBALL", 7296 ``!x:real e. bounded(cball(x,e))``, 7297 REPEAT GEN_TAC THEN REWRITE_TAC[bounded_def] THEN 7298 EXISTS_TAC ``abs(x:real) + e`` THEN REWRITE_TAC[IN_CBALL, dist] THEN 7299 REAL_ARITH_TAC); 7300 7301val BOUNDED_BALL = store_thm ("BOUNDED_BALL", 7302 ``!x e. bounded(ball(x,e))``, 7303 MESON_TAC[BALL_SUBSET_CBALL, BOUNDED_CBALL, BOUNDED_SUBSET]); 7304 7305val FINITE_IMP_BOUNDED = store_thm ("FINITE_IMP_BOUNDED", 7306 ``!s:real->bool. FINITE s ==> bounded s``, 7307 KNOW_TAC ``!s:real->bool. (bounded s) = (\s. bounded s) s`` THENL 7308 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 7309 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN REWRITE_TAC[BOUNDED_EMPTY] THEN 7310 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 7311 REWRITE_TAC[bounded_def, IN_INSERT] THEN GEN_TAC THEN X_GEN_TAC ``x:real`` THEN 7312 REWRITE_TAC [AND_IMP_INTRO] THEN STRIP_TAC THEN 7313 EXISTS_TAC ``abs(x:real) + abs a`` THEN REPEAT STRIP_TAC THEN 7314 ASM_MESON_TAC[ABS_POS, REAL_ARITH 7315 ``(y <= b /\ &0 <= x ==> y <= x + abs b) /\ x <= x + abs b:real``]); 7316 7317val BOUNDED_UNION = store_thm ("BOUNDED_UNION", 7318 ``!s t. bounded (s UNION t) <=> bounded s /\ bounded t``, 7319 REWRITE_TAC[bounded_def, IN_UNION] THEN MESON_TAC[REAL_LE_MAX]); 7320 7321val BOUNDED_BIGUNION = store_thm ("BOUNDED_BIGUNION", 7322 ``!f. FINITE f /\ (!s. s IN f ==> bounded s) ==> bounded(BIGUNION f)``, 7323 REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 7324 KNOW_TAC ``!f. ((!s. s IN f ==> bounded s) ==> bounded(BIGUNION f)) = 7325 (\f. (!s. s IN f ==> bounded s) ==> bounded(BIGUNION f)) f`` THENL 7326 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 7327 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 7328 REWRITE_TAC[BIGUNION_EMPTY, BOUNDED_EMPTY, IN_INSERT, BIGUNION_INSERT] THEN 7329 MESON_TAC[BOUNDED_UNION]); 7330 7331val BOUNDED_POS = store_thm ("BOUNDED_POS", 7332 ``!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> abs(x) <= b``, 7333 REWRITE_TAC[bounded_def] THEN 7334 METIS_TAC[REAL_ARITH ``&0 < &1 + abs(y) /\ (x <= y ==> x:real <= &1 + abs(y))``]); 7335 7336val BOUNDED_POS_LT = store_thm ("BOUNDED_POS_LT", 7337 ``!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> abs(x) < b``, 7338 REWRITE_TAC[bounded_def] THEN 7339 MESON_TAC[REAL_LT_IMP_LE, 7340 REAL_ARITH ``&0 < &1 + abs(y) /\ (x <= y ==> x < &1 + abs(y:real))``]); 7341 7342val BOUNDED_INTER = store_thm ("BOUNDED_INTER", 7343 ``!s t. bounded s \/ bounded t ==> bounded (s INTER t)``, 7344 MESON_TAC[BOUNDED_SUBSET, INTER_SUBSET]); 7345 7346val BOUNDED_DIFF = store_thm ("BOUNDED_DIFF", 7347 ``!s t. bounded s ==> bounded (s DIFF t)``, 7348 METIS_TAC[BOUNDED_SUBSET, DIFF_SUBSET]); 7349 7350val BOUNDED_INSERT = store_thm ("BOUNDED_INSERT", 7351 ``!x s. bounded(x INSERT s) <=> bounded s``, 7352 ONCE_REWRITE_TAC[SET_RULE ``x INSERT s = {x} UNION s``] THEN 7353 SIMP_TAC std_ss [BOUNDED_UNION, FINITE_IMP_BOUNDED, FINITE_EMPTY, FINITE_INSERT]); 7354 7355val BOUNDED_SING = store_thm ("BOUNDED_SING", 7356 ``!a. bounded {a}``, 7357 REWRITE_TAC[BOUNDED_INSERT, BOUNDED_EMPTY]); 7358 7359val BOUNDED_BIGINTER = store_thm ("BOUNDED_BIGINTER", 7360 ``!f:(real->bool)->bool. 7361 (?s:real->bool. s IN f /\ bounded s) ==> bounded(BIGINTER f)``, 7362 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, CONJ_EQ_IMP] THEN REPEAT GEN_TAC THEN 7363 DISCH_TAC THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN 7364 ASM_SET_TAC[]); 7365 7366val NOT_BOUNDED_UNIV = store_thm ("NOT_BOUNDED_UNIV", 7367 ``~(bounded univ(:real))``, 7368 SIMP_TAC std_ss [BOUNDED_POS, NOT_FORALL_THM, NOT_EXISTS_THM, IN_UNIV, 7369 DE_MORGAN_THM, REAL_NOT_LE] THEN 7370 X_GEN_TAC ``B:real`` THEN ASM_CASES_TAC ``&0 < B:real`` THEN ASM_REWRITE_TAC[] THEN 7371 EXISTS_TAC ``(B + &1):real`` THEN REAL_ARITH_TAC); 7372 7373val COBOUNDED_IMP_UNBOUNDED = store_thm ("COBOUNDED_IMP_UNBOUNDED", 7374 ``!s. bounded(univ(:real) DIFF s) ==> ~bounded s``, 7375 GEN_TAC THEN REWRITE_TAC[TAUT `a ==> ~b <=> ~(a /\ b)`] THEN 7376 REWRITE_TAC[GSYM BOUNDED_UNION, SET_RULE ``UNIV DIFF s UNION s = UNIV``] THEN 7377 REWRITE_TAC[NOT_BOUNDED_UNIV]); 7378 7379val BOUNDED_LINEAR_IMAGE = store_thm ("BOUNDED_LINEAR_IMAGE", 7380 ``!f:real->real s. bounded s /\ linear f ==> bounded(IMAGE f s)``, 7381 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN 7382 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC ``B1:real``) MP_TAC) THEN 7383 DISCH_THEN(X_CHOOSE_TAC ``B2:real`` o MATCH_MP LINEAR_BOUNDED_POS) THEN 7384 EXISTS_TAC ``B2 * B1:real`` THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL, FORALL_IN_IMAGE] THEN 7385 X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN 7386 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``B2 * abs(x:real)`` THEN 7387 ASM_SIMP_TAC std_ss [REAL_LE_LMUL]); 7388 7389val BOUNDED_SCALING = store_thm ("BOUNDED_SCALING", 7390 ``!c s. bounded s ==> bounded (IMAGE (\x. c * x) s)``, 7391 REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_LINEAR_IMAGE THEN 7392 ASM_SIMP_TAC std_ss [LINEAR_COMPOSE_CMUL, LINEAR_ID]); 7393 7394val BOUNDED_NEGATIONS = store_thm ("BOUNDED_NEGATIONS", 7395 ``!s. bounded s ==> bounded (IMAGE (\x. -x) s)``, 7396 GEN_TAC THEN 7397 DISCH_THEN(MP_TAC o SPEC ``-&1:real`` o MATCH_MP BOUNDED_SCALING) THEN 7398 REWRITE_TAC[bounded_def, IN_IMAGE, REAL_MUL_LNEG, REAL_MUL_LID]); 7399 7400val BOUNDED_TRANSLATION = store_thm ("BOUNDED_TRANSLATION", 7401 ``!a:real s. bounded s ==> bounded (IMAGE (\x. a + x) s)``, 7402 REPEAT GEN_TAC THEN SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE] THEN 7403 DISCH_THEN(X_CHOOSE_TAC ``B:real``) THEN 7404 EXISTS_TAC ``B + abs(a:real)`` THEN POP_ASSUM MP_TAC THEN 7405 MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN 7406 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x:real`) THEN 7407 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN REAL_ARITH_TAC); 7408 7409val BOUNDED_TRANSLATION_EQ = store_thm ("BOUNDED_TRANSLATION_EQ", 7410 ``!a s. bounded (IMAGE (\x:real. a + x) s) <=> bounded s``, 7411 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_TRANSLATION] THEN 7412 DISCH_THEN(MP_TAC o SPEC ``-a:real`` o MATCH_MP BOUNDED_TRANSLATION) THEN 7413 SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID, 7414 REAL_ARITH ``-a + (a + x:real) = x``]); 7415 7416val BOUNDED_DIFFS = store_thm ("BOUNDED_DIFFS", 7417 ``!s t:real->bool. 7418 bounded s /\ bounded t ==> bounded {x - y | x IN s /\ y IN t}``, 7419 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN 7420 DISCH_THEN(CONJUNCTS_THEN2 7421 (X_CHOOSE_TAC ``B:real``) (X_CHOOSE_TAC ``C:real``)) THEN 7422 EXISTS_TAC ``B + C:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN 7423 CONJ_TAC THENL [MATCH_MP_TAC REAL_LT_ADD THEN ASM_REWRITE_TAC [], REPEAT STRIP_TAC] THEN 7424 ASM_REWRITE_TAC[] THEN KNOW_TAC ``abs p_1 <= B:real /\ abs p_2 <= C:real`` THENL 7425 [ASM_SET_TAC [], ALL_TAC] THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN 7426 EXISTS_TAC ``abs p_1 + abs p_2:real`` THEN REWRITE_TAC [real_sub, ABS_TRIANGLE] THEN 7427 CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN 7428 MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC [ABS_NEG]); 7429 7430val BOUNDED_SUMS = store_thm ("BOUNDED_SUMS", 7431 ``!s t:real->bool. 7432 bounded s /\ bounded t ==> bounded {x + y | x IN s /\ y IN t}``, 7433 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN 7434 DISCH_THEN(CONJUNCTS_THEN2 7435 (X_CHOOSE_TAC ``B:real``) (X_CHOOSE_TAC ``C:real``)) THEN 7436 EXISTS_TAC ``B + C:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN 7437 CONJ_TAC THENL [MATCH_MP_TAC REAL_LT_ADD THEN ASM_REWRITE_TAC [], REPEAT STRIP_TAC] THEN 7438 ASM_REWRITE_TAC[] THEN KNOW_TAC ``abs p_1 <= B:real /\ abs p_2 <= C:real`` THENL 7439 [ASM_SET_TAC [], ALL_TAC] THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN 7440 EXISTS_TAC ``abs p_1 + abs p_2:real`` THEN REWRITE_TAC [ABS_TRIANGLE] THEN 7441 MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC []); 7442 7443val BOUNDED_SUMS_IMAGE = store_thm ("BOUNDED_SUMS_IMAGE", 7444 ``!f g t. bounded {f x | x IN t} /\ bounded {g x | x IN t} 7445 ==> bounded {f x + g x | x IN t}``, 7446 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUMS) THEN 7447 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN 7448 REWRITE_TAC [SUBSET_DEF] THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN 7449 METIS_TAC []); 7450 7451val BOUNDED_SUMS_IMAGES = store_thm ("BOUNDED_SUMS_IMAGES", 7452 ``!f:'a->'b->real t s. FINITE s /\ 7453 (!a. a IN s ==> bounded {f x a | x IN t}) 7454 ==> bounded { sum s (f x) | x IN t}``, 7455 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN 7456 KNOW_TAC ``!s. ((!a. a IN s ==> bounded {(f:'a->'b->real) x a | x IN t}) ==> 7457 bounded {sum s (f x) | x IN t}) = 7458 (\s. (!a. a IN s ==> bounded {f x a | x IN t}) ==> 7459 bounded {sum s (f x) | x IN t}) s`` THENL 7460 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 7461 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 7462 SIMP_TAC std_ss [SUM_CLAUSES] THEN CONJ_TAC THENL 7463 [DISCH_THEN(K ALL_TAC) THEN MATCH_MP_TAC BOUNDED_SUBSET THEN 7464 EXISTS_TAC ``{0:real}`` THEN 7465 SIMP_TAC std_ss [FINITE_IMP_BOUNDED, FINITE_EMPTY, FINITE_INSERT] THEN SET_TAC[], 7466 ALL_TAC] THEN REPEAT STRIP_TAC THEN 7467 KNOW_TAC ``bounded {(f:'a->'b->real) x e | x IN t} /\ 7468 bounded {sum s ((f:'a->'b->real) x) | x IN t}`` THENL 7469 [ALL_TAC, METIS_TAC [BOUNDED_SUMS_IMAGE]] THEN ASM_SIMP_TAC std_ss [IN_INSERT]); 7470 7471val BOUNDED_SUBSET_BALL = store_thm ("BOUNDED_SUBSET_BALL", 7472 ``!s x:real. bounded(s) ==> ?r. &0 < r /\ s SUBSET ball(x,r)``, 7473 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN 7474 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 7475 EXISTS_TAC ``&2 * B + abs(x:real)`` THEN 7476 ASM_SIMP_TAC std_ss [ABS_POS, REAL_ARITH 7477 ``&0 < B /\ &0 <= x ==> &0 < &2 * B + x:real``] THEN 7478 REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 7479 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN ASM_REWRITE_TAC[IN_BALL, dist] THEN 7480 UNDISCH_TAC ``&0 < B:real`` THEN REAL_ARITH_TAC); 7481 7482val BOUNDED_SUBSET_CBALL = store_thm ("BOUNDED_SUBSET_CBALL", 7483 ``!s x:real. bounded(s) ==> ?r. &0 < r /\ s SUBSET cball(x,r)``, 7484 MESON_TAC[BOUNDED_SUBSET_BALL, SUBSET_TRANS, BALL_SUBSET_CBALL]); 7485 7486val UNBOUNDED_INTER_COBOUNDED = store_thm ("UNBOUNDED_INTER_COBOUNDED", 7487 ``!s t. ~bounded s /\ bounded(univ(:real) DIFF t) ==> ~(s INTER t = {})``, 7488 REWRITE_TAC[SET_RULE ``(s INTER t = {}) <=> s SUBSET univ(:real) DIFF t``] THEN 7489 MESON_TAC[BOUNDED_SUBSET]); 7490 7491val COBOUNDED_INTER_UNBOUNDED = store_thm ("COBOUNDED_INTER_UNBOUNDED", 7492 ``!s t. bounded(univ(:real) DIFF s) /\ ~bounded t ==> ~(s INTER t = {})``, 7493 REWRITE_TAC[SET_RULE ``(s INTER t = {}) <=> t SUBSET univ(:real) DIFF s``] THEN 7494 MESON_TAC[BOUNDED_SUBSET]); 7495 7496val SUBSPACE_BOUNDED_EQ_TRIVIAL = store_thm ("SUBSPACE_BOUNDED_EQ_TRIVIAL", 7497 ``!s:real->bool. subspace s ==> (bounded s <=> (s = {0}))``, 7498 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [BOUNDED_SING] THEN 7499 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 7500 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE 7501 ``~(s = {a}) ==> a IN s ==> ?b. b IN s /\ ~(b = a)``)) THEN 7502 ASM_SIMP_TAC std_ss [SUBSPACE_0] THEN 7503 DISCH_THEN(X_CHOOSE_THEN ``v:real`` STRIP_ASSUME_TAC) THEN 7504 SIMP_TAC std_ss [bounded_def, NOT_EXISTS_THM] THEN X_GEN_TAC ``B:real`` THEN 7505 EXISTS_TAC ``(B + &1) / abs v * v:real`` THEN 7506 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM ABS_ZERO]) THEN 7507 ASM_SIMP_TAC std_ss [SUBSPACE_MUL, ABS_MUL, ABS_DIV, ABS_ABS] THEN 7508 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, ABS_ZERO] THEN REAL_ARITH_TAC); 7509 7510val BOUNDED_COMPONENTWISE = store_thm ("BOUNDED_COMPONENTWISE", 7511 ``!s:real->bool. 7512 bounded s <=> bounded (IMAGE (\x. x) s)``, 7513 METIS_TAC [IMAGE_ID]); 7514 7515(* ------------------------------------------------------------------------- *) 7516(* Some theorems on sups and infs using the notion "bounded". *) 7517(* ------------------------------------------------------------------------- *) 7518 7519val BOUNDED_HAS_SUP = store_thm ("BOUNDED_HAS_SUP", 7520 ``!s. bounded s /\ ~(s = {}) 7521 ==> (!x. x IN s ==> x <= sup s) /\ 7522 (!b. (!x. x IN s ==> x <= b) ==> sup s <= b)``, 7523 REWRITE_TAC[bounded_def, IMAGE_EQ_EMPTY] THEN 7524 MESON_TAC[SUP, REAL_ARITH ``abs(x) <= a ==> x <= a:real``]); 7525 7526val SUP_INSERT = store_thm ("SUP_INSERT", 7527 ``!x s:real->bool. bounded s 7528 ==> (sup(x INSERT s) = if s = {} then x else (max x (sup s)))``, 7529 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_UNIQUE THEN 7530 COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL 7531 [MESON_TAC[REAL_LE_REFL], ALL_TAC] THEN 7532 REWRITE_TAC[REAL_LE_MAX, REAL_LT_MAX, IN_INSERT] THEN 7533 MP_TAC(ISPEC ``s:real->bool`` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN 7534 REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL, REAL_NOT_LT]); 7535 7536val BOUNDED_HAS_INF = store_thm ("BOUNDED_HAS_INF", 7537 ``!s. bounded s /\ ~(s = {}) 7538 ==> (!x. x IN s ==> inf s <= x) /\ 7539 (!b. (!x. x IN s ==> b <= x) ==> b <= inf s)``, 7540 REWRITE_TAC[bounded_def, IMAGE_EQ_EMPTY] THEN 7541 MESON_TAC[INF, REAL_ARITH ``abs(x) <= a ==> -a <= x:real``]); 7542 7543val INF_INSERT = store_thm ("INF_INSERT", 7544 ``!x s. bounded s 7545 ==> (inf(x INSERT s) = if s = {} then x else (min x (inf s)))``, 7546 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INF_UNIQUE THEN 7547 COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL 7548 [MESON_TAC[REAL_LE_REFL], ALL_TAC] THEN 7549 REWRITE_TAC[REAL_MIN_LE, REAL_MIN_LT, IN_INSERT] THEN 7550 MP_TAC(ISPEC ``s:real->bool`` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN 7551 REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL, REAL_NOT_LT]); 7552 7553(* ------------------------------------------------------------------------- *) 7554(* Subset and overlapping relations on balls. *) 7555(* ------------------------------------------------------------------------- *) 7556 7557val lemma = prove ( 7558 ``(!a':real r r'. 7559 cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0) /\ 7560 (!a':real r r'. 7561 cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0)``, 7562 CONJ_TAC THENL 7563 [KNOW_TAC ``(!a' r r'. 7564 cball (a,r) SUBSET cball (a',r') <=> dist (a,a') + r <= r' \/ r < 0) = 7565 (!r r' a. 7566 cball (a,r) SUBSET cball (0,r') <=> dist (a,0) + r <= r' \/ r < 0)`` THENL 7567 [EQ_TAC THENL 7568 [DISCH_TAC THEN REPEAT GEN_TAC THEN 7569 FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist, 7570 REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN 7571 POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN 7572 FULL_SIMP_TAC std_ss [REAL_ARITH ``a - (a - b) = b:real``] THEN 7573 POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN 7574 POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN 7575 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 7576 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL 7577 [DISCH_TAC THEN GEN_TAC THEN 7578 POP_ASSUM (MP_TAC o Q.SPEC `-(a - a' - x:real)`) THEN 7579 REWRITE_TAC [ABS_NEG] THEN REAL_ARITH_TAC, ALL_TAC] THEN 7580 DISCH_TAC THEN GEN_TAC THEN 7581 POP_ASSUM (MP_TAC o Q.SPEC `-(-a + a' - x:real)`) THEN 7582 REAL_ARITH_TAC, ALL_TAC] THEN 7583 DISCH_TAC THEN REPEAT GEN_TAC THEN 7584 FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist, 7585 REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN 7586 POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN 7587 POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN 7588 POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN 7589 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 7590 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL 7591 [DISCH_TAC THEN GEN_TAC THEN 7592 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7593 REAL_ARITH_TAC, ALL_TAC] THEN 7594 DISCH_TAC THEN GEN_TAC THEN 7595 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7596 REAL_ARITH_TAC, 7597 DISCH_TAC THEN ASM_REWRITE_TAC[] THEN POP_ASSUM K_TAC], 7598 KNOW_TAC ``(!a' r r'. 7599 cball (a,r) SUBSET ball (a',r') <=> dist (a,a') + r < r' \/ r < 0) = 7600 (!r r' a. 7601 cball (a,r) SUBSET ball (0,r') <=> dist (a,0) + r < r' \/ r < 0)`` THENL 7602 [EQ_TAC THENL 7603 [DISCH_TAC THEN REPEAT GEN_TAC THEN 7604 FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist, 7605 REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN 7606 POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN 7607 FULL_SIMP_TAC std_ss [REAL_ARITH ``a - (a - b) = b:real``] THEN 7608 POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN 7609 POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN 7610 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 7611 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL 7612 [DISCH_TAC THEN GEN_TAC THEN 7613 POP_ASSUM (MP_TAC o Q.SPEC `-(a - a' - x:real)`) THEN 7614 REWRITE_TAC [ABS_NEG] THEN REAL_ARITH_TAC, ALL_TAC] THEN 7615 DISCH_TAC THEN GEN_TAC THEN 7616 POP_ASSUM (MP_TAC o Q.SPEC `-(-a + a' - x:real)`) THEN 7617 REAL_ARITH_TAC, ALL_TAC] THEN 7618 DISCH_TAC THEN REPEAT GEN_TAC THEN 7619 FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist, 7620 REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN 7621 POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN 7622 POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN 7623 POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN 7624 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 7625 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL 7626 [DISCH_TAC THEN GEN_TAC THEN 7627 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7628 REAL_ARITH_TAC, ALL_TAC] THEN 7629 DISCH_TAC THEN GEN_TAC THEN 7630 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7631 REAL_ARITH_TAC, 7632 DISCH_TAC THEN ASM_REWRITE_TAC[] THEN POP_ASSUM K_TAC]] THEN 7633 (REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET_DEF, IN_CBALL, IN_BALL] THEN 7634 EQ_TAC THENL 7635 [REWRITE_TAC[DIST_0], 7636 REWRITE_TAC [dist] THEN REAL_ARITH_TAC] THEN 7637 DISJ_CASES_TAC(REAL_ARITH ``r < &0 \/ &0 <= r:real``) THEN 7638 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN DISJ1_TAC THEN 7639 ASM_CASES_TAC ``a:real = 0`` THENL 7640 [FIRST_X_ASSUM(MP_TAC o SPEC ``r:real``) THEN 7641 ASM_SIMP_TAC std_ss [DIST_0, ABS_MUL, LESS_EQ_REFL] THEN 7642 ASM_REAL_ARITH_TAC, 7643 FIRST_X_ASSUM(MP_TAC o SPEC ``(&1 + r / abs(a)) * a:real``) THEN 7644 SIMP_TAC std_ss [dist, REAL_ARITH ``a - (&1 + x) * a:real = -(x * a)``] THEN 7645 ASM_SIMP_TAC std_ss [ABS_MUL, ABS_DIV, ABS_ABS, ABS_NEG, REAL_POS, 7646 REAL_LE_DIV, ABS_POS, REAL_ADD_RDISTRIB, REAL_DIV_RMUL, 7647 ABS_ZERO, REAL_ARITH ``&0 <= x ==> (abs(&1 + x) = &1 + x:real)``] THEN 7648 ASM_REAL_ARITH_TAC])); 7649 7650val tac = DISCH_THEN(MP_TAC o MATCH_MP SUBSET_CLOSURE) THEN 7651 ASM_SIMP_TAC std_ss [CLOSED_CBALL, CLOSURE_CLOSED, CLOSURE_BALL]; 7652 7653val SUBSET_BALLS = store_thm ("SUBSET_BALLS", 7654 ``(!a a':real r r'. 7655 ball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\ 7656 (!a a':real r r'. 7657 ball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\ 7658 (!a a':real r r'. 7659 cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0) /\ 7660 (!a a':real r r'. 7661 cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0)``, 7662 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN 7663 KNOW_TAC ``(!a a':real r r'. 7664 (ball (a,r) SUBSET ball (a',r') <=> 7665 dist (a,a') + r <= r' \/ r <= 0) /\ 7666 (ball (a,r) SUBSET cball (a',r') <=> 7667 dist (a,a') + r <= r' \/ r <= 0) /\ 7668 (cball (a,r) SUBSET ball (a',r') <=> 7669 dist (a,a') + r < r' \/ r < 0) /\ 7670 (cball (a,r) SUBSET cball (a',r') <=> 7671 dist (a,a') + r <= r' \/ r < 0)) = 7672 (!a:real r r'. 7673 (ball (a,r) SUBSET ball (0,r') <=> 7674 dist (a,0) + r <= r' \/ r <= 0) /\ 7675 (ball (a,r) SUBSET cball (0,r') <=> 7676 dist (a,0) + r <= r' \/ r <= 0) /\ 7677 (cball (a,r) SUBSET ball (0,r') <=> 7678 dist (a,0) + r < r' \/ r < 0) /\ 7679 (cball (a,r) SUBSET cball (0,r') <=> 7680 dist (a,0) + r <= r' \/ r < 0))`` THENL 7681 [EQ_TAC THENL 7682 [DISCH_TAC THEN REPEAT GEN_TAC THEN METIS_TAC [], ALL_TAC] THEN 7683 DISCH_TAC THEN REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [DIST_0] THEN 7684 FULL_SIMP_TAC std_ss [cball, ball, dist, SUBSET_DEF, GSPECIFICATION] THEN 7685 FULL_SIMP_TAC std_ss [REAL_SUB_LZERO, ABS_NEG] THEN 7686 POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN 7687 POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN 7688 POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN 7689 GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN 7690 REPEAT STRIP_TAC THENL 7691 [UNDISCH_TAC ``abs (a - a') + r <= r' \/ r <= 0 <=> 7692 !x:real. abs (a - a' - x) < r ==> abs x < r'`` THEN 7693 REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN 7694 ASM_REWRITE_TAC [] THEN EQ_TAC THENL 7695 [DISCH_TAC THEN GEN_TAC THEN 7696 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7697 REAL_ARITH_TAC, 7698 DISCH_TAC THEN GEN_TAC THEN 7699 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7700 REAL_ARITH_TAC], 7701 UNDISCH_TAC ``abs (a - a') + r <= r' \/ r <= 0 <=> 7702 !x:real. abs (a - a' - x) < r ==> abs x <= r'`` THEN 7703 REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN 7704 ASM_REWRITE_TAC [] THEN EQ_TAC THENL 7705 [DISCH_TAC THEN GEN_TAC THEN 7706 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7707 REAL_ARITH_TAC, 7708 DISCH_TAC THEN GEN_TAC THEN 7709 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7710 REAL_ARITH_TAC], 7711 UNDISCH_TAC ``abs (a - a') + r < r' \/ r < 0 <=> 7712 !x:real. abs (a - a' - x) <= r ==> abs x < r'`` THEN 7713 REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN 7714 ASM_REWRITE_TAC [] THEN EQ_TAC THENL 7715 [DISCH_TAC THEN GEN_TAC THEN 7716 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7717 REAL_ARITH_TAC, 7718 DISCH_TAC THEN GEN_TAC THEN 7719 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7720 REAL_ARITH_TAC], 7721 UNDISCH_TAC ``abs (a - a') + r <= r' \/ r < 0 <=> 7722 !x:real. abs (a - a' - x) <= r ==> abs x <= r'`` THEN 7723 REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN 7724 ASM_REWRITE_TAC [] THEN EQ_TAC THENL 7725 [DISCH_TAC THEN GEN_TAC THEN 7726 POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN 7727 REAL_ARITH_TAC, 7728 DISCH_TAC THEN GEN_TAC THEN 7729 POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN 7730 REAL_ARITH_TAC]], 7731 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 7732 REPEAT STRIP_TAC THEN 7733 (EQ_TAC THENL 7734 [ALL_TAC, REWRITE_TAC[SUBSET_DEF, IN_BALL, IN_CBALL, dist] THEN REAL_ARITH_TAC]) THEN 7735 MATCH_MP_TAC(SET_RULE 7736 ``((s = {}) <=> q) /\ (s SUBSET t /\ ~(s = {}) /\ ~(t = {}) ==> p) 7737 ==> s SUBSET t ==> p \/ q``) THEN 7738 SIMP_TAC std_ss [BALL_EQ_EMPTY, CBALL_EQ_EMPTY, REAL_NOT_LE, REAL_NOT_LT] THEN 7739 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THENL 7740 [tac, tac, ALL_TAC, ALL_TAC] THEN REWRITE_TAC[lemma] THEN 7741 REPEAT(POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC); 7742 7743(* NOTE: this proof needs 10s to finish (last step created 2048*4 subgoals *) 7744val INTER_BALLS_EQ_EMPTY = store_thm 7745 ("INTER_BALLS_EQ_EMPTY", 7746 ``(!a b:real r s. (ball(a,r) INTER ball(b,s) = {}) <=> 7747 r <= &0 \/ s <= &0 \/ r + s <= dist(a,b)) /\ 7748 (!a b:real r s. (ball(a,r) INTER cball(b,s) = {}) <=> 7749 r <= &0 \/ s < &0 \/ r + s <= dist(a,b)) /\ 7750 (!a b:real r s. (cball(a,r) INTER ball(b,s) = {}) <=> 7751 r < &0 \/ s <= &0 \/ r + s <= dist(a,b)) /\ 7752 (!a b:real r s. (cball(a,r) INTER cball(b,s) = {}) <=> 7753 r < &0 \/ s < &0 \/ r + s < dist(a,b))``, 7754 REPEAT STRIP_TAC THENL 7755 [KNOW_TAC ``!b:real. 0 <= b ==> 7756 !r s:real. ((ball (0,r) INTER ball (b,s) = {}) <=> 7757 r <= 0 \/ s <= 0 \/ r + s <= dist (0,b))`` THENL 7758 [ALL_TAC, SIMP_TAC std_ss [ball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``, 7759 EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN 7760 DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN 7761 REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN 7762 POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN 7763 GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 7764 POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN 7765 REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 7766 POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN 7767 EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN 7768 POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC, 7769 DISCH_TAC THEN GEN_TAC THEN 7770 POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC]], 7771 7772 KNOW_TAC ``!b:real. 0 <= b ==> 7773 !r s:real. ((ball (0,r) INTER cball (b,s) = {}) <=> 7774 r <= 0 \/ s < 0 \/ r + s <= dist (0,b))`` THENL 7775 [ALL_TAC, SIMP_TAC std_ss [ball, cball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``, 7776 EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN 7777 DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN 7778 REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN 7779 POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN 7780 GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 7781 POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN 7782 REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 7783 POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN 7784 EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN 7785 POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC, 7786 DISCH_TAC THEN GEN_TAC THEN 7787 POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC]], 7788 7789 KNOW_TAC ``!b:real. 0 <= b ==> 7790 !r s:real. ((cball (0,r) INTER ball (b,s) = {}) <=> 7791 r < 0 \/ s <= 0 \/ r + s <= dist (0,b))`` THENL 7792 [ALL_TAC, SIMP_TAC std_ss [ball, cball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``, 7793 EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN 7794 DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN 7795 REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN 7796 POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN 7797 GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 7798 POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN 7799 REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 7800 POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN 7801 EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN 7802 POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC, 7803 DISCH_TAC THEN GEN_TAC THEN 7804 POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC]], 7805 7806 KNOW_TAC ``!b:real. 0 <= b ==> 7807 !r s:real. ((cball (0,r) INTER cball (b,s) = {}) <=> 7808 r < 0 \/ s < 0 \/ r + s < dist (0,b))`` THENL 7809 [ALL_TAC, SIMP_TAC std_ss [ball, cball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``, 7810 EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN 7811 DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN 7812 REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN 7813 POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN 7814 GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 7815 POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN 7816 REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 7817 POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN 7818 EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN 7819 POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC, 7820 DISCH_TAC THEN GEN_TAC THEN 7821 POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC]]] THEN 7822 7823 REPEAT STRIP_TAC THEN 7824 REWRITE_TAC[EXTENSION, NOT_IN_EMPTY, IN_INTER, IN_CBALL, IN_BALL] THEN 7825 (EQ_TAC THENL 7826 [ALL_TAC, SPEC_TAC(``b:real``,``v:real``) THEN 7827 REWRITE_TAC [dist] THEN REAL_ARITH_TAC]) THEN 7828 DISCH_THEN(MP_TAC o GEN ``c:real`` o SPEC ``c:real``) THEN 7829 SIMP_TAC std_ss [ABS_MUL, LESS_EQ_REFL, dist, ABS_NEG, 7830 REAL_SUB_LZERO, GSYM REAL_SUB_RDISTRIB, REAL_MUL_RID] THEN 7831 ASM_REWRITE_TAC[abs] THEN REWRITE_TAC[GSYM abs] THEN 7832 DISCH_THEN(fn th => 7833 MP_TAC(SPEC ``min b r:real`` th) THEN 7834 MP_TAC(SPEC ``max (&0) (b - s:real)`` th) THEN 7835 MP_TAC(SPEC ``(r + (b - s)) / &2:real`` th)) THEN 7836 REWRITE_TAC [real_div] THEN 7837 ONCE_REWRITE_TAC [REAL_ARITH ``a - b * c = a * 1 - b * c:real``] THEN 7838 REWRITE_TAC [METIS [REAL_DIV_REFL, REAL_ARITH ``2 <> 0:real``, real_div] 7839 ``1 = 2 * inv 2:real``, REAL_ARITH ``a * (b * c) = (a * b) * c:real``] THEN 7840 REWRITE_TAC [GSYM REAL_SUB_RDISTRIB] THEN 7841 SIMP_TAC std_ss [real_div, ABS_MUL, REAL_ARITH ``2 <> 0:real``, ABS_INV, ABS_N] THEN 7842 SIMP_TAC std_ss [GSYM real_div] THEN 7843 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_LE_RDIV_EQ, 7844 REAL_LT_LDIV_EQ, REAL_LE_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 7845 7846 RW_TAC bool_ss [abs, max_def, min_def] THEN (* 2048 subgoals (each) *) 7847 ASM_REAL_ARITH_TAC THEN 7848 PRINT_TAC "stage work in INTER_BALLS_EQ_EMPTY"); 7849 7850(* ------------------------------------------------------------------------- *) 7851(* Every closed set is a G_Delta. *) 7852(* ------------------------------------------------------------------------- *) 7853 7854val CLOSED_AS_GDELTA = store_thm ("CLOSED_AS_GDELTA", 7855 ``!s:real->bool. closed s ==> ?g. COUNTABLE g /\ 7856 (!u. u IN g ==> open u) /\ (BIGINTER g = s)``, 7857 REPEAT STRIP_TAC THEN EXISTS_TAC 7858 ``{ BIGUNION { ball(x:real,inv(&n + &1)) | x IN s} | n IN univ(:num)}`` THEN 7859 SIMP_TAC std_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, NUM_COUNTABLE] THEN 7860 SIMP_TAC std_ss [FORALL_IN_IMAGE, OPEN_BIGUNION, OPEN_BALL] THEN 7861 MATCH_MP_TAC(SET_RULE 7862 ``(closure s = s) /\ s SUBSET t /\ t SUBSET closure s ==> (t = s)``) THEN 7863 ASM_REWRITE_TAC[CLOSURE_EQ] THEN CONJ_TAC THENL 7864 [SIMP_TAC std_ss [SUBSET_BIGINTER, FORALL_IN_IMAGE, IN_UNIV] THEN 7865 X_GEN_TAC ``n:num`` THEN SIMP_TAC std_ss [BIGUNION_IMAGE, SUBSET_DEF, GSPECIFICATION] THEN 7866 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN EXISTS_TAC ``x:real`` THEN 7867 ASM_REWRITE_TAC[CENTRE_IN_BALL, REAL_LT_INV_EQ] THEN 7868 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``1:real`` THEN CONJ_TAC THENL 7869 [REAL_ARITH_TAC, ALL_TAC] THEN REWRITE_TAC [REAL_LE_ADDL, REAL_POS], 7870 SIMP_TAC std_ss [SUBSET_DEF, CLOSURE_APPROACHABLE, BIGINTER_IMAGE, IN_UNIV] THEN 7871 X_GEN_TAC ``x:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, BIGUNION_IMAGE] THEN 7872 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 7873 POP_ASSUM MP_TAC THEN GEN_REWR_TAC LAND_CONV [REAL_ARCH_INV] THEN 7874 DISCH_THEN(X_CHOOSE_THEN ``n:num`` STRIP_ASSUME_TAC) THEN 7875 FIRST_X_ASSUM(MP_TAC o SPEC ``n:num``) THEN REWRITE_TAC[IN_BALL] THEN 7876 DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN 7877 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN 7878 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LT_TRANS) THEN 7879 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] REAL_LT_TRANS)) THEN 7880 MATCH_MP_TAC REAL_LT_INV2 THEN 7881 REWRITE_TAC[REAL_OF_NUM_ADD, REAL_LT] THEN CONJ_TAC THENL 7882 [FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ, GSYM REAL_LT], 7883 FULL_SIMP_TAC arith_ss [REAL_LT_ADDR]]]); 7884 7885(* ------------------------------------------------------------------------- *) 7886(* Compactness (the definition is the one based on convegent subsequences). *) 7887(* ------------------------------------------------------------------------- *) 7888 7889val compact = new_definition ("compact", 7890 ``compact s <=> !f:num->real. (!n. f(n) IN s) 7891 ==> ?l r. l IN s /\ (!m n:num. m < n ==> r(m) < r(n)) /\ 7892 ((f o r) --> l) sequentially``); 7893 7894val MONOTONE_BIGGER = store_thm ("MONOTONE_BIGGER", 7895 ``!r. (!m n. m < n ==> r(m) < r(n)) ==> !n:num. n <= r(n)``, 7896 GEN_TAC THEN DISCH_TAC THEN INDUCT_TAC THEN 7897 METIS_TAC[ZERO_LESS_EQ, ARITH_PROVE ``n <= m /\ m < p ==> SUC n <= p``, LT]); 7898 7899val LIM_SUBSEQUENCE = store_thm ("LIM_SUBSEQUENCE", 7900 ``!s r l. (!m n. m < n ==> r(m) < r(n)) /\ (s --> l) sequentially 7901 ==> (s o r --> l) sequentially``, 7902 SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN 7903 MESON_TAC[MONOTONE_BIGGER, LESS_EQ_TRANS]); 7904 7905val MONOTONE_SUBSEQUENCE = store_thm ("MONOTONE_SUBSEQUENCE", 7906 ``!s:num->real. ?r:num->num. 7907 (!m n. m < n ==> r(m) < r(n)) /\ 7908 ((!m n. m <= n ==> s(r(m)) <= s(r(n))) \/ 7909 (!m n. m <= n ==> s(r(n)) <= s(r(m))))``, 7910 GEN_TAC THEN 7911 ASM_CASES_TAC ``!n:num. ?p. n < p /\ !m. p <= m ==> s(m):real <= s(p)`` THEN 7912 POP_ASSUM MP_TAC THEN 7913 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_EXISTS_THM, NOT_IMP, DE_MORGAN_THM] THEN 7914 SIMP_TAC std_ss [RIGHT_OR_EXISTS_THM, SKOLEM_THM, REAL_NOT_LE, REAL_NOT_LT] THENL 7915 [ABBREV_TAC ``N = 0:num``, DISCH_THEN(X_CHOOSE_THEN ``N:num`` MP_TAC)] THEN 7916 DISCH_THEN(X_CHOOSE_THEN ``next:num->num`` STRIP_ASSUME_TAC) THEN 7917 (KNOW_TAC ``(?r. (r 0 = (next:num->num) (SUC N)) /\ 7918 (!n. r (SUC n) = (next:num->num) (r n)))`` THENL 7919 [RW_TAC std_ss [num_Axiom], ALL_TAC]) THEN 7920 STRIP_TAC THEN EXISTS_TAC ``r:num->num`` THENL 7921 [SUBGOAL_THEN ``!m:num n:num. r n <= m ==> s(m) <= s(r n):real`` 7922 ASSUME_TAC THEN TRY CONJ_TAC THEN TRY DISJ2_TAC THEN 7923 GEN_TAC THEN INDUCT_TAC THEN ASM_SIMP_TAC std_ss [LT, LE] THEN 7924 ASM_MESON_TAC[REAL_LE_TRANS, REAL_LE_REFL, LESS_IMP_LESS_OR_EQ, LESS_TRANS], 7925 SUBGOAL_THEN ``!n. N < (r:num->num) n`` ASSUME_TAC THEN 7926 TRY(CONJ_TAC THENL [GEN_TAC, DISJ1_TAC THEN GEN_TAC]) THEN 7927 INDUCT_TAC THEN ASM_SIMP_TAC std_ss [LT, LE] THEN 7928 TRY STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 7929 ASM_MESON_TAC[REAL_LT_REFL, LT_LE, LESS_LESS_EQ_TRANS, REAL_LE_REFL, 7930 REAL_LT_LE, REAL_LE_TRANS, LT]]); 7931 7932val CONVERGENT_BOUNDED_INCREASING = store_thm ("CONVERGENT_BOUNDED_INCREASING", 7933 ``!s:num->real b. (!m n. m <= n ==> s m <= s n) /\ (!n. abs(s n) <= b) 7934 ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e``, 7935 REPEAT STRIP_TAC THEN 7936 MP_TAC(SPEC ``\x. ?n. (s:num->real) n = x`` REAL_COMPLETE) THEN BETA_TAC THEN 7937 KNOW_TAC ``(?x:real n:num. s n = x) /\ (?M. !x. (?n. s n = x) ==> x <= M)`` THENL 7938 [ASM_MESON_TAC[REAL_ARITH ``abs(x:real) <= b ==> x <= b``], 7939 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 7940 DISCH_THEN (X_CHOOSE_TAC ``l:real``) THEN EXISTS_TAC ``l:real`` THEN 7941 POP_ASSUM MP_TAC THEN STRIP_TAC THEN 7942 X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN 7943 FIRST_X_ASSUM(MP_TAC o SPEC ``l - e:real``) THEN 7944 METIS_TAC[REAL_ARITH ``&0:real < e ==> ~(l <= l - e)``, 7945 REAL_ARITH ``x <= y /\ y <= l /\ ~(x <= l - e) ==> abs(y - l) < e:real``]); 7946 7947val CONVERGENT_BOUNDED_MONOTONE = store_thm ("CONVERGENT_BOUNDED_MONOTONE", 7948 ``!s:num->real b. (!n. abs(s n) <= b) /\ 7949 ((!m n. m <= n ==> s m <= s n) \/ 7950 (!m n. m <= n ==> s n <= s m)) 7951 ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e``, 7952 REPEAT STRIP_TAC THENL 7953 [ASM_MESON_TAC[CONVERGENT_BOUNDED_INCREASING], ALL_TAC] THEN 7954 MP_TAC(SPEC ``\n. -((s:num->real) n)`` CONVERGENT_BOUNDED_INCREASING) THEN 7955 ASM_SIMP_TAC std_ss [REAL_LE_NEG2, ABS_NEG] THEN 7956 ASM_MESON_TAC[REAL_ARITH ``abs(x - -l) = abs(-x - l:real)``]); 7957 7958val COMPACT_REAL_LEMMA = store_thm ("COMPACT_REAL_LEMMA", 7959 ``!s b. (!n:num. abs(s n) <= b) 7960 ==> ?l r. (!m n:num. m < n ==> r(m) < r(n)) /\ 7961 !e. &0:real < e ==> ?N. !n. N <= n ==> abs(s(r n) - l) < e``, 7962 REPEAT GEN_TAC THEN DISCH_TAC THEN 7963 KNOW_TAC ``?(r :num -> num) (l :real). 7964 (!(m :num) (n :num). m < n ==> r m < r n) /\ 7965 !(e :real). 7966 (0 :real) < e ==> 7967 ?(N :num). 7968 !(n :num). N <= n ==> abs ((s :num -> real) (r n) - l) < e`` THENL 7969 [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN 7970 MP_TAC(SPEC ``s:num->real`` MONOTONE_SUBSEQUENCE) THEN 7971 DISCH_THEN (X_CHOOSE_TAC ``r:num->num``) THEN EXISTS_TAC ``r:num->num`` THEN 7972 ASM_SIMP_TAC std_ss [] THEN POP_ASSUM MP_TAC THEN STRIP_TAC THENL 7973 [MP_TAC(SPEC ``\n. ((s:num->real) ((r:num->num) n))`` CONVERGENT_BOUNDED_INCREASING), 7974 MP_TAC(SPEC ``\n. -((s:num->real) ((r:num->num) n))`` CONVERGENT_BOUNDED_INCREASING)] THEN 7975 ASM_SIMP_TAC std_ss [REAL_LE_NEG2, ABS_NEG] THEN 7976 ASM_MESON_TAC[REAL_ARITH ``abs(x - -l) = abs(-x - l:real)``]); 7977 7978val COMPACT_LEMMA = store_thm ("COMPACT_LEMMA", 7979``!s. bounded s /\ (!n. (x:num->real) n IN s) 7980 ==> ?l:real r. (!m n. m < n ==> r m < (r:num->num) n) /\ 7981 !e. &0 < e ==> ?N. !n i. N <= n ==> abs(x(r n) - l) < e``, 7982 METIS_TAC [COMPACT_REAL_LEMMA, bounded_def]); 7983 7984val BOUNDED_CLOSED_IMP_COMPACT = store_thm ("BOUNDED_CLOSED_IMP_COMPACT", 7985 ``!s:real->bool. bounded s /\ closed s ==> compact s``, 7986 REPEAT STRIP_TAC THEN REWRITE_TAC[compact] THEN 7987 X_GEN_TAC ``x:num->real`` THEN DISCH_TAC THEN 7988 MP_TAC(ISPEC ``s:real->bool`` COMPACT_LEMMA) THEN 7989 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN 7990 MAP_EVERY EXISTS_TAC [``l:real``, ``r:num->num``] THEN 7991 ASM_SIMP_TAC std_ss [] THEN 7992 MATCH_MP_TAC(TAUT `(b ==> a) /\ b ==> a /\ b`) THEN 7993 REPEAT STRIP_TAC THENL 7994 [FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CLOSED_SEQUENTIAL_LIMITS]) THEN 7995 EXISTS_TAC ``(x:num->real) o (r:num->num)`` THEN 7996 ASM_SIMP_TAC std_ss [o_THM], ALL_TAC] THEN 7997 REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 7998 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 7999 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT, REAL_HALF, 8000 ARITH_PROVE ``0:num < n <=> ~(n = 0)``] THEN 8001 STRIP_TAC THEN EXISTS_TAC ``N:num`` THEN 8002 POP_ASSUM MP_TAC THEN 8003 REWRITE_TAC[dist] THEN REPEAT STRIP_TAC THEN 8004 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN 8005 GEN_REWR_TAC LAND_CONV [GSYM REAL_ADD_RID] THEN MATCH_MP_TAC REAL_LT_ADD2 THEN 8006 UNDISCH_TAC `` !n:num. N <= n ==> abs (x ((r:num->num) n) - l) < e / 2:real`` THEN 8007 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `n:num`) THEN 8008 ASM_REWRITE_TAC [] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 8009 METIS_TAC [REAL_LT_HALF1]); 8010 8011(* ------------------------------------------------------------------------- *) 8012(* Completeness. *) 8013(* ------------------------------------------------------------------------- *) 8014 8015val cauchy = new_definition ("cauchy", 8016 ``cauchy (s:num->real) <=> 8017 !e. &0 < e ==> ?N. !m n. m >= N /\ n >= N ==> dist(s m,s n) < e``); 8018 8019val complete = new_definition ("complete", 8020 ``complete s <=> 8021 !f:num->real. (!n. f n IN s) /\ cauchy f 8022 ==> ?l. l IN s /\ (f --> l) sequentially``); 8023 8024val CAUCHY = store_thm ("CAUCHY", 8025 ``!s:num->real. 8026 cauchy s <=> !e. &0 < e ==> ?N. !n. n >= N ==> dist(s n,s N) < e``, 8027 REPEAT GEN_TAC THEN REWRITE_TAC[cauchy, GREATER_EQ] THEN EQ_TAC THENL 8028 [MESON_TAC[LESS_EQ_REFL], DISCH_TAC] THEN 8029 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 8030 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN 8031 MESON_TAC[DIST_TRIANGLE_HALF_L]); 8032 8033val CONVERGENT_IMP_CAUCHY = store_thm ("CONVERGENT_IMP_CAUCHY", 8034 ``!s l. (s --> l) sequentially ==> cauchy s``, 8035 REWRITE_TAC[LIM_SEQUENTIALLY, cauchy] THEN 8036 REPEAT GEN_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 8037 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 8038 ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT] THEN 8039 ASM_MESON_TAC[GREATER_EQ, LESS_EQ_REFL, DIST_TRIANGLE_HALF_L]); 8040 8041val GREATER_EQ_REFL = store_thm ("GREATER_EQ_REFL", 8042 ``!m:num. m >= m``, 8043 REWRITE_TAC [GREATER_EQ, LESS_EQ_REFL]); 8044 8045val UPPER_BOUND_FINITE_SET_REAL = store_thm ("UPPER_BOUND_FINITE_SET_REAL", 8046 ``!f:('a->real) s. FINITE(s) ==> ?a. !x. x IN s ==> f(x) <= a``, 8047 REPEAT GEN_TAC THEN 8048 KNOW_TAC `` (?a. !x. x IN s ==> (f:'a->real) x <= a) = 8049 (\s. ?a. !x. x IN s ==> (f:'a->real) x <= a) s`` THENL 8050 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 8051 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 8052 REWRITE_TAC[IN_INSERT, NOT_IN_EMPTY] THEN 8053 MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]); 8054 8055val CAUCHY_IMP_BOUNDED = store_thm ("CAUCHY_IMP_BOUNDED", 8056 ``!s:num->real. cauchy s ==> bounded {y | ?n. y = s n}``, 8057 REWRITE_TAC[cauchy, bounded_def, GSPECIFICATION] THEN GEN_TAC THEN 8058 DISCH_THEN(MP_TAC o SPEC ``&1:real``) THEN REWRITE_TAC[REAL_LT_01] THEN 8059 DISCH_THEN(X_CHOOSE_THEN ``N:num`` (MP_TAC o SPEC ``N:num``)) THEN 8060 REWRITE_TAC[GREATER_EQ_REFL] THEN DISCH_TAC THEN 8061 SUBGOAL_THEN ``!n:num. N <= n ==> abs(s n :real) <= abs(s N) + &1:real`` 8062 ASSUME_TAC THENL 8063 [ASM_MESON_TAC[GREATER_EQ, dist, DIST_SYM, ABS_TRIANGLE_SUB, 8064 REAL_ARITH ``a <= b + c /\ c < &1 ==> a <= b + &1:real``], 8065 MP_TAC(ISPECL [``\n:num. abs(s n :real)``, ``0..N``] 8066 UPPER_BOUND_FINITE_SET_REAL) THEN 8067 SIMP_TAC std_ss [FINITE_NUMSEG, IN_NUMSEG, LESS_EQ_0, GSYM LEFT_EXISTS_IMP_THM] THEN 8068 ASM_MESON_TAC[LESS_EQ_CASES, 8069 REAL_ARITH ``x <= a \/ x <= b ==> x <= abs a + abs b:real``]]); 8070 8071val COMPACT_IMP_COMPLETE = store_thm ("COMPACT_IMP_COMPLETE", 8072 ``!s:real->bool. compact s ==> complete s``, 8073 GEN_TAC THEN REWRITE_TAC[complete, compact] THEN 8074 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `f:num->real`) THEN 8075 DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN 8076 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC ``l:real`` THEN 8077 FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] LIM_ADD)) THEN 8078 DISCH_THEN(MP_TAC o SPEC ``\n. (f:num->real)(n) - f(r n)``) THEN 8079 DISCH_THEN(MP_TAC o SPEC ``0:real``) THEN ASM_SIMP_TAC std_ss [o_THM] THEN 8080 SIMP_TAC std_ss [REAL_ADD_RID, REAL_SUB_ADD2, ETA_AX] THEN 8081 DISCH_THEN MATCH_MP_TAC THEN 8082 UNDISCH_TAC ``cauchy f`` THEN GEN_REWR_TAC LAND_CONV [cauchy] THEN 8083 SIMP_TAC std_ss [GE, LIM, SEQUENTIALLY, dist, REAL_SUB_RZERO] THEN 8084 SUBGOAL_THEN ``!n:num. n <= r(n)`` MP_TAC THENL [INDUCT_TAC, ALL_TAC] THEN 8085 ASM_MESON_TAC[LESS_EQ_TRANS, LESS_EQ_REFL, LT, LESS_EQ_LESS_TRANS, ZERO_LESS_EQ, LE_SUC_LT]); 8086 8087val COMPLETE_UNIV = store_thm ("COMPLETE_UNIV", 8088 ``complete univ(:real)``, 8089 REWRITE_TAC[complete, IN_UNIV] THEN X_GEN_TAC ``x:num->real`` THEN 8090 DISCH_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN 8091 DISCH_THEN(ASSUME_TAC o MATCH_MP BOUNDED_CLOSURE) THEN 8092 MP_TAC(ISPEC ``closure {y:real | ?n:num. y = x n}`` 8093 COMPACT_IMP_COMPLETE) THEN 8094 ASM_SIMP_TAC std_ss [BOUNDED_CLOSED_IMP_COMPACT, CLOSED_CLOSURE, complete] THEN 8095 DISCH_THEN(MP_TAC o SPEC ``x:num->real``) THEN 8096 KNOW_TAC ``(!n. x n IN closure {y | ?n. y = x n}) /\ cauchy x`` THENL 8097 [ALL_TAC, MESON_TAC[]] THEN 8098 ASM_SIMP_TAC std_ss [closure, GSPECIFICATION, IN_UNION] THEN MESON_TAC[]); 8099 8100val COMPLETE_EQ_CLOSED = store_thm ("COMPLETE_EQ_CLOSED", 8101 ``!s:real->bool. complete s <=> closed s``, 8102 GEN_TAC THEN EQ_TAC THENL 8103 [REWRITE_TAC[complete, CLOSED_LIMPT, LIMPT_SEQUENTIAL] THEN 8104 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN GEN_TAC THEN 8105 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN DISCH_TAC THEN 8106 GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `f:num->real`) THEN 8107 MESON_TAC[CONVERGENT_IMP_CAUCHY, IN_DELETE, LIM_UNIQUE, 8108 TRIVIAL_LIMIT_SEQUENTIALLY], 8109 REWRITE_TAC[complete, CLOSED_SEQUENTIAL_LIMITS] THEN DISCH_TAC THEN 8110 X_GEN_TAC ``f:num->real`` THEN STRIP_TAC THEN 8111 MP_TAC(REWRITE_RULE[complete] COMPLETE_UNIV) THEN 8112 DISCH_THEN(MP_TAC o SPEC ``f:num->real``) THEN 8113 ASM_REWRITE_TAC[IN_UNIV] THEN ASM_MESON_TAC[]]); 8114 8115val CONVERGENT_EQ_CAUCHY = store_thm ("CONVERGENT_EQ_CAUCHY", 8116 ``!s. (?l. (s --> l) sequentially) <=> cauchy s``, 8117 GEN_TAC THEN EQ_TAC THENL 8118 [METIS_TAC [LEFT_IMP_EXISTS_THM, CONVERGENT_IMP_CAUCHY], 8119 REWRITE_TAC[REWRITE_RULE[complete, IN_UNIV] COMPLETE_UNIV]]); 8120 8121val CONVERGENT_IMP_BOUNDED = store_thm ("CONVERGENT_IMP_BOUNDED", 8122 ``!s l. (s --> l) sequentially ==> bounded (IMAGE s univ(:num))``, 8123 SIMP_TAC std_ss [LEFT_FORALL_IMP_THM, CONVERGENT_EQ_CAUCHY] THEN 8124 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN 8125 REWRITE_TAC [bounded_def] THEN SET_TAC []); 8126 8127(* ------------------------------------------------------------------------- *) 8128(* Total boundedness. *) 8129(* ------------------------------------------------------------------------- *) 8130 8131val COMPACT_IMP_TOTALLY_BOUNDED = store_thm 8132 ("COMPACT_IMP_TOTALLY_BOUNDED", 8133 ``!s:real->bool. compact s 8134 ==> !e. &0 < e ==> ?k. FINITE k /\ k SUBSET s /\ 8135 s SUBSET (BIGUNION (IMAGE (\x. ball(x,e)) k))``, 8136 GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 8137 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN 8138 REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`, SUBSET_DEF] THEN 8139 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 8140 SUBGOAL_THEN 8141 ``?x:num->real. !n. x(n) IN s /\ !m. m < n ==> ~(dist(x(m),x(n)) < e)`` 8142 MP_TAC THENL 8143 [SUBGOAL_THEN 8144 ``?x:num->real. 8145 !n. x(n) = @y. y IN s /\ !m. m < n ==> ~(dist(x(m),y) < e)`` 8146 MP_TAC THENL 8147 [KNOW_TAC ``?(x :num -> real). !(n :num). x n = 8148 (\x n. @(y :real). y IN (s :real -> bool) /\ 8149 !(m :num). m < n ==> ~((dist (x m,y) :real) < (e :real))) x n`` THENL 8150 [ALL_TAC, METIS_TAC []] THEN 8151 MATCH_MP_TAC(MATCH_MP WF_REC WF_num) THEN SIMP_TAC std_ss [], ALL_TAC] THEN 8152 DISCH_THEN (X_CHOOSE_TAC ``x:num->real``) THEN EXISTS_TAC ``x:num->real`` THEN 8153 KNOW_TAC ``!(n :num). (\n. (x :num -> real) n IN (s :real -> bool) /\ 8154 !(m :num). m < n ==> ~((dist (x m,x n) :real) < (e :real))) n`` THENL 8155 [ALL_TAC, METIS_TAC []] THEN 8156 MATCH_MP_TAC COMPLETE_INDUCTION THEN X_GEN_TAC ``n:num`` THEN 8157 BETA_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SPEC ``n:num``) THEN STRIP_TAC THEN 8158 CONV_TAC SELECT_CONV THEN 8159 FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (x:num->real) {m | m < n}``) THEN 8160 SIMP_TAC std_ss [IMAGE_FINITE, FINITE_NUMSEG_LT, NOT_FORALL_THM, NOT_IMP] THEN 8161 SIMP_TAC std_ss [IN_BIGUNION, IN_IMAGE, GSPECIFICATION] THEN METIS_TAC[IN_BALL], 8162 ALL_TAC] THEN 8163 SIMP_TAC std_ss [compact, NOT_FORALL_THM] THEN 8164 DISCH_THEN (X_CHOOSE_TAC ``x:num->real``) THEN EXISTS_TAC ``x:num->real`` THEN 8165 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IMP, FORALL_AND_THM] THEN 8166 STRIP_TAC THEN ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN REPEAT STRIP_TAC THEN 8167 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 8168 FIRST_X_ASSUM(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN 8169 REWRITE_TAC[cauchy] THEN DISCH_THEN(MP_TAC o SPEC ``e:real``) THEN 8170 ASM_SIMP_TAC std_ss [o_THM, NOT_EXISTS_THM, NOT_IMP, NOT_FORALL_THM, NOT_IMP] THEN 8171 X_GEN_TAC ``N:num`` THEN MAP_EVERY EXISTS_TAC [``N:num``, ``SUC N``] THEN 8172 CONJ_TAC THENL [ARITH_TAC, ASM_MESON_TAC[LT]]); 8173 8174(* ------------------------------------------------------------------------- *) 8175(* Heine-Borel theorem (following Burkill & Burkill vol. 2) *) 8176(* ------------------------------------------------------------------------- *) 8177 8178val HEINE_BOREL_LEMMA = store_thm ("HEINE_BOREL_LEMMA", 8179 ``!s:real->bool. compact s 8180 ==> !t. s SUBSET (BIGUNION t) /\ (!b. b IN t ==> open b) 8181 ==> ?e. &0 < e /\ 8182 !x. x IN s ==> ?b. b IN t /\ ball(x,e) SUBSET b``, 8183 GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 8184 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN 8185 DISCH_THEN(CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 8186 DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC ``&1 / (&n + &1:real)``) THEN 8187 SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT_01, REAL_ARITH ``x <= y ==> x < y + &1:real``, 8188 FORALL_AND_THM, REAL_POS, NOT_FORALL_THM, NOT_IMP, SKOLEM_THM, compact] THEN 8189 DISCH_THEN (X_CHOOSE_TAC ``f:num->real``) THEN 8190 EXISTS_TAC ``f:num->real`` THEN POP_ASSUM MP_TAC THEN 8191 SIMP_TAC std_ss [NOT_EXISTS_THM] THEN 8192 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN 8193 DISCH_TAC THEN MAP_EVERY X_GEN_TAC [``l:real``, ``r:num->num``] THEN 8194 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 8195 SUBGOAL_THEN ``?b:real->bool. l IN b /\ b IN t`` STRIP_ASSUME_TAC THENL 8196 [ASM_MESON_TAC[SUBSET_DEF, IN_BIGUNION], ALL_TAC] THEN 8197 SUBGOAL_THEN ``?e. &0 < e /\ !z:real. dist(z,l) < e ==> z IN b`` 8198 STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[open_def], ALL_TAC] THEN 8199 UNDISCH_TAC ``(f o r:num->num --> l:real) sequentially`` THEN DISCH_TAC THEN 8200 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LIM_SEQUENTIALLY]) THEN 8201 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN 8202 SUBGOAL_THEN ``&0 < e / &2:real`` (fn th => 8203 REWRITE_TAC [th, o_THM] THEN MP_TAC(ONCE_REWRITE_RULE [REAL_ARCH_INV] th)) 8204 THENL [ASM_REWRITE_TAC[REAL_HALF], ALL_TAC] THEN 8205 DISCH_THEN(X_CHOOSE_THEN ``N1:num`` STRIP_ASSUME_TAC) THEN 8206 DISCH_THEN(X_CHOOSE_THEN ``N2:num`` STRIP_ASSUME_TAC) THEN 8207 FIRST_X_ASSUM(MP_TAC o SPECL 8208 [``(r:num->num)(N1 + N2)``, ``b:real->bool``]) THEN 8209 ASM_REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 8210 FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_R THEN 8211 EXISTS_TAC ``(f:num->real)(r(N1 + N2:num))`` THEN CONJ_TAC THENL 8212 [ALL_TAC, FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC] THEN 8213 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [IN_BALL]) THEN 8214 MATCH_MP_TAC(REAL_ARITH ``a <= b ==> x < a ==> x < b:real``) THEN 8215 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``inv(&N1:real)`` THEN 8216 ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE] THEN REWRITE_TAC[real_div, REAL_MUL_LID] THEN 8217 MATCH_MP_TAC REAL_LE_INV2 THEN 8218 REWRITE_TAC[REAL_OF_NUM_ADD, REAL_OF_NUM_LE, REAL_LT] THEN 8219 ASM_MESON_TAC[ARITH_PROVE ``(~(n = 0) ==> 0 < n:num)``, LESS_EQ_ADD, MONOTONE_BIGGER, 8220 LESS_IMP_LESS_OR_EQ, LESS_EQ_TRANS]); 8221 8222val COMPACT_IMP_HEINE_BOREL = store_thm 8223 ("COMPACT_IMP_HEINE_BOREL", 8224 ``!s. compact (s:real->bool) 8225 ==> !f. (!t. t IN f ==> open t) /\ s SUBSET (BIGUNION f) 8226 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (BIGUNION f')``, 8227 REPEAT STRIP_TAC THEN 8228 FIRST_ASSUM(MP_TAC o SPEC ``f:(real->bool)->bool`` o 8229 MATCH_MP HEINE_BOREL_LEMMA) THEN ASM_REWRITE_TAC[] THEN 8230 DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 8231 DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 8232 SIMP_TAC std_ss [SKOLEM_THM, SUBSET_DEF, IN_BALL] THEN 8233 DISCH_THEN(X_CHOOSE_TAC ``B:real->real->bool``) THEN 8234 FIRST_ASSUM(MP_TAC o SPEC ``e:real`` o 8235 MATCH_MP COMPACT_IMP_TOTALLY_BOUNDED) THEN 8236 ASM_SIMP_TAC std_ss [BIGUNION_IMAGE, SUBSET_DEF, GSPECIFICATION] THEN 8237 REWRITE_TAC[IN_BIGUNION, IN_BALL] THEN 8238 DISCH_THEN(X_CHOOSE_THEN ``k:real->bool`` STRIP_ASSUME_TAC) THEN 8239 EXISTS_TAC ``IMAGE (B:real->real->bool) k`` THEN 8240 ASM_SIMP_TAC std_ss [IMAGE_FINITE, SUBSET_DEF, IN_IMAGE, LEFT_IMP_EXISTS_THM] THEN 8241 ASM_MESON_TAC[IN_BALL]); 8242 8243(* ------------------------------------------------------------------------- *) 8244(* Bolzano-Weierstrass property. *) 8245(* ------------------------------------------------------------------------- *) 8246 8247val HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS = store_thm 8248 ("HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS", 8249 ``!s:real->bool. 8250 (!f. (!t. t IN f ==> open t) /\ s SUBSET (BIGUNION f) 8251 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (BIGUNION f')) 8252 ==> !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t``, 8253 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM, limit_point_of] THEN REPEAT GEN_TAC THEN 8254 ONCE_REWRITE_TAC[TAUT `a ==> b /\ c ==> d <=> c ==> ~d ==> a ==> ~b`] THEN 8255 KNOW_TAC ``t SUBSET s 8256 ==> (!x. ?t'. ~(x IN s:real->bool /\ 8257 (x IN t' /\ open t' ==> (?y. ~(y = x) /\ y IN t /\ y IN t')))) 8258 ==> (!f. (!t. t IN f ==> open t) /\ s SUBSET BIGUNION f 8259 ==> (?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET BIGUNION f')) 8260 ==> ~INFINITE t`` THENL 8261 [ALL_TAC, SIMP_TAC std_ss [NOT_FORALL_THM, NOT_EXISTS_THM, RIGHT_AND_FORALL_THM] THEN 8262 METIS_TAC []] THEN 8263 DISCH_TAC THEN SIMP_TAC std_ss [SKOLEM_THM] THEN 8264 DISCH_THEN(X_CHOOSE_TAC ``f:real->real->bool``) THEN 8265 DISCH_THEN(MP_TAC o SPEC 8266 ``{t:real->bool | ?x:real. x IN s /\ (t = f x)}``) THEN 8267 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_BIGUNION, NOT_IMP] THEN 8268 KNOW_TAC ``(!t. (?x. x IN s:real->bool /\ (t = f x)) ==> open t) /\ 8269 (!x. x IN s ==> ?s'. x IN s' /\ ?x. x IN s /\ (s' = f x))`` THENL 8270 [METIS_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 8271 DISCH_THEN(X_CHOOSE_THEN ``g:(real->bool)->bool`` STRIP_ASSUME_TAC) THEN 8272 MATCH_MP_TAC SUBSET_FINITE_I THEN 8273 EXISTS_TAC ``{x:real | x IN t /\ (f(x):real->bool) IN g}`` THEN 8274 CONJ_TAC THENL 8275 [MATCH_MP_TAC FINITE_IMAGE_INJ_GENERAL THEN ASM_MESON_TAC[SUBSET_DEF], 8276 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN X_GEN_TAC ``u:real`` THEN 8277 DISCH_TAC THEN SUBGOAL_THEN ``(u:real) IN s`` ASSUME_TAC THEN 8278 ASM_MESON_TAC[SUBSET_DEF]]); 8279 8280(* ------------------------------------------------------------------------- *) 8281(* Complete the chain of compactness variants. *) 8282(* ------------------------------------------------------------------------- *) 8283 8284val BOLZANO_WEIERSTRASS_IMP_BOUNDED = store_thm ("BOLZANO_WEIERSTRASS_IMP_BOUNDED", 8285 ``!s:real->bool. 8286 (!t. INFINITE t /\ t SUBSET s ==> ?x. x limit_point_of t) 8287 ==> bounded s``, 8288 GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 8289 SIMP_TAC std_ss [compact, bounded_def] THEN 8290 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_EXISTS_THM, SKOLEM_THM, NOT_IMP] THEN 8291 REWRITE_TAC[REAL_NOT_LE] THEN 8292 DISCH_THEN(X_CHOOSE_TAC ``beyond:real->real``) THEN 8293 KNOW_TAC ``?f. (f(0) = beyond(&0)) /\ 8294 (!n. f(SUC n) = beyond(abs(f n) + &1):real)`` THENL 8295 [RW_TAC std_ss [num_Axiom], ALL_TAC] THEN 8296 DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN 8297 EXISTS_TAC ``IMAGE (x:num->real) UNIV`` THEN 8298 SUBGOAL_THEN 8299 ``!m n. m < n ==> abs((x:num->real) m) + &1 < abs(x n)`` 8300 ASSUME_TAC THENL 8301 [GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[LT] THEN 8302 ASM_MESON_TAC[REAL_LT_TRANS, REAL_ARITH ``b < b + &1:real``], 8303 ALL_TAC] THEN 8304 SUBGOAL_THEN ``!m n. ~(m = n) ==> &1 < dist((x:num->real) m,x n)`` 8305 ASSUME_TAC THENL 8306 [REPEAT GEN_TAC THEN REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC 8307 (SPECL [``m:num``, ``n:num``] LT_CASES) THEN 8308 ASM_MESON_TAC[dist, LT_CASES, ABS_TRIANGLE_SUB, ABS_SUB, 8309 REAL_ARITH ``x + &1 < y /\ y <= x + d ==> &1 < d:real``], 8310 ALL_TAC] THEN 8311 REPEAT CONJ_TAC THENL 8312 [ASM_MESON_TAC[IMAGE_11_INFINITE, num_INFINITE, DIST_REFL, 8313 REAL_ARITH ``~(&1 < &0:real)``], 8314 SIMP_TAC std_ss [SUBSET_DEF, IN_IMAGE, IN_UNIV, LEFT_IMP_EXISTS_THM] THEN 8315 INDUCT_TAC THEN METIS_TAC[], ALL_TAC] THEN 8316 X_GEN_TAC ``l:real`` THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN 8317 SIMP_TAC std_ss [IN_IMAGE, IN_UNIV, GSYM LEFT_EXISTS_AND_THM] THEN 8318 KNOW_TAC ``~(!(e :real). (0 :real) < e ==> 8319 (?(x'' :num) (x' :real). (x' = (x :num -> real) x'') /\ (x' <> (l :real)) /\ 8320 ((dist (x',l) :real) < e)))`` THENL 8321 [ALL_TAC, METIS_TAC []] THEN SIMP_TAC std_ss [UNWIND_THM2] THEN 8322 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 8323 FIRST_ASSUM(MP_TAC o SPEC ``&1 / &2:real``) THEN 8324 REWRITE_TAC [METIS [REAL_HALF_BETWEEN] ``0 < 1 / 2:real``] THEN 8325 DISCH_THEN(X_CHOOSE_THEN ``k:num`` STRIP_ASSUME_TAC) THEN 8326 FIRST_X_ASSUM(MP_TAC o SPEC ``dist((x:num->real) k,l)``) THEN 8327 ASM_SIMP_TAC std_ss [DIST_POS_LT] THEN 8328 X_GEN_TAC ``m:num`` THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 8329 ASM_CASES_TAC ``m:num = k`` THEN 8330 ASM_MESON_TAC[DIST_TRIANGLE_HALF_L, REAL_LT_TRANS, REAL_LT_REFL]); 8331 8332val INF_FINITE_LEMMA = store_thm ("INF_FINITE_LEMMA", 8333 ``!s. FINITE s /\ ~(s = {}) ==> ?b:real. b IN s /\ !x. x IN s ==> b <= x``, 8334 REWRITE_TAC[CONJ_EQ_IMP] THEN 8335 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 8336 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 8337 REWRITE_TAC[NOT_INSERT_EMPTY, IN_INSERT] THEN 8338 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN 8339 MESON_TAC[REAL_LE_TOTAL, REAL_LE_TRANS]); 8340 8341val INF_FINITE = store_thm ("INF_FINITE", 8342 ``!s:real->bool. FINITE s /\ ~(s = {}) ==> (inf s) IN s /\ !x. x IN s ==> inf s <= x``, 8343 GEN_TAC THEN DISCH_TAC THEN 8344 FIRST_ASSUM(MP_TAC o MATCH_MP INF_FINITE_LEMMA) THEN 8345 ASM_MESON_TAC[REAL_LE_ANTISYM, REAL_LE_TOTAL, INF]); 8346 8347val REAL_LE_INF_FINITE = store_thm ("REAL_LE_INF_FINITE", 8348 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (a <= inf s <=> !x. x IN s ==> a <= x)``, 8349 METIS_TAC[INF_FINITE, REAL_LE_TRANS]); 8350 8351val REAL_INF_LE_FINITE = store_thm ("REAL_INF_LE_FINITE", 8352 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (inf s <= a <=> ?x. x IN s /\ x <= a)``, 8353 MESON_TAC[INF_FINITE, REAL_LE_TRANS]); 8354 8355val REAL_LT_INF_FINITE = store_thm ("REAL_LT_INF_FINITE", 8356 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (a < inf s <=> !x. x IN s ==> a < x)``, 8357 MESON_TAC[INF_FINITE, REAL_LTE_TRANS]); 8358 8359val REAL_INF_LT_FINITE = store_thm ("REAL_INF_LT_FINITE", 8360 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (inf s < a <=> ?x. x IN s /\ x < a)``, 8361 MESON_TAC[INF_FINITE, REAL_LET_TRANS]); 8362 8363val SEQUENCE_INFINITE_LEMMA = store_thm ("SEQUENCE_INFINITE_LEMMA", 8364 ``!f l. (!n. ~(f(n) = l)) /\ (f --> l) sequentially 8365 ==> INFINITE {y:real | ?n. y = f n}``, 8366 REPEAT STRIP_TAC THEN MP_TAC(ISPEC 8367 ``IMAGE (\y:real. dist(y,l)) {y | ?n:num. y = f n}`` INF_FINITE) THEN 8368 ASM_SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, IN_IMAGE, IMAGE_FINITE, GSPECIFICATION] THEN 8369 ASM_MESON_TAC[LIM_SEQUENTIALLY, LESS_EQ_REFL, REAL_NOT_LE, DIST_POS_LT]); 8370 8371val LE_1 = store_thm ("LE_1", 8372 ``(!n:num. ~(n = 0) ==> 0 < n) /\ 8373 (!n:num. ~(n = 0) ==> 1 <= n) /\ 8374 (!n:num. 0 < n ==> ~(n = 0)) /\ 8375 (!n:num. 0 < n ==> 1 <= n) /\ 8376 (!n:num. 1 <= n ==> 0 < n) /\ 8377 (!n:num. 1 <= n ==> ~(n = 0))``, 8378 REWRITE_TAC[LT_NZ, GSYM NOT_LESS, ONE, LT]); 8379 8380val LIMPT_OF_SEQUENCE_SUBSEQUENCE = store_thm ("LIMPT_OF_SEQUENCE_SUBSEQUENCE", 8381 ``!f:num->real l. 8382 l limit_point_of (IMAGE f univ(:num)) 8383 ==> ?r. (!m n. m < n ==> r(m) < r(n)) /\ ((f o r) --> l) sequentially``, 8384 REPEAT STRIP_TAC THEN 8385 FIRST_ASSUM(MP_TAC o REWRITE_RULE [LIMPT_APPROACHABLE]) THEN 8386 DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC 8387 ``inf((inv(&n + &1:real)) INSERT IMAGE (\k. dist((f:num->real) k,l)) 8388 {k | k IN (0:num)..n /\ ~(f k = l)})``) THEN 8389 SIMP_TAC std_ss [REAL_LT_INF_FINITE, FINITE_INSERT, NOT_INSERT_EMPTY, 8390 FINITE_RESTRICT, FINITE_NUMSEG, IMAGE_FINITE] THEN 8391 SIMP_TAC std_ss [FORALL_IN_INSERT, EXISTS_IN_IMAGE, FORALL_IN_IMAGE, IN_UNIV] THEN 8392 SIMP_TAC std_ss [REAL_LT_INV_EQ, METIS [REAL_LT, REAL_OF_NUM_ADD, GSYM ADD1, LESS_0] 8393 ``&0 < &n + &1:real``] THEN 8394 SIMP_TAC std_ss [FORALL_AND_THM, FORALL_IN_GSPEC, GSYM DIST_NZ, SKOLEM_THM] THEN 8395 DISCH_THEN(X_CHOOSE_THEN ``nn:num->num`` STRIP_ASSUME_TAC) THEN 8396 KNOW_TAC ``?r:num->num. (r 0 = nn 0) /\ (!n. r (SUC n) = nn(r n))`` THENL 8397 [RW_TAC std_ss [num_Axiom], ALL_TAC] THEN 8398 STRIP_TAC THEN EXISTS_TAC ``r:num->num`` THEN 8399 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL 8400 [ONCE_REWRITE_TAC [METIS [] 8401 `` (r:num->num) m < r n = (\m n. r m < r n) m n``] THEN 8402 MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN CONJ_TAC THENL 8403 [METIS_TAC [LESS_TRANS], ALL_TAC] THEN 8404 X_GEN_TAC ``n:num`` THEN ASM_REWRITE_TAC[] THEN 8405 FIRST_X_ASSUM(MP_TAC o SPECL 8406 [``(r:num->num) n``, ``(nn:num->num)(r(n:num))``]) THEN 8407 ASM_SIMP_TAC arith_ss [IN_NUMSEG, ZERO_LESS_EQ, REAL_LT_REFL], 8408 DISCH_THEN(ASSUME_TAC o MATCH_MP MONOTONE_BIGGER)] THEN 8409 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 8410 X_GEN_TAC ``e:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_ARCH_INV] THEN 8411 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 8412 POP_ASSUM MP_TAC THEN STRIP_TAC THEN 8413 ONCE_REWRITE_TAC [METIS [] ``!n:num. (N <= n ==> dist ((f o r) n,l) < e) = 8414 (\n. N <= n ==> dist ((f o r) n,l) < e) n``] THEN 8415 MATCH_MP_TAC INDUCTION THEN ASM_SIMP_TAC std_ss [CONJUNCT1 LE] THEN 8416 X_GEN_TAC ``n:num`` THEN DISCH_THEN(K ALL_TAC) THEN DISCH_TAC THEN 8417 ASM_SIMP_TAC std_ss [o_THM] THEN MATCH_MP_TAC REAL_LT_TRANS THEN 8418 EXISTS_TAC ``inv(&((r:num->num) n) + &1:real)`` THEN ASM_REWRITE_TAC[] THEN 8419 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``inv(&N:real)`` THEN 8420 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN 8421 ASM_SIMP_TAC std_ss [REAL_OF_NUM_LE, REAL_LT, LE_1, REAL_OF_NUM_ADD] THEN 8422 MATCH_MP_TAC(ARITH_PROVE ``N <= SUC n /\ n <= r n ==> N <= r n + 1``) THEN 8423 ASM_REWRITE_TAC[]); 8424 8425val SEQUENCE_UNIQUE_LIMPT = store_thm ("SEQUENCE_UNIQUE_LIMPT", 8426 ``!f l l':real. 8427 (f --> l) sequentially /\ l' limit_point_of {y | ?n. y = f n} 8428 ==> (l' = l)``, 8429 REWRITE_TAC[SET_RULE ``{y | ?n. y = f n} = IMAGE f univ(:num)``] THEN 8430 REPEAT STRIP_TAC THEN 8431 FIRST_X_ASSUM(MP_TAC o MATCH_MP LIMPT_OF_SEQUENCE_SUBSEQUENCE) THEN 8432 DISCH_THEN(X_CHOOSE_THEN ``r:num->num`` STRIP_ASSUME_TAC) THEN 8433 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN 8434 EXISTS_TAC ``(f:num->real) o (r:num->num)`` THEN 8435 ASM_SIMP_TAC std_ss [TRIVIAL_LIMIT_SEQUENTIALLY, LIM_SUBSEQUENCE]); 8436 8437val BOLZANO_WEIERSTRASS_IMP_CLOSED = store_thm ("BOLZANO_WEIERSTRASS_IMP_CLOSED", 8438 ``!s:real->bool. 8439 (!t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t) 8440 ==> closed s``, 8441 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS] THEN 8442 MAP_EVERY X_GEN_TAC [``f:num->real``, ``l:real``] THEN 8443 DISCH_TAC THEN 8444 MAP_EVERY (MP_TAC o ISPECL [``f:num->real``, ``l:real``]) 8445 [SEQUENCE_UNIQUE_LIMPT, SEQUENCE_INFINITE_LEMMA] THEN 8446 MATCH_MP_TAC(TAUT 8447 `(~d ==> a /\ ~(b /\ c)) ==> (a ==> b) ==> c ==> d`) THEN 8448 DISCH_TAC THEN CONJ_TAC THENL [ASM_MESON_TAC[], STRIP_TAC] THEN 8449 FIRST_X_ASSUM(MP_TAC o SPEC ``{y:real | ?n:num. y = f n}``) THEN 8450 ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL 8451 [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION], 8452 ABBREV_TAC ``t = {y:real | ?n:num. y = f n}``] THEN 8453 ASM_MESON_TAC[]); 8454 8455(* ------------------------------------------------------------------------- *) 8456(* Hence express everything as an equivalence. *) 8457(* ------------------------------------------------------------------------- *) 8458 8459val COMPACT_EQ_HEINE_BOREL = store_thm ("COMPACT_EQ_HEINE_BOREL", 8460 ``!s:real->bool. compact s <=> 8461 !f. (!t. t IN f ==> open t) /\ s SUBSET (BIGUNION f) 8462 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (BIGUNION f')``, 8463 GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [COMPACT_IMP_HEINE_BOREL] THEN 8464 DISCH_THEN(MP_TAC o MATCH_MP HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS) THEN 8465 DISCH_TAC THEN MATCH_MP_TAC BOUNDED_CLOSED_IMP_COMPACT THEN 8466 ASM_MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED, 8467 BOLZANO_WEIERSTRASS_IMP_CLOSED]); 8468 8469val COMPACT_EQ_BOLZANO_WEIERSTRASS = store_thm ("COMPACT_EQ_BOLZANO_WEIERSTRASS", 8470 ``!s:real->bool. compact s <=> 8471 !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t``, 8472 GEN_TAC THEN EQ_TAC THENL 8473 [SIMP_TAC std_ss [COMPACT_EQ_HEINE_BOREL, HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS], 8474 MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED, BOLZANO_WEIERSTRASS_IMP_CLOSED, 8475 BOUNDED_CLOSED_IMP_COMPACT]]); 8476 8477val COMPACT_EQ_BOUNDED_CLOSED = store_thm ("COMPACT_EQ_BOUNDED_CLOSED", 8478``!s:real->bool. compact s <=> bounded s /\ closed s``, 8479 GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSED_IMP_COMPACT] THEN 8480 MESON_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS, BOLZANO_WEIERSTRASS_IMP_BOUNDED, 8481 BOLZANO_WEIERSTRASS_IMP_CLOSED]); 8482 8483val COMPACT_IMP_BOUNDED = store_thm ("COMPACT_IMP_BOUNDED", 8484 ``!s. compact s ==> bounded s``, 8485 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED]); 8486 8487val COMPACT_IMP_CLOSED = store_thm ("COMPACT_IMP_CLOSED", 8488 ``!s. compact s ==> closed s``, 8489 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED]); 8490 8491val COMPACT_SEQUENCE_WITH_LIMIT = store_thm ("COMPACT_SEQUENCE_WITH_LIMIT", 8492 ``!f l:real. 8493 (f --> l) sequentially ==> compact (l INSERT IMAGE f univ(:num))``, 8494 REPEAT STRIP_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN 8495 REWRITE_TAC[BOUNDED_INSERT] THEN CONJ_TAC THENL 8496 [ASM_MESON_TAC[CONVERGENT_IMP_BOUNDED], 8497 SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_INSERT, IN_INSERT] THEN 8498 SIMP_TAC std_ss [IMAGE_DEF, IN_UNIV, SET_RULE ``{f x | x IN s} = 8499 {y | ?x. x IN s /\ (y = f x)}``] THEN REPEAT STRIP_TAC THEN DISJ1_TAC THEN 8500 MATCH_MP_TAC SEQUENCE_UNIQUE_LIMPT THEN METIS_TAC[]]); 8501 8502val CLOSED_IN_COMPACT = store_thm ("CLOSED_IN_COMPACT", 8503 ``!s t:real->bool. 8504 compact s /\ closed_in (subtopology euclidean s) t 8505 ==> compact t``, 8506 SIMP_TAC std_ss [CONJ_EQ_IMP, COMPACT_EQ_BOUNDED_CLOSED, CLOSED_IN_CLOSED_EQ] THEN 8507 MESON_TAC[BOUNDED_SUBSET]); 8508 8509val CLOSED_IN_COMPACT_EQ = store_thm ("CLOSED_IN_COMPACT_EQ", 8510 ``!s t. compact s 8511 ==> (closed_in (subtopology euclidean s) t <=> 8512 compact t /\ t SUBSET s)``, 8513 MESON_TAC[CLOSED_IN_CLOSED_EQ, COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_SUBSET]); 8514 8515(* ------------------------------------------------------------------------- *) 8516(* A version of Heine-Borel for subtopology. *) 8517(* ------------------------------------------------------------------------- *) 8518 8519val COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY = store_thm ("COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY", 8520 ``!s:real->bool. compact s <=> 8521 (!f. (!t. t IN f ==> open_in(subtopology euclidean s) t) /\ 8522 s SUBSET BIGUNION f 8523 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET BIGUNION f')``, 8524 GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN EQ_TAC THEN 8525 DISCH_TAC THEN X_GEN_TAC ``f:(real->bool)->bool`` THENL 8526 [REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_TAC THEN 8527 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 8528 SIMP_TAC std_ss [SKOLEM_THM] THEN 8529 DISCH_THEN(CONJUNCTS_THEN2 8530 (X_CHOOSE_TAC ``m:(real->bool)->(real->bool)``) ASSUME_TAC) THEN 8531 FIRST_X_ASSUM(MP_TAC o SPEC 8532 ``IMAGE (m:(real->bool)->(real->bool)) f``) THEN 8533 ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 8534 KNOW_TAC ``(s :real -> bool) SUBSET 8535 BIGUNION 8536 (IMAGE (m :(real -> bool) -> real -> bool) 8537 (f :(real -> bool) -> bool))`` THENL 8538 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 8539 DISCH_THEN(X_CHOOSE_THEN ``f':(real->bool)->bool`` STRIP_ASSUME_TAC) THEN 8540 EXISTS_TAC ``IMAGE (\t:real->bool. s INTER t) f'`` THEN 8541 ASM_SIMP_TAC std_ss [IMAGE_FINITE, BIGUNION_IMAGE, SUBSET_DEF, FORALL_IN_IMAGE] THEN 8542 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 8543 UNDISCH_TAC ``f' SUBSET IMAGE (m :(real -> bool) -> real -> bool) f`` THEN 8544 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_IMAGE]) THEN 8545 STRIP_TAC THEN ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN ASM_MESON_TAC[SUBSET_DEF], 8546 DISCH_TAC THEN 8547 FIRST_X_ASSUM(MP_TAC o SPEC ``{s INTER t:real->bool | t IN f}``) THEN 8548 SIMP_TAC std_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, OPEN_IN_OPEN, BIGUNION_IMAGE] THEN 8549 KNOW_TAC ``(!(t :real -> bool). 8550 t IN (f :(real -> bool) -> bool) ==> 8551 ?(t' :real -> bool). 8552 (open t' :bool) /\ ((s :real -> bool) INTER t = s INTER t')) /\ 8553 s SUBSET {y | ?(t :real -> bool). t IN f /\ y IN s INTER t}`` THENL 8554 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 8555 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN 8556 SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE, BIGUNION_IMAGE] THEN 8557 STRIP_TAC THEN EXISTS_TAC ``f' :(real -> bool) -> bool`` THEN 8558 ASM_SET_TAC []]); 8559 8560(* ------------------------------------------------------------------------- *) 8561(* More easy lemmas. *) 8562(* ------------------------------------------------------------------------- *) 8563 8564val COMPACT_CLOSURE = store_thm ("COMPACT_CLOSURE", 8565 ``!s. compact(closure s) <=> bounded s``, 8566 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE, BOUNDED_CLOSURE_EQ]); 8567 8568val BOLZANO_WEIERSTRASS_CONTRAPOS = store_thm ("BOLZANO_WEIERSTRASS_CONTRAPOS", 8569 ``!s t:real->bool. 8570 compact s /\ t SUBSET s /\ 8571 (!x. x IN s ==> ~(x limit_point_of t)) 8572 ==> FINITE t``, 8573 REWRITE_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS] THEN MESON_TAC[]); 8574 8575val DISCRETE_BOUNDED_IMP_FINITE = store_thm ("DISCRETE_BOUNDED_IMP_FINITE", 8576 ``!s:real->bool e. &0 < e /\ 8577 (!x y. x IN s /\ y IN s /\ abs(y - x) < e ==> (y = x)) /\ 8578 bounded s ==> FINITE s``, 8579 REPEAT STRIP_TAC THEN 8580 SUBGOAL_THEN ``compact(s:real->bool)`` MP_TAC THENL 8581 [ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN 8582 ASM_MESON_TAC[DISCRETE_IMP_CLOSED], 8583 DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_HEINE_BOREL)] THEN 8584 DISCH_THEN(MP_TAC o SPEC ``IMAGE (\x:real. ball(x,e)) s``) THEN 8585 SIMP_TAC std_ss [FORALL_IN_IMAGE, OPEN_BALL, BIGUNION_IMAGE, GSPECIFICATION] THEN 8586 KNOW_TAC ``(s :real -> bool) SUBSET 8587 {y | ?(x :real). x IN s /\ y IN ball (x,(e :real))}`` THENL 8588 [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN ASM_MESON_TAC[CENTRE_IN_BALL], 8589 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 8590 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`]] THEN 8591 SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE] THEN 8592 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 8593 SUBGOAL_THEN ``s:real->bool = t`` (fn th => ASM_REWRITE_TAC[th]) THEN 8594 MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN 8595 REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 8596 UNDISCH_TAC ``s SUBSET BIGUNION (IMAGE (\x. ball (x,e)) t)`` THEN 8597 GEN_REWR_TAC (LAND_CONV o RAND_CONV) [BIGUNION_IMAGE] THEN 8598 DISCH_THEN(MP_TAC o SPEC ``x:real`` o REWRITE_RULE [SUBSET_DEF]) THEN 8599 ASM_SIMP_TAC std_ss [GSPECIFICATION, IN_BALL, dist] THEN ASM_MESON_TAC[SUBSET_DEF]); 8600 8601val BOLZANO_WEIERSTRASS = store_thm ("BOLZANO_WEIERSTRASS", 8602 ``!s:real->bool. bounded s /\ INFINITE s ==> ?x. x limit_point_of s``, 8603 GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 8604 FIRST_ASSUM(ASSUME_TAC o MATCH_MP NO_LIMIT_POINT_IMP_CLOSED) THEN 8605 STRIP_TAC THEN 8606 MP_TAC(ISPEC ``s:real->bool`` COMPACT_EQ_BOLZANO_WEIERSTRASS) THEN 8607 ASM_SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED] THEN 8608 EXISTS_TAC ``s:real->bool`` THEN 8609 ASM_REWRITE_TAC[SUBSET_REFL] THEN ASM_MESON_TAC[]); 8610 8611val BOUNDED_EQ_BOLZANO_WEIERSTRASS = store_thm ("BOUNDED_EQ_BOLZANO_WEIERSTRASS", 8612 ``!s:real->bool. 8613 bounded s <=> !t. t SUBSET s /\ INFINITE t ==> ?x. x limit_point_of t``, 8614 MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED, BOLZANO_WEIERSTRASS, 8615 BOUNDED_SUBSET]); 8616 8617(* ------------------------------------------------------------------------- *) 8618(* In particular, some common special cases. *) 8619(* ------------------------------------------------------------------------- *) 8620 8621val COMPACT_EMPTY = store_thm ("COMPACT_EMPTY", 8622 ``compact {}``, 8623 REWRITE_TAC[compact, NOT_IN_EMPTY]); 8624 8625val COMPACT_UNION = store_thm ("COMPACT_UNION", 8626 ``!s t. compact s /\ compact t ==> compact (s UNION t)``, 8627 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_UNION, CLOSED_UNION]); 8628 8629val COMPACT_INTER = store_thm ("COMPACT_INTER", 8630 ``!s t. compact s /\ compact t ==> compact (s INTER t)``, 8631 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTER, CLOSED_INTER]); 8632 8633val COMPACT_INTER_CLOSED = store_thm ("COMPACT_INTER_CLOSED", 8634 ``!s t. compact s /\ closed t ==> compact (s INTER t)``, 8635 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_INTER] THEN 8636 MESON_TAC[BOUNDED_SUBSET, INTER_SUBSET]); 8637 8638val CLOSED_INTER_COMPACT = store_thm ("CLOSED_INTER_COMPACT", 8639 ``!s t. closed s /\ compact t ==> compact (s INTER t)``, 8640 MESON_TAC[COMPACT_INTER_CLOSED, INTER_COMM]); 8641 8642val COMPACT_BIGINTER = store_thm ("COMPACT_BIGINTER", 8643 ``!f:(real->bool)->bool. 8644 (!s. s IN f ==> compact s) /\ ~(f = {}) 8645 ==> compact(BIGINTER f)``, 8646 SIMP_TAC std_ss[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_BIGINTER] THEN 8647 REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_BIGINTER THEN ASM_SET_TAC[]); 8648 8649val FINITE_IMP_CLOSED = store_thm ("FINITE_IMP_CLOSED", 8650 ``!s. FINITE s ==> closed s``, 8651 MESON_TAC[BOLZANO_WEIERSTRASS_IMP_CLOSED, SUBSET_FINITE_I]); 8652 8653val FINITE_IMP_CLOSED_IN = store_thm ("FINITE_IMP_CLOSED_IN", 8654 ``!s t. FINITE s /\ s SUBSET t ==> closed_in (subtopology euclidean t) s``, 8655 SIMP_TAC std_ss [CLOSED_SUBSET_EQ, FINITE_IMP_CLOSED]); 8656 8657val FINITE_IMP_COMPACT = store_thm ("FINITE_IMP_COMPACT", 8658 ``!s. FINITE s ==> compact s``, 8659 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, FINITE_IMP_CLOSED, FINITE_IMP_BOUNDED]); 8660 8661val COMPACT_SING = store_thm ("COMPACT_SING", 8662 ``!a. compact {a}``, 8663 SIMP_TAC std_ss [FINITE_IMP_COMPACT, FINITE_EMPTY, FINITE_INSERT]); 8664 8665val COMPACT_INSERT = store_thm ("COMPACT_INSERT", 8666 ``!a s. compact s ==> compact(a INSERT s)``, 8667 ONCE_REWRITE_TAC[SET_RULE ``a INSERT s = {a} UNION s``] THEN 8668 SIMP_TAC std_ss [COMPACT_UNION, COMPACT_SING]); 8669 8670val CLOSED_SING = store_thm ("CLOSED_SING", 8671 ``!a. closed {a}``, 8672 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, COMPACT_SING]); 8673 8674val CLOSED_IN_SING = store_thm ("CLOSED_IN_SING", 8675 ``!u x:real. closed_in (subtopology euclidean u) {x} <=> x IN u``, 8676 SIMP_TAC std_ss [CLOSED_SUBSET_EQ, CLOSED_SING] THEN SET_TAC[]); 8677 8678val CLOSURE_SING = store_thm ("CLOSURE_SING", 8679 ``!x:real. closure {x} = {x}``, 8680 SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_SING]); 8681 8682val CLOSED_INSERT = store_thm ("CLOSED_INSERT", 8683 ``!a s. closed s ==> closed(a INSERT s)``, 8684 ONCE_REWRITE_TAC[SET_RULE ``a INSERT s = {a} UNION s``] THEN 8685 SIMP_TAC std_ss [CLOSED_UNION, CLOSED_SING]); 8686 8687val COMPACT_CBALL = store_thm ("COMPACT_CBALL", 8688 ``!x e. compact(cball(x,e))``, 8689 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_CBALL, CLOSED_CBALL]); 8690 8691val COMPACT_FRONTIER_BOUNDED = store_thm ("COMPACT_FRONTIER_BOUNDED", 8692 ``!s. bounded s ==> compact(frontier s)``, 8693 SIMP_TAC std_ss [frontier, COMPACT_EQ_BOUNDED_CLOSED, 8694 CLOSED_DIFF, OPEN_INTERIOR, CLOSED_CLOSURE] THEN 8695 MESON_TAC[DIFF_SUBSET, BOUNDED_SUBSET, BOUNDED_CLOSURE]); 8696 8697val COMPACT_FRONTIER = store_thm ("COMPACT_FRONTIER", 8698 ``!s. compact s ==> compact (frontier s)``, 8699 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, COMPACT_FRONTIER_BOUNDED]); 8700 8701val BOUNDED_FRONTIER = store_thm ("BOUNDED_FRONTIER", 8702 ``!s:real->bool. bounded s ==> bounded(frontier s)``, 8703 MESON_TAC[COMPACT_FRONTIER_BOUNDED, COMPACT_IMP_BOUNDED]); 8704 8705val FRONTIER_SUBSET_COMPACT = store_thm ("FRONTIER_SUBSET_COMPACT", 8706 ``!s. compact s ==> frontier s SUBSET s``, 8707 MESON_TAC[FRONTIER_SUBSET_CLOSED, COMPACT_EQ_BOUNDED_CLOSED]); 8708 8709val OPEN_DELETE = store_thm ("OPEN_DELETE", 8710 ``!s x. open s ==> open(s DELETE x)``, 8711SIMP_TAC std_ss [SET_RULE ``s DELETE x = s DIFF {x}``, 8712 OPEN_DIFF, CLOSED_SING]); 8713 8714val OPEN_IN_DELETE = store_thm ("OPEN_IN_DELETE", 8715 ``!u s a:real. 8716 open_in (subtopology euclidean u) s 8717 ==> open_in (subtopology euclidean u) (s DELETE a)``, 8718 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``(a:real) IN s`` THENL 8719 [ONCE_REWRITE_TAC[SET_RULE ``s DELETE a = s DIFF {a}``] THEN 8720 MATCH_MP_TAC OPEN_IN_DIFF THEN ASM_REWRITE_TAC[CLOSED_IN_SING] THEN 8721 FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM_SET_TAC[], 8722 ASM_SIMP_TAC std_ss [SET_RULE ``~(a IN s) ==> (s DELETE a = s)``]]); 8723 8724val CLOSED_BIGINTER_COMPACT = store_thm ("CLOSED_BIGINTER_COMPACT", 8725 ``!s:real->bool. 8726 closed s <=> !e. compact(cball(0,e) INTER s)``, 8727 GEN_TAC THEN EQ_TAC THENL 8728 [SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_INTER, CLOSED_CBALL, 8729 BOUNDED_INTER, BOUNDED_CBALL], ALL_TAC] THEN 8730 STRIP_TAC THEN REWRITE_TAC[CLOSED_LIMPT] THEN 8731 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 8732 FIRST_X_ASSUM(MP_TAC o SPEC ``abs(x:real) + &1:real``) THEN 8733 DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_CLOSED) THEN 8734 REWRITE_TAC[CLOSED_LIMPT] THEN DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 8735 REWRITE_TAC[IN_INTER] THEN 8736 KNOW_TAC ``(x :real) limit_point_of 8737 cball ((0 :real),abs x + (1 :real)) INTER (s :real -> bool)`` THENL 8738 [ALL_TAC, MESON_TAC[]] THEN 8739 POP_ASSUM MP_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN 8740 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 8741 FIRST_X_ASSUM(MP_TAC o SPEC ``min e (&1 / &2:real)``) THEN 8742 KNOW_TAC ``0 < min e (1 / 2:real)`` THENL 8743 [REWRITE_TAC [min_def] THEN COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [REAL_HALF_BETWEEN], 8744 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 8745 DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN 8746 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [IN_INTER, IN_CBALL] THEN 8747 REWRITE_TAC [REAL_LT_MIN, DIST_0, dist] THEN STRIP_TAC THEN 8748 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 8749 ASM_REAL_ARITH_TAC); 8750 8751val COMPACT_BIGUNION = store_thm ("COMPACT_BIGUNION", 8752 ``!s. FINITE s /\ (!t. t IN s ==> compact t) ==> compact(BIGUNION s)``, 8753 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_BIGUNION, BOUNDED_BIGUNION]); 8754 8755val COMPACT_DIFF = store_thm ("COMPACT_DIFF", 8756 ``!s t. compact s /\ open t ==> compact(s DIFF t)``, 8757 ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN 8758 SIMP_TAC std_ss [COMPACT_INTER_CLOSED, GSYM OPEN_CLOSED]); 8759 8760val COMPACT_SPHERE = store_thm ("COMPACT_SPHERE", 8761 ``!a:real r. compact(sphere(a,r))``, 8762 REPEAT GEN_TAC THEN 8763 REWRITE_TAC[GSYM FRONTIER_CBALL] THEN MATCH_MP_TAC COMPACT_FRONTIER THEN 8764 REWRITE_TAC[COMPACT_CBALL]); 8765 8766val BOUNDED_SPHERE = store_thm ("BOUNDED_SPHERE", 8767 ``!a:real r. bounded(sphere(a,r))``, 8768 SIMP_TAC std_ss [COMPACT_SPHERE, COMPACT_IMP_BOUNDED]); 8769 8770val CLOSED_SPHERE = store_thm ("CLOSED_SPHERE", 8771 ``!a r. closed(sphere(a,r))``, 8772 SIMP_TAC std_ss [COMPACT_SPHERE, COMPACT_IMP_CLOSED]); 8773 8774val FRONTIER_SING = store_thm ("FRONTIER_SING", 8775 ``!a:real. frontier {a} = {a}``, 8776 REWRITE_TAC[frontier, CLOSURE_SING, INTERIOR_SING, DIFF_EMPTY]); 8777 8778(* ------------------------------------------------------------------------- *) 8779(* Finite intersection property. I could make it an equivalence in fact. *) 8780(* ------------------------------------------------------------------------- *) 8781 8782val lemma = prove ( 8783 ``(s = UNIV DIFF t) <=> (UNIV DIFF s = t)``, 8784 SET_TAC[]); 8785 8786val COMPACT_IMP_FIP = store_thm ("COMPACT_IMP_FIP", 8787 ``!s:real->bool f. 8788 compact s /\ 8789 (!t. t IN f ==> closed t) /\ 8790 (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (BIGINTER f') = {})) 8791 ==> ~(s INTER (BIGINTER f) = {})``, 8792 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 8793 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [COMPACT_EQ_HEINE_BOREL]) THEN 8794 DISCH_THEN(MP_TAC o SPEC ``IMAGE (\t:real->bool. UNIV DIFF t) f``) THEN 8795 ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 8796 DISCH_THEN(fn th => REPEAT STRIP_TAC THEN MP_TAC th) THEN 8797 ASM_SIMP_TAC std_ss [OPEN_DIFF, CLOSED_DIFF, OPEN_UNIV, CLOSED_UNIV, NOT_IMP] THEN 8798 CONJ_TAC THENL 8799 [UNDISCH_TAC ``(s:real->bool) INTER BIGINTER f = {}`` THEN 8800 ONCE_REWRITE_TAC[SUBSET_DEF, EXTENSION] THEN 8801 REWRITE_TAC [IN_BIGUNION] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN 8802 REWRITE_TAC [EXISTS_IN_IMAGE] THEN BETA_TAC THEN SET_TAC[], 8803 X_GEN_TAC ``g:(real->bool)->bool`` THEN 8804 FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (\t:real->bool. UNIV DIFF t) g``) THEN 8805 ASM_CASES_TAC ``FINITE(g:(real->bool)->bool)`` THEN 8806 ASM_SIMP_TAC std_ss [IMAGE_FINITE] THEN ONCE_REWRITE_TAC[SUBSET_DEF, EXTENSION] THEN 8807 SIMP_TAC std_ss [FORALL_IN_IMAGE, IN_INTER, IN_BIGINTER, IN_IMAGE, IN_DIFF, 8808 IN_UNIV, NOT_IN_EMPTY, lemma, UNWIND_THM1, IN_BIGUNION] THEN 8809 SET_TAC[]]); 8810 8811val CLOSED_IMP_FIP = store_thm ("CLOSED_IMP_FIP", 8812 ``!s:real->bool f. 8813 closed s /\ 8814 (!t. t IN f ==> closed t) /\ (?t. t IN f /\ bounded t) /\ 8815 (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (BIGINTER f') = {})) 8816 ==> ~(s INTER (BIGINTER f) = {})``, 8817 REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC(SET_RULE 8818 ``~((s INTER t) INTER u = {}) ==> ~(s INTER u = {})``) THEN 8819 MATCH_MP_TAC COMPACT_IMP_FIP THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL 8820 [ASM_MESON_TAC[CLOSED_INTER_COMPACT, COMPACT_EQ_BOUNDED_CLOSED], 8821 REWRITE_TAC [METIS [INTER_ASSOC, GSYM BIGINTER_INSERT] 8822 ``!f. s INTER t INTER BIGINTER f = s INTER BIGINTER (t INSERT f)``] THEN 8823 GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 8824 ASM_SIMP_TAC std_ss [FINITE_INSERT, INSERT_SUBSET]]); 8825 8826val CLOSED_IMP_FIP_COMPACT = store_thm ("CLOSED_IMP_FIP_COMPACT", 8827 ``!s:real->bool f. 8828 closed s /\ (!t. t IN f ==> compact t) /\ 8829 (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (BIGINTER f') = {})) 8830 ==> ~(s INTER (BIGINTER f) = {})``, 8831 REPEAT GEN_TAC THEN 8832 ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN 8833 ASM_SIMP_TAC std_ss [SUBSET_EMPTY, BIGINTER_EMPTY, INTER_UNIV] THENL 8834 [MESON_TAC[FINITE_EMPTY], ALL_TAC] THEN 8835 STRIP_TAC THEN MATCH_MP_TAC CLOSED_IMP_FIP THEN 8836 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, MEMBER_NOT_EMPTY]); 8837 8838val CLOSED_FIP = store_thm ("CLOSED_FIP", 8839 ``!f. (!t:real->bool. t IN f ==> closed t) /\ (?t. t IN f /\ bounded t) /\ 8840 (!f'. FINITE f' /\ f' SUBSET f ==> ~(BIGINTER f' = {})) 8841 ==> ~(BIGINTER f = {})``, 8842 GEN_TAC THEN DISCH_TAC THEN 8843 ONCE_REWRITE_TAC[SET_RULE ``(s = {}) <=> (UNIV INTER s = {})``] THEN 8844 MATCH_MP_TAC CLOSED_IMP_FIP THEN ASM_REWRITE_TAC[CLOSED_UNIV, INTER_UNIV]); 8845 8846val COMPACT_FIP = store_thm ("COMPACT_FIP", 8847 ``!f. (!t:real->bool. t IN f ==> compact t) /\ 8848 (!f'. FINITE f' /\ f' SUBSET f ==> ~(BIGINTER f' = {})) 8849 ==> ~(BIGINTER f = {})``, 8850 GEN_TAC THEN DISCH_TAC THEN 8851 ONCE_REWRITE_TAC[SET_RULE ``(s = {}) <=> (UNIV INTER s = {})``] THEN 8852 MATCH_MP_TAC CLOSED_IMP_FIP_COMPACT THEN 8853 ASM_REWRITE_TAC[CLOSED_UNIV, INTER_UNIV]); 8854 8855(* ------------------------------------------------------------------------- *) 8856(* Bounded closed nest property (proof does not use Heine-Borel). *) 8857(* ------------------------------------------------------------------------- *) 8858 8859val BOUNDED_CLOSED_NEST = store_thm ("BOUNDED_CLOSED_NEST", 8860 ``!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\ 8861 (!m n. m <= n ==> s(n) SUBSET s(m)) /\ 8862 bounded(s 0) 8863 ==> ?a:real. !n:num. a IN s(n)``, 8864 GEN_TAC THEN SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, SKOLEM_THM] THEN 8865 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 8866 DISCH_THEN(CONJUNCTS_THEN2 8867 (X_CHOOSE_TAC ``a:num->real``) STRIP_ASSUME_TAC) THEN 8868 SUBGOAL_THEN ``compact(s (0:num):real->bool)`` MP_TAC THENL 8869 [METIS_TAC[BOUNDED_CLOSED_IMP_COMPACT], ALL_TAC] THEN 8870 REWRITE_TAC[compact] THEN 8871 DISCH_THEN(MP_TAC o SPEC ``a:num->real``) THEN 8872 KNOW_TAC ``(!n:num. a n IN s (0:num):real->bool)`` THENL 8873 [ASM_MESON_TAC[SUBSET_DEF, ZERO_LESS_EQ], 8874 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 8875 DISCH_THEN (X_CHOOSE_TAC ``l:real``) THEN 8876 EXISTS_TAC ``l:real`` THEN POP_ASSUM MP_TAC THEN 8877 SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN 8878 DISCH_THEN(X_CHOOSE_THEN ``r:num->num`` STRIP_ASSUME_TAC) THEN 8879 GEN_REWR_TAC I [TAUT `p <=> ~(~p)`] THEN 8880 REWRITE_TAC [NOT_FORALL_THM] THEN X_GEN_TAC ``N:num`` THEN 8881 MP_TAC(ISPECL [``l:real``, ``(s:num->real->bool) N``] 8882 CLOSED_APPROACHABLE) THEN 8883 ASM_MESON_TAC[SUBSET_DEF, LESS_EQ_REFL, LESS_EQ_TRANS, LE_CASES, MONOTONE_BIGGER]); 8884 8885(* ------------------------------------------------------------------------- *) 8886(* Decreasing case does not even need compactness, just completeness. *) 8887(* ------------------------------------------------------------------------- *) 8888 8889val DECREASING_CLOSED_NEST = store_thm ("DECREASING_CLOSED_NEST", 8890 ``!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\ 8891 (!m n. m <= n ==> s(n) SUBSET s(m)) /\ 8892 (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e) 8893 ==> ?a:real. !n:num. a IN s(n)``, 8894 GEN_TAC THEN SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, SKOLEM_THM] THEN 8895 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 8896 DISCH_THEN(CONJUNCTS_THEN2 8897 (X_CHOOSE_TAC ``a:num->real``) STRIP_ASSUME_TAC) THEN 8898 SUBGOAL_THEN ``?l:real. (a --> l) sequentially`` MP_TAC THENL 8899 [ASM_MESON_TAC[cauchy, GE, SUBSET_DEF, LESS_EQ_TRANS, LESS_EQ_REFL, 8900 complete, COMPLETE_UNIV, IN_UNIV], 8901 ASM_MESON_TAC[LIM_SEQUENTIALLY, CLOSED_APPROACHABLE, 8902 SUBSET_DEF, LESS_EQ_REFL, LESS_EQ_TRANS, LE_CASES]]); 8903 8904(* ------------------------------------------------------------------------- *) 8905(* Strengthen it to the intersection actually being a singleton. *) 8906(* ------------------------------------------------------------------------- *) 8907 8908val DECREASING_CLOSED_NEST_SING = store_thm ("DECREASING_CLOSED_NEST_SING", 8909 ``!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\ 8910 (!m n. m <= n ==> s(n) SUBSET s(m)) /\ 8911 (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e) 8912 ==> ?a:real. BIGINTER {t | ?n:num. t = s n} = {a}``, 8913 GEN_TAC THEN DISCH_TAC THEN 8914 FIRST_ASSUM(MP_TAC o MATCH_MP DECREASING_CLOSED_NEST) THEN 8915 STRIP_TAC THEN EXISTS_TAC ``a:real`` THEN 8916 SIMP_TAC std_ss [EXTENSION, IN_BIGINTER, IN_SING, GSPECIFICATION] THEN 8917 METIS_TAC[DIST_POS_LT, REAL_LT_REFL, SUBSET_DEF, LE_CASES]); 8918 8919(* ------------------------------------------------------------------------- *) 8920(* A version for a more general chain, not indexed by N. *) 8921(* ------------------------------------------------------------------------- *) 8922 8923val BOUNDED_CLOSED_CHAIN = store_thm ("BOUNDED_CLOSED_CHAIN", 8924 ``!f b:real->bool. 8925 (!s. s IN f ==> closed s /\ ~(s = {})) /\ 8926 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) /\ 8927 b IN f /\ bounded b 8928 ==> ~(BIGINTER f = {})``, 8929 REPEAT GEN_TAC THEN STRIP_TAC THEN 8930 SUBGOAL_THEN ``~(b INTER (BIGINTER f):real->bool = {})`` MP_TAC THENL 8931 [ALL_TAC, SET_TAC[]] THEN 8932 MATCH_MP_TAC COMPACT_IMP_FIP THEN 8933 ASM_SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED] THEN 8934 X_GEN_TAC ``u:(real->bool)->bool`` THEN STRIP_TAC THEN 8935 SUBGOAL_THEN ``?s:real->bool. s IN f /\ !t. t IN u ==> s SUBSET t`` 8936 MP_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 8937 UNDISCH_TAC ``(u:(real->bool)->bool) SUBSET f`` THEN 8938 UNDISCH_TAC ``FINITE(u:(real->bool)->bool)`` THEN 8939 SPEC_TAC(``u:(real->bool)->bool``,``u:(real->bool)->bool``) THEN 8940 ONCE_REWRITE_TAC [METIS [] ``!u. (u SUBSET f ==> ?s. s IN f /\ !t. t IN u ==> s SUBSET t) = 8941 (\u. u SUBSET f ==> ?s. s IN f /\ !t. t IN u ==> s SUBSET t) u``] THEN 8942 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 8943 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 8944 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN 8945 MAP_EVERY X_GEN_TAC [``u:(real->bool)->bool``, ``t:real->bool``] THEN 8946 REWRITE_TAC[INSERT_SUBSET] THEN 8947 ONCE_REWRITE_TAC [AND_IMP_INTRO] THEN 8948 DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN 8949 ASM_REWRITE_TAC[] THEN 8950 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 8951 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN 8952 DISCH_THEN(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN 8953 FIRST_X_ASSUM(MP_TAC o SPECL [``s:real->bool``, ``t:real->bool``]) THEN 8954 ASM_SET_TAC[]); 8955 8956(* ------------------------------------------------------------------------- *) 8957(* Analogous things directly for compactness. *) 8958(* ------------------------------------------------------------------------- *) 8959 8960val COMPACT_CHAIN = store_thm ("COMPACT_CHAIN", 8961 ``!f:(real->bool)->bool. 8962 (!s. s IN f ==> compact s /\ ~(s = {})) /\ 8963 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) 8964 ==> ~(BIGINTER f = {})``, 8965 GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN STRIP_TAC THEN 8966 ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THENL 8967 [ASM_REWRITE_TAC[BIGINTER_EMPTY] THEN SET_TAC[], 8968 MATCH_MP_TAC BOUNDED_CLOSED_CHAIN THEN ASM_SET_TAC[]]); 8969 8970val COMPACT_NEST = store_thm ("COMPACT_NEST", 8971 ``!s. (!n. compact(s n) /\ ~(s n = {})) /\ 8972 (!m n. m <= n ==> s n SUBSET s m) 8973 ==> ~(BIGINTER {s n | n IN univ(:num)} = {})``, 8974 GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC COMPACT_CHAIN THEN 8975 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 8976 ONCE_REWRITE_TAC [METIS [] ``!n n'. (s n SUBSET s n' \/ s n' SUBSET s n) = 8977 (\n n'. s n SUBSET s n' \/ s n' SUBSET s n) n n'``] THEN 8978 MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]); 8979 8980(* ------------------------------------------------------------------------- *) 8981(* Cauchy-type criteria for *uniform* convergence. *) 8982(* ------------------------------------------------------------------------- *) 8983 8984val UNIFORMLY_CONVERGENT_EQ_CAUCHY = store_thm ("UNIFORMLY_CONVERGENT_EQ_CAUCHY", 8985 ``!P s:num->'a->real. 8986 (?l. !e. &0 < e 8987 ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e) <=> 8988 (!e. &0 < e 8989 ==> ?N. !m n x. N <= m /\ N <= n /\ P x 8990 ==> dist(s m x,s n x) < e)``, 8991 REPEAT GEN_TAC THEN EQ_TAC THENL 8992 [DISCH_THEN(X_CHOOSE_TAC ``l:'a->real``) THEN X_GEN_TAC ``e:real`` THEN 8993 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 8994 ASM_REWRITE_TAC[REAL_HALF] THEN MESON_TAC[DIST_TRIANGLE_HALF_L], 8995 ALL_TAC] THEN 8996 DISCH_TAC THEN 8997 SUBGOAL_THEN ``!x:'a. P x ==> cauchy (\n. s n x :real)`` MP_TAC THENL 8998 [REWRITE_TAC[cauchy, GE] THEN ASM_MESON_TAC[], ALL_TAC] THEN 8999 REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY, LIM_SEQUENTIALLY] THEN 9000 DISCH_TAC THEN KNOW_TAC ``(!(x :'a). ?(l :real). (P :'a -> bool) x ==> 9001 (!(e :real). (0 :real) < e ==> 9002 (?(N :num). !(n :num). N <= n ==> 9003 (dist ((\(n :num). (s :num -> 'a -> real) n x) n,l) :real) < e)))`` THENL 9004 [METIS_TAC [], POP_ASSUM K_TAC] THEN SIMP_TAC std_ss [SKOLEM_THM] THEN 9005 DISCH_THEN (X_CHOOSE_TAC ``l:'a->real``) THEN 9006 EXISTS_TAC ``l:'a->real`` THEN POP_ASSUM MP_TAC THEN 9007 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN 9008 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 9009 ASM_REWRITE_TAC[REAL_HALF] THEN 9010 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 9011 POP_ASSUM MP_TAC THEN STRIP_TAC THEN 9012 MAP_EVERY X_GEN_TAC [``n:num``, ``x:'a``] THEN STRIP_TAC THEN 9013 FIRST_X_ASSUM(MP_TAC o SPEC ``x:'a``) THEN ASM_REWRITE_TAC[] THEN 9014 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_HALF] THEN 9015 DISCH_THEN(X_CHOOSE_TAC ``M:num``) THEN 9016 UNDISCH_TAC ``!m n x. N:num <= m /\ N <= n /\ P x 9017 ==> dist (s m x,s n x) < e / 2:real`` THEN DISCH_TAC THEN 9018 POP_ASSUM (MP_TAC o Q.SPECL [`n:num`, `N + M:num`, `x:'a`]) THEN 9019 ASM_REWRITE_TAC[LE_ADD] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN 9020 FIRST_X_ASSUM(MP_TAC o SPEC ``M + N:num``) THEN REWRITE_TAC[LE_ADD] THEN 9021 ASM_MESON_TAC[DIST_TRIANGLE_HALF_L, DIST_SYM]); 9022 9023val UNIFORMLY_CONVERGENT_EQ_CAUCHY_ALT = store_thm ("UNIFORMLY_CONVERGENT_EQ_CAUCHY_ALT", 9024 ``!P s:num->'a->real. 9025 (?l. !e. &0 < e 9026 ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e) <=> 9027 (!e. &0 < e 9028 ==> ?N. !m n x. N <= m /\ N <= n /\ m < n /\ P x 9029 ==> dist(s m x,s n x) < e)``, 9030 REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN 9031 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 9032 FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN 9033 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 9034 ASM_SIMP_TAC std_ss [] THEN 9035 ONCE_REWRITE_TAC [METIS [] ``!m n. (!x. N:num <= m /\ N <= n /\ P x 9036 ==> dist (s m x,s n x) < e) = 9037 (\m n. !x. N:num <= m /\ N <= n /\ P x 9038 ==> dist (s m x,s n x) < e) m n``] THEN 9039 MATCH_MP_TAC WLOG_LT THEN 9040 ASM_SIMP_TAC std_ss [DIST_REFL] THEN MESON_TAC[DIST_SYM]); 9041 9042val UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT = store_thm ("UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT", 9043 ``!P (s:num->'a->real) l. 9044 (!e. &0 < e 9045 ==> ?N. !m n x. N <= m /\ N <= n /\ P x ==> dist(s m x,s n x) < e) /\ 9046 (!x. P x ==> !e. &0 < e ==> ?N. !n. N <= n ==> dist(s n x,l x) < e) 9047 ==> (!e. &0 < e ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e)``, 9048 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN 9049 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC ``l':'a->real``) ASSUME_TAC) THEN 9050 SUBGOAL_THEN ``!x. P x ==> ((l:'a->real) x = l' x)`` MP_TAC THENL 9051 [ALL_TAC, METIS_TAC[]] THEN 9052 REPEAT STRIP_TAC THEN MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN 9053 EXISTS_TAC ``\n. (s:num->'a->real) n x`` THEN 9054 REWRITE_TAC[LIM_SEQUENTIALLY, TRIVIAL_LIMIT_SEQUENTIALLY] THEN 9055 ASM_MESON_TAC[]); 9056 9057(* ------------------------------------------------------------------------- *) 9058(* Define continuity over a net to take in restrictions of the set. *) 9059(* ------------------------------------------------------------------------- *) 9060 9061val _ = set_fixity "continuous" (Infix(NONASSOC, 450)); 9062 9063val continuous = new_definition ("continuous", 9064 ``f continuous net <=> (f --> f(netlimit net)) net``); 9065 9066val CONTINUOUS_TRIVIAL_LIMIT = store_thm ("CONTINUOUS_TRIVIAL_LIMIT", 9067 ``!f net. trivial_limit net ==> f continuous net``, 9068 SIMP_TAC std_ss [continuous, LIM]); 9069 9070val CONTINUOUS_WITHIN = store_thm ("CONTINUOUS_WITHIN", 9071 ``!f x:real. f continuous (at x within s) <=> (f --> f(x)) (at x within s)``, 9072 REPEAT GEN_TAC THEN REWRITE_TAC[continuous] THEN 9073 ASM_CASES_TAC ``trivial_limit(at (x:real) within s)`` THENL 9074 [ASM_REWRITE_TAC[LIM], ASM_SIMP_TAC std_ss [NETLIMIT_WITHIN]]); 9075 9076val CONTINUOUS_AT = store_thm ("CONTINUOUS_AT", 9077 ``!f (x:real). f continuous (at x) <=> (f --> f(x)) (at x)``, 9078 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 9079 REWRITE_TAC[CONTINUOUS_WITHIN, IN_UNIV]); 9080 9081val CONTINUOUS_AT_WITHIN = store_thm ("CONTINUOUS_AT_WITHIN", 9082 ``!f:real->real x s. 9083 f continuous (at x) ==> f continuous (at x within s)``, 9084 SIMP_TAC std_ss [LIM_AT_WITHIN, CONTINUOUS_AT, CONTINUOUS_WITHIN]); 9085 9086val CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL = store_thm ("CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL", 9087 ``!a s. closed s /\ ~(a IN s) ==> f continuous (at a within s)``, 9088 ASM_SIMP_TAC std_ss [continuous, LIM, LIM_WITHIN_CLOSED_TRIVIAL]); 9089 9090val CONTINUOUS_TRANSFORM_WITHIN = store_thm ("CONTINUOUS_TRANSFORM_WITHIN", 9091 ``!f g:real->real s x d. &0 < d /\ x IN s /\ 9092 (!x'. x' IN s /\ dist(x',x) < d ==> (f(x') = g(x'))) /\ 9093 f continuous (at x within s) ==> g continuous (at x within s)``, 9094 SIMP_TAC std_ss [CONTINUOUS_WITHIN] THEN 9095 METIS_TAC[LIM_TRANSFORM_WITHIN, DIST_REFL]); 9096 9097val CONTINUOUS_TRANSFORM_AT = store_thm ("CONTINUOUS_TRANSFORM_AT", 9098 ``!f g:real->real x d. 9099 &0 < d /\ (!x'. dist(x',x) < d ==> (f(x') = g(x'))) /\ 9100 f continuous (at x) ==> g continuous (at x)``, 9101 REWRITE_TAC[CONTINUOUS_AT] THEN 9102 METIS_TAC[LIM_TRANSFORM_AT, DIST_REFL]); 9103 9104val CONTINUOUS_TRANSFORM_WITHIN_OPEN = store_thm ("CONTINUOUS_TRANSFORM_WITHIN_OPEN", 9105 ``!f g:real->real s a. open s /\ a IN s /\ 9106 (!x. x IN s ==> (f x = g x)) /\ 9107 f continuous at a ==> g continuous at a``, 9108 METIS_TAC[CONTINUOUS_AT, LIM_TRANSFORM_WITHIN_OPEN]); 9109 9110val CONTINUOUS_TRANSFORM_WITHIN_OPEN_IN = store_thm ("CONTINUOUS_TRANSFORM_WITHIN_OPEN_IN", 9111 ``!f g:real->real s t a. 9112 open_in (subtopology euclidean t) s /\ a IN s /\ 9113 (!x. x IN s ==> (f x = g x)) /\ 9114 f continuous (at a within t) ==> g continuous (at a within t)``, 9115 METIS_TAC[CONTINUOUS_WITHIN, LIM_TRANSFORM_WITHIN_OPEN_IN]); 9116 9117val CONTINUOUS_TRANSFORM_WITHIN_SET_IMP = store_thm ("CONTINUOUS_TRANSFORM_WITHIN_SET_IMP", 9118 ``!f a s t. eventually (\x. x IN t ==> x IN s) (at a) /\ 9119 f continuous (at a within s) ==> f continuous (at a within t)``, 9120 REWRITE_TAC[CONTINUOUS_WITHIN, LIM_TRANSFORM_WITHIN_SET_IMP]); 9121 9122(* ------------------------------------------------------------------------- *) 9123(* Derive the epsilon-delta forms, which we often use as "definitions" *) 9124(* ------------------------------------------------------------------------- *) 9125 9126val continuous_within = store_thm ("continuous_within", 9127 ``f continuous (at x within s) <=> !e. &0 < e 9128 ==> ?d. &0 < d /\ !x'. x' IN s /\ dist(x',x) < d 9129 ==> dist(f(x'),f(x)) < e``, 9130 SIMP_TAC std_ss [CONTINUOUS_WITHIN, LIM_WITHIN] THEN 9131 SIMP_TAC std_ss [GSYM DIST_NZ] THEN MESON_TAC[DIST_REFL]); 9132 9133val continuous_at = store_thm ("continuous_at", 9134 ``f continuous (at x) <=> 9135 !e. &0 < e ==> ?d. &0 < d /\ 9136 !x'. dist(x',x) < d ==> dist(f(x'),f(x)) < e``, 9137 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 9138 SIMP_TAC std_ss [continuous_within, IN_UNIV]); 9139 9140(* ------------------------------------------------------------------------- *) 9141(* Versions in terms of open balls. *) 9142(* ------------------------------------------------------------------------- *) 9143 9144val CONTINUOUS_WITHIN_BALL = store_thm ("CONTINUOUS_WITHIN_BALL", 9145 ``!f s x. f continuous (at x within s) <=> 9146 !e. &0 < e ==> ?d. &0 < d /\ 9147 IMAGE f (ball(x,d) INTER s) SUBSET ball(f x,e)``, 9148 SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE, IN_BALL, continuous_within, IN_INTER] THEN 9149 MESON_TAC[DIST_SYM]); 9150 9151val CONTINUOUS_AT_BALL = store_thm ("CONTINUOUS_AT_BALL", 9152 ``!f x. f continuous (at x) <=> 9153 !e. &0 < e ==> ?d. &0 < d /\ 9154 IMAGE f (ball(x,d)) SUBSET ball(f x,e)``, 9155 SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE, IN_BALL, continuous_at] THEN 9156 MESON_TAC[DIST_SYM]); 9157 9158(* ------------------------------------------------------------------------- *) 9159(* *) 9160(* ------------------------------------------------------------------------- *) 9161 9162val CONTINUOUS_WITHIN_COMPARISON = store_thm ("CONTINUOUS_WITHIN_COMPARISON", 9163 ``!f:real->real g:real->real s a. 9164 g continuous (at a within s) /\ 9165 (!x. x IN s ==> dist(f a,f x) <= dist(g a,g x)) 9166 ==> f continuous (at a within s)``, 9167 ONCE_REWRITE_TAC[DIST_SYM] THEN 9168 REWRITE_TAC[continuous_within] THEN MESON_TAC[REAL_LET_TRANS]); 9169 9170(* ------------------------------------------------------------------------- *) 9171(* For setwise continuity, just start from the epsilon-delta definitions. *) 9172(* ------------------------------------------------------------------------- *) 9173 9174val _ = set_fixity "continuous_on" (Infix(NONASSOC, 450)); 9175val _ = set_fixity "uniformly_continuous_on" (Infix(NONASSOC, 450)); 9176 9177val continuous_on = new_definition ("continuous_on", 9178 ``f continuous_on s <=> 9179 !x. x IN s ==> !e. &0 < e 9180 ==> ?d. &0 < d /\ !x'. x' IN s /\ dist(x',x) < d 9181 ==> dist(f(x'),f(x)) < e``); 9182 9183val uniformly_continuous_on = new_definition ("uniformly_continuous_on", 9184 ``f uniformly_continuous_on s <=> 9185 !e. &0 < e 9186 ==> ?d. &0 < d /\ !x x'. x IN s /\ x' IN s /\ dist(x',x) < d 9187 ==> dist(f(x'),f(x)) < e``); 9188 9189(* ------------------------------------------------------------------------- *) 9190(* Some simple consequential lemmas. *) 9191(* ------------------------------------------------------------------------- *) 9192 9193val UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS = store_thm ("UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS", 9194 ``!f s. f uniformly_continuous_on s ==> f continuous_on s``, 9195 REWRITE_TAC[uniformly_continuous_on, continuous_on] THEN MESON_TAC[]); 9196 9197val CONTINUOUS_AT_IMP_CONTINUOUS_ON = store_thm ("CONTINUOUS_AT_IMP_CONTINUOUS_ON", 9198 ``!f s. (!x. x IN s ==> f continuous (at x)) ==> f continuous_on s``, 9199 REWRITE_TAC[continuous_at, continuous_on] THEN MESON_TAC[]); 9200 9201val CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN = store_thm ("CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN", 9202 ``!f s. f continuous_on s <=> !x. x IN s ==> f continuous (at x within s)``, 9203 REWRITE_TAC[continuous_on, continuous_within]); 9204 9205val CONTINUOUS_ON = store_thm ("CONTINUOUS_ON", 9206 ``!f (s:real->bool). 9207 f continuous_on s <=> !x. x IN s ==> (f --> f(x)) (at x within s)``, 9208 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_WITHIN]); 9209 9210val CONTINUOUS_ON_EQ_CONTINUOUS_AT = store_thm ("CONTINUOUS_ON_EQ_CONTINUOUS_AT", 9211 ``!f:real->real s. 9212 open s ==> (f continuous_on s <=> (!x. x IN s ==> f continuous (at x)))``, 9213 SIMP_TAC std_ss [CONTINUOUS_ON, CONTINUOUS_AT, LIM_WITHIN_OPEN]); 9214 9215val CONTINUOUS_WITHIN_SUBSET = store_thm ("CONTINUOUS_WITHIN_SUBSET", 9216 ``!f s t x. f continuous (at x within s) /\ t SUBSET s 9217 ==> f continuous (at x within t)``, 9218 REWRITE_TAC[CONTINUOUS_WITHIN] THEN MESON_TAC[LIM_WITHIN_SUBSET]); 9219 9220val CONTINUOUS_ON_SUBSET = store_thm ("CONTINUOUS_ON_SUBSET", 9221 ``!f s t. f continuous_on s /\ t SUBSET s ==> f continuous_on t``, 9222 REWRITE_TAC[CONTINUOUS_ON] THEN MESON_TAC[SUBSET_DEF, LIM_WITHIN_SUBSET]); 9223 9224val UNIFORMLY_CONTINUOUS_ON_SUBSET = store_thm ("UNIFORMLY_CONTINUOUS_ON_SUBSET", 9225 ``!f s t. f uniformly_continuous_on s /\ t SUBSET s 9226 ==> f uniformly_continuous_on t``, 9227 REWRITE_TAC[uniformly_continuous_on] THEN 9228 MESON_TAC[SUBSET_DEF, LIM_WITHIN_SUBSET]); 9229 9230val CONTINUOUS_ON_INTERIOR = store_thm ("CONTINUOUS_ON_INTERIOR", 9231 ``!f:real->real s x. 9232 f continuous_on s /\ x IN interior(s) ==> f continuous at x``, 9233 SIMP_TAC std_ss [interior, GSPECIFICATION] THEN 9234 MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT, CONTINUOUS_ON_SUBSET]); 9235 9236val CONTINUOUS_ON_EQ = store_thm ("CONTINUOUS_ON_EQ", 9237 ``!f g s. (!x. x IN s ==> (f(x) = g(x))) /\ f continuous_on s 9238 ==> g continuous_on s``, 9239 SIMP_TAC std_ss [continuous_on, CONJ_EQ_IMP]); 9240 9241val UNIFORMLY_CONTINUOUS_ON_EQ = store_thm ("UNIFORMLY_CONTINUOUS_ON_EQ", 9242 ``!f g s. (!x. x IN s ==> (f x = g x)) /\ f uniformly_continuous_on s 9243 ==> g uniformly_continuous_on s``, 9244 SIMP_TAC std_ss [uniformly_continuous_on, CONJ_EQ_IMP]); 9245 9246val CONTINUOUS_ON_SING = store_thm ("CONTINUOUS_ON_SING", 9247 ``!f:real->real a. f continuous_on {a}``, 9248 SIMP_TAC std_ss [continuous_on, IN_SING, DIST_REFL] THEN 9249 METIS_TAC[]); 9250 9251val CONTINUOUS_ON_EMPTY = store_thm ("CONTINUOUS_ON_EMPTY", 9252 ``!f:real->real. f continuous_on {}``, 9253 MESON_TAC[CONTINUOUS_ON_SING, EMPTY_SUBSET, CONTINUOUS_ON_SUBSET]); 9254 9255val CONTINUOUS_ON_NO_LIMPT = store_thm ("CONTINUOUS_ON_NO_LIMPT", 9256 ``!f:real->real s. 9257 ~(?x. x limit_point_of s) ==> f continuous_on s``, 9258 REWRITE_TAC[continuous_on, LIMPT_APPROACHABLE] THEN MESON_TAC[DIST_REFL]); 9259 9260val CONTINUOUS_ON_FINITE = store_thm ("CONTINUOUS_ON_FINITE", 9261 ``!f:real->real s. FINITE s ==> f continuous_on s``, 9262 MESON_TAC[CONTINUOUS_ON_NO_LIMPT, LIMIT_POINT_FINITE]); 9263 9264val CONTRACTION_IMP_CONTINUOUS_ON = store_thm ("CONTRACTION_IMP_CONTINUOUS_ON", 9265 ``!f:real->real. 9266 (!x y. x IN s /\ y IN s ==> dist(f x,f y) <= dist(x,y)) 9267 ==> f continuous_on s``, 9268 SIMP_TAC std_ss [continuous_on] THEN MESON_TAC[REAL_LET_TRANS]); 9269 9270val ISOMETRY_ON_IMP_CONTINUOUS_ON = store_thm ("ISOMETRY_ON_IMP_CONTINUOUS_ON", 9271 ``!f:real->real. 9272 (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y))) 9273 ==> f continuous_on s``, 9274 SIMP_TAC std_ss [CONTRACTION_IMP_CONTINUOUS_ON, REAL_LE_REFL]); 9275 9276(* ------------------------------------------------------------------------- *) 9277(* Characterization of various kinds of continuity in terms of sequences. *) 9278(* ------------------------------------------------------------------------- *) 9279 9280val FORALL_POS_MONO_1 = store_thm ("FORALL_POS_MONO_1", 9281 ``!P. (!d e. d < e /\ P d ==> P e) /\ (!n. P(inv(&n + &1))) 9282 ==> !e. (&0:real) < e ==> P e``, 9283 SIMP_TAC std_ss [REAL_OF_NUM_SUC] THEN SIMP_TAC std_ss [GSYM FORALL_SUC] THEN 9284 REWRITE_TAC [FORALL_POS_MONO]); 9285 9286val CONTINUOUS_WITHIN_SEQUENTIALLY = store_thm ("CONTINUOUS_WITHIN_SEQUENTIALLY", 9287 ``!f s a:real. 9288 f continuous (at a within s) <=> 9289 !x. (!n. x(n) IN s) /\ (x --> a) sequentially 9290 ==> ((f o x) --> f(a)) sequentially``, 9291 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL 9292 [SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN MESON_TAC[], ALL_TAC] THEN 9293 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 9294 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN 9295 DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 9296 DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC ``&1 / (&n + &1:real)``) THEN 9297 SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT, REAL_OF_NUM_LE, REAL_POS, 9298 REAL_ARITH ``&0 <= n ==> &0 < n + &1:real``, NOT_FORALL_THM, SKOLEM_THM] THEN 9299 DISCH_THEN (X_CHOOSE_TAC ``y:num->real``) THEN EXISTS_TAC ``y:num->real`` THEN 9300 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IMP, FORALL_AND_THM] THEN 9301 SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN 9302 STRIP_TAC THEN CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[LESS_EQ_REFL]] THEN 9303 KNOW_TAC ``!e. (?N:num. !n. N <= n ==> dist (y n,a) < e) = 9304 (\e. ?N:num. !n. N <= n ==> dist (y n,a) < e) e`` THENL 9305 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 9306 MATCH_MP_TAC FORALL_POS_MONO_1 THEN BETA_TAC THEN 9307 CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS], ALL_TAC] THEN 9308 X_GEN_TAC ``n:num`` THEN EXISTS_TAC ``n:num`` THEN X_GEN_TAC ``m:num`` THEN 9309 DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN 9310 EXISTS_TAC ``&1 / (&m + &1:real)`` THEN ASM_REWRITE_TAC[] THEN 9311 ASM_SIMP_TAC std_ss [REAL_LE_INV2, real_div, REAL_ARITH ``&0 <= x ==> &0 < x + &1:real``, 9312 REAL_POS, REAL_MUL_LID, REAL_LE_RADD, REAL_OF_NUM_LE]); 9313 9314val CONTINUOUS_AT_SEQUENTIALLY = store_thm ("CONTINUOUS_AT_SEQUENTIALLY", 9315 ``!f a:real. f continuous (at a) <=> 9316 !x. (x --> a) sequentially ==> ((f o x) --> f(a)) sequentially``, 9317 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 9318 REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY, IN_UNIV]); 9319 9320val CONTINUOUS_ON_SEQUENTIALLY = store_thm ("CONTINUOUS_ON_SEQUENTIALLY", 9321 ``!f s:real->bool. f continuous_on s <=> 9322 !x a. a IN s /\ (!n. x(n) IN s) /\ (x --> a) sequentially 9323 ==> ((f o x) --> f(a)) sequentially``, 9324 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, 9325 CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]); 9326 9327val UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY = store_thm ("UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY", 9328 ``!f s:real->bool. f uniformly_continuous_on s <=> 9329 !x y. (!n. x(n) IN s) /\ (!n. y(n) IN s) /\ 9330 ((\n. x(n) - y(n)) --> 0) sequentially 9331 ==> ((\n. f(x(n)) - f(y(n))) --> 0) sequentially``, 9332 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN 9333 REWRITE_TAC[LIM_SEQUENTIALLY, dist, REAL_SUB_RZERO] THEN 9334 EQ_TAC THENL [MESON_TAC[], ALL_TAC] THEN 9335 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 9336 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN 9337 DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 9338 DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC ``&1 / (&n + &1:real)``) THEN 9339 SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT, REAL_OF_NUM_LE, REAL_POS, 9340 REAL_ARITH ``&0 <= n ==> &0 < n + &1:real``, NOT_FORALL_THM, SKOLEM_THM] THEN 9341 DISCH_THEN (X_CHOOSE_TAC ``x:num->real``) THEN POP_ASSUM MP_TAC THEN 9342 DISCH_THEN (X_CHOOSE_TAC ``y:num->real``) THEN 9343 EXISTS_TAC ``x:num->real`` THEN EXISTS_TAC ``y:num->real`` THEN 9344 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IMP, FORALL_AND_THM] THEN STRIP_TAC THEN 9345 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[ABS_SUB] THEN CONJ_TAC THENL 9346 [KNOW_TAC ``!e:real. (?N:num. !n. N <= n ==> abs (y n - x n) < e) = 9347 (\e. ?N:num. !n. N <= n ==> abs (y n - x n) < e) e`` THENL 9348 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 9349 MATCH_MP_TAC FORALL_POS_MONO_1 THEN BETA_TAC THEN 9350 CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS], ALL_TAC] THEN 9351 X_GEN_TAC ``n:num`` THEN EXISTS_TAC ``n:num`` THEN X_GEN_TAC ``m:num`` THEN 9352 DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN 9353 EXISTS_TAC ``&1 / (&m + &1:real)`` THEN ASM_REWRITE_TAC[] THEN 9354 ASM_SIMP_TAC std_ss [REAL_LE_INV2, real_div, REAL_ARITH ``&0 <= x ==> &0 < x + &1:real``, 9355 REAL_POS, REAL_MUL_LID, REAL_LE_RADD, REAL_OF_NUM_LE], 9356 EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN 9357 EXISTS_TAC ``\x:num. x`` THEN ASM_SIMP_TAC std_ss [LESS_EQ_REFL]]); 9358 9359val LIM_CONTINUOUS_FUNCTION = store_thm ("LIM_CONTINUOUS_FUNCTION", 9360 ``!f net g l. 9361 f continuous (at l) /\ (g --> l) net ==> ((\x. f(g x)) --> f l) net``, 9362 REWRITE_TAC[tendsto, continuous_at, eventually] THEN MESON_TAC[]); 9363 9364(* ------------------------------------------------------------------------- *) 9365(* Combination results for pointwise continuity. *) 9366(* ------------------------------------------------------------------------- *) 9367 9368val CONTINUOUS_CONST = store_thm ("CONTINUOUS_CONST", 9369 ``!net c. (\x. c) continuous net``, 9370 REWRITE_TAC[continuous, LIM_CONST]); 9371 9372val CONTINUOUS_CMUL = store_thm ("CONTINUOUS_CMUL", 9373 ``!f c net. f continuous net ==> (\x. c * f(x)) continuous net``, 9374 SIMP_TAC std_ss [continuous, LIM_CMUL]); 9375 9376val CONTINUOUS_NEG = store_thm ("CONTINUOUS_NEG", 9377 ``!f net. f continuous net ==> (\x. -(f x)) continuous net``, 9378 SIMP_TAC std_ss [continuous, LIM_NEG]); 9379 9380val CONTINUOUS_ADD = store_thm ("CONTINUOUS_ADD", 9381 ``!f g net. f continuous net /\ g continuous net 9382 ==> (\x. f(x) + g(x)) continuous net``, 9383 SIMP_TAC std_ss [continuous, LIM_ADD]); 9384 9385val CONTINUOUS_SUB = store_thm ("CONTINUOUS_SUB", 9386 ``!f g net. f continuous net /\ g continuous net 9387 ==> (\x. f(x) - g(x)) continuous net``, 9388 SIMP_TAC std_ss [continuous, LIM_SUB]); 9389 9390val CONTINUOUS_ABS = store_thm ("CONTINUOUS_ABS", 9391 ``!(f:'a->real) net. f continuous net 9392 ==> (\x. abs(f(x)):real) continuous net``, 9393 SIMP_TAC std_ss [continuous, LIM_ABS]); 9394 9395val CONTINUOUS_MAX = store_thm ("CONTINUOUS_MAX", 9396 ``!(f:'a->real) (g:'a->real) net. 9397 f continuous net /\ g continuous net 9398 ==> (\x. (max (f(x)) (g(x))):real) continuous net``, 9399 SIMP_TAC std_ss [continuous, LIM_MAX]); 9400 9401val CONTINUOUS_MIN = store_thm ("CONTINUOUS_MIN", 9402 ``!(f:'a->real) (g:'a->real) net. 9403 f continuous net /\ g continuous net 9404 ==> (\x. (min (f(x)) (g(x))):real) continuous net``, 9405 SIMP_TAC std_ss [continuous, LIM_MIN]); 9406 9407val CONTINUOUS_SUM = store_thm ("CONTINUOUS_SUM", 9408 ``!net f s. FINITE s /\ (!a. a IN s ==> (f a) continuous net) 9409 ==> (\x. sum s (\a. f a x)) continuous net``, 9410 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[CONJ_EQ_IMP] THEN 9411 KNOW_TAC ``!s. ((!a:'b. a IN s ==> f a continuous net) ==> 9412 (\x:'a. sum s (\a. f a x)) continuous net) = 9413 (\s. (!a. a IN s ==> f a continuous net) ==> 9414 (\x. sum s (\a. f a x)) continuous net) s`` THENL 9415 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 9416 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 9417 SIMP_TAC std_ss [FORALL_IN_INSERT, NOT_IN_EMPTY, SUM_CLAUSES, 9418 CONTINUOUS_CONST, CONTINUOUS_ADD, ETA_AX] THEN 9419 METIS_TAC [FORALL_IN_INSERT, NOT_IN_EMPTY, SUM_CLAUSES, 9420 CONTINUOUS_CONST, CONTINUOUS_ADD, ETA_AX]); 9421 9422(* ------------------------------------------------------------------------- *) 9423(* Same thing for setwise continuity. *) 9424(* ------------------------------------------------------------------------- *) 9425 9426val CONTINUOUS_ON_CONST = store_thm ("CONTINUOUS_ON_CONST", 9427 ``!s c. (\x. c) continuous_on s``, 9428 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_CONST]); 9429 9430val CONTINUOUS_ON_CMUL = store_thm ("CONTINUOUS_ON_CMUL", 9431 ``!f c s. f continuous_on s ==> (\x. c * f(x)) continuous_on s``, 9432 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_CMUL]); 9433 9434val CONTINUOUS_ON_NEG = store_thm ("CONTINUOUS_ON_NEG", 9435 ``!f s. f continuous_on s 9436 ==> (\x. -(f x)) continuous_on s``, 9437 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_NEG]); 9438 9439val CONTINUOUS_ON_ADD = store_thm ("CONTINUOUS_ON_ADD", 9440 ``!f g s. f continuous_on s /\ g continuous_on s 9441 ==> (\x. f(x) + g(x)) continuous_on s``, 9442 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_ADD]); 9443 9444val CONTINUOUS_ON_SUB = store_thm ("CONTINUOUS_ON_SUB", 9445 ``!f g s. f continuous_on s /\ g continuous_on s 9446 ==> (\x. f(x) - g(x)) continuous_on s``, 9447 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_SUB]); 9448 9449val CONTINUOUS_ON_ABS = store_thm ("CONTINUOUS_ON_ABS", 9450 ``!f:real->real s. f continuous_on s 9451 ==> (\x. (abs(f(x))):real) continuous_on s``, 9452 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_ABS]); 9453 9454val CONTINUOUS_ON_MAX = store_thm ("CONTINUOUS_ON_MAX", 9455 ``!f:real->real g:real->real s. 9456 f continuous_on s /\ g continuous_on s 9457 ==> (\x. (max (f(x)) (g(x))):real) 9458 continuous_on s``, 9459 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_MAX]); 9460 9461val CONTINUOUS_ON_MIN = store_thm ("CONTINUOUS_ON_MIN", 9462 ``!f:real->real g:real->real s. 9463 f continuous_on s /\ g continuous_on s 9464 ==> (\x. (min (f(x)) (g(x))):real) 9465 continuous_on s``, 9466 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_MIN]); 9467 9468val CONTINUOUS_ON_SUM = store_thm ("CONTINUOUS_ON_SUM", 9469 ``!t f s. FINITE s /\ (!a. a IN s ==> (f a) continuous_on t) 9470 ==> (\x. sum s (\a. f a x)) continuous_on t``, 9471 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_SUM]); 9472 9473(* ------------------------------------------------------------------------- *) 9474(* Same thing for uniform continuity, using sequential formulations. *) 9475(* ------------------------------------------------------------------------- *) 9476 9477val UNIFORMLY_CONTINUOUS_ON_CONST = store_thm ("UNIFORMLY_CONTINUOUS_ON_CONST", 9478 ``!s c. (\x. c) uniformly_continuous_on s``, 9479 SIMP_TAC std_ss [UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY, o_DEF, 9480 REAL_SUB_REFL, LIM_CONST]); 9481 9482val LINEAR_UNIFORMLY_CONTINUOUS_ON = store_thm ("LINEAR_UNIFORMLY_CONTINUOUS_ON", 9483 ``!f:real->real s. linear f ==> f uniformly_continuous_on s``, 9484 REPEAT STRIP_TAC THEN 9485 ASM_SIMP_TAC std_ss [uniformly_continuous_on, dist, GSYM LINEAR_SUB] THEN 9486 FIRST_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o 9487 MATCH_MP LINEAR_BOUNDED_POS) THEN 9488 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN EXISTS_TAC ``e / B:real`` THEN 9489 ASM_SIMP_TAC std_ss [REAL_LT_DIV] THEN 9490 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 9491 MATCH_MP_TAC REAL_LET_TRANS THEN 9492 EXISTS_TAC ``B * abs(y - x:real)`` THEN ASM_REWRITE_TAC[] THEN 9493 ASM_MESON_TAC[REAL_LT_RDIV_EQ, REAL_MUL_SYM]); 9494 9495val lemma = prove ( 9496 ``(!y. ((?x. (y = f x) /\ P x) /\ Q y ==> R y)) <=> 9497 (!x. P x /\ Q (f x) ==> R (f x))``, 9498 MESON_TAC[]); 9499 9500val UNIFORMLY_CONTINUOUS_ON_COMPOSE = store_thm ("UNIFORMLY_CONTINUOUS_ON_COMPOSE", 9501 ``!f g s. f uniformly_continuous_on s /\ 9502 g uniformly_continuous_on (IMAGE f s) 9503 ==> (g o f) uniformly_continuous_on s``, 9504 REPEAT GEN_TAC THEN 9505 SIMP_TAC std_ss [uniformly_continuous_on, o_THM, IN_IMAGE] THEN 9506 KNOW_TAC ``((!e:real. 0 < e ==> ?d. 0 < d /\ 9507 !x x'. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9508 (!e:real. 0 < e ==> ?d. 0 < d /\ 9509 !x x'. (?x'. (x = f x') /\ x' IN s) /\ (?x. (x' = f x) /\ x IN s) /\ 9510 dist (x',x) < d ==> dist (g x',g x) < e) ==> 9511 !e:real. 0 < e ==> ?d. 0 < d /\ 9512 !x x'. x IN s /\ x' IN s /\ dist (x',x) < d ==> 9513 dist (g (f x'),g (f x)) < e) = 9514 ((!e:real. 0 < e ==> ?d. 0 < d /\ 9515 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9516 (!e:real. 0 < e ==> ?d. 0 < d /\ 9517 !x' x. (?x'. (x = f x') /\ x' IN s) /\ (?x. (x' = f x) /\ x IN s) /\ 9518 dist (x',x) < d ==> dist (g x',g x) < e) ==> 9519 !e:real. 0 < e ==> ?d. 0 < d /\ 9520 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> 9521 dist (g (f x'),g (f x)) < e)`` THENL 9522 [METIS_TAC [SWAP_FORALL_THM], ALL_TAC] THEN DISC_RW_KILL THEN 9523 KNOW_TAC `` ((!e:real. 0 < e ==> ?d. 0 < d /\ 9524 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9525 (!e:real. 0 < e ==> ?d. 0 < d /\ 9526 !x' x. (?x'. (x = f x') /\ x' IN s) /\ (?x. (x' = f x) /\ x IN s) /\ 9527 dist (x',x) < d ==> dist (g x',g x) < e) ==> 9528 !e:real. 0 < e ==> ?d. 0 < d /\ 9529 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> 9530 dist (g (f x'),g (f x)) < e) = 9531 ((!e:real. 0 < e ==> ?d. 0 < d /\ 9532 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9533 (!e:real. 0 < e ==> ?d. 0 < d /\ 9534 !x' x. x IN s /\ (?x. (x' = f x) /\ x IN s) /\ dist (x',f x) < d 9535 ==> dist (g x',g (f x)) < e) ==> 9536 !e:real. 0 < e ==> ?d. 0 < d /\ 9537 !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> 9538 dist (g (f x'),g (f x)) < e)`` THENL 9539 [METIS_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN 9540 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN 9541 KNOW_TAC ``((!e. 0 < e ==> ?d. 0 < d /\ 9542 !x' x. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9543 (!e. 0 < e ==> ?d. 0 < d /\ 9544 !x' x. (?x. (x' = f x) /\ x IN s) /\ x IN s /\ dist (x',f x) < d ==> 9545 dist (g x',g (f x)) < e) ==> 9546 !e. 0 < e ==> ?d. 0 < d /\ 9547 !x' x. x' IN s /\ x IN s /\ dist (x',x) < d ==> 9548 dist (g (f x'),g (f x)) < e) = 9549 ((!e. 0 < e ==> ?d. 0 < d /\ 9550 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9551 (!e. 0 < e ==> ?d. 0 < d /\ 9552 !x x'. (?x. (x' = f x) /\ x IN s) /\ x IN s /\ dist (x',f x) < d ==> 9553 dist (g x',g (f x)) < e) ==> 9554 !e. 0 < e ==> ?d. 0 < d /\ 9555 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> 9556 dist (g (f x'),g (f x)) < e)`` THENL 9557 [METIS_TAC [SWAP_FORALL_THM], ALL_TAC] THEN DISC_RW_KILL THEN 9558 KNOW_TAC ``((!e. 0 < e ==> ?d. 0 < d /\ 9559 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9560 (!e. 0 < e ==> ?d. 0 < d /\ 9561 !x x'. (?x. (x' = f x) /\ x IN s) /\ x IN s /\ dist (x',f x) < d ==> 9562 dist (g x',g (f x)) < e) ==> 9563 !e. 0 < e ==> ?d. 0 < d /\ 9564 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> 9565 dist (g (f x'),g (f x)) < e) = 9566 ((!e. 0 < e ==> ?d. 0 < d /\ 9567 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\ 9568 (!e. 0 < e ==> ?d. 0 < d /\ 9569 !x x'. x' IN s /\ x IN s /\ dist (f x',f x) < d ==> 9570 dist (g (f x'),g (f x)) < e) ==> 9571 !e. 0 < e ==> ?d. 0 < d /\ 9572 !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> 9573 dist (g (f x'),g (f x)) < e)`` THENL 9574 [METIS_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN 9575 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 9576 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN 9577 POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 9578 ASM_CASES_TAC ``&0 < e`` THEN ASM_REWRITE_TAC[] THEN 9579 ASM_MESON_TAC[]); 9580 9581val BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE = store_thm ("BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE", 9582 ``!f:real->real g (h:real->real->real) s. 9583 f uniformly_continuous_on s /\ g uniformly_continuous_on s /\ 9584 bilinear h /\ bounded(IMAGE f s) /\ bounded(IMAGE g s) 9585 ==> (\x. h (f x) (g x)) uniformly_continuous_on s``, 9586 REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on, dist] THEN 9587 BETA_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 9588 SUBGOAL_THEN 9589 ``!a b c d. (h:real->real->real) a b - h c d = 9590 h (a - c) b + h c (b - d)`` (fn th => ONCE_REWRITE_TAC[th]) THENL 9591 [FIRST_ASSUM(fn th => REWRITE_TAC[MATCH_MP BILINEAR_LSUB th]) THEN 9592 FIRST_ASSUM(fn th => REWRITE_TAC[MATCH_MP BILINEAR_RSUB th]) THEN 9593 REAL_ARITH_TAC, ALL_TAC] THEN 9594 FIRST_X_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o 9595 MATCH_MP BILINEAR_BOUNDED_POS) THEN 9596 UNDISCH_TAC ``bounded(IMAGE (g:real->real) s)`` THEN 9597 UNDISCH_TAC ``bounded(IMAGE (f:real->real) s)`` THEN 9598 SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE] THEN 9599 DISCH_THEN(X_CHOOSE_THEN ``B1:real`` STRIP_ASSUME_TAC) THEN 9600 DISCH_THEN(X_CHOOSE_THEN ``B2:real`` STRIP_ASSUME_TAC) THEN 9601 UNDISCH_TAC ``(g:real->real) uniformly_continuous_on s`` THEN 9602 UNDISCH_TAC ``(f:real->real) uniformly_continuous_on s`` THEN 9603 REWRITE_TAC[uniformly_continuous_on] THEN 9604 DISCH_THEN(MP_TAC o SPEC ``e:real / &2 / &2 / B / B2``) THEN 9605 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_HALF, dist] THEN 9606 DISCH_THEN(X_CHOOSE_THEN ``d1:real`` STRIP_ASSUME_TAC) THEN 9607 DISCH_THEN(MP_TAC o SPEC ``e:real / &2 / &2 / B / B1``) THEN 9608 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_HALF, dist] THEN 9609 DISCH_THEN(X_CHOOSE_THEN ``d2:real`` STRIP_ASSUME_TAC) THEN 9610 EXISTS_TAC ``min d1 d2:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 9611 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 9612 FIRST_X_ASSUM(MP_TAC o SPECL [``x:real``, ``y:real``]) THEN 9613 FIRST_X_ASSUM(MP_TAC o SPECL [``x:real``, ``y:real``]) THEN 9614 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN 9615 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC 9616 ``B * e / &2 / &2 / B / B2 * B2 + B * B1 * e / &2 / &2 / B / B1:real`` THEN 9617 CONJ_TAC THENL 9618 [MATCH_MP_TAC(REAL_ARITH 9619 ``abs(x) <= a /\ abs(y) <= b ==> abs(x + y:real) <= a + b``) THEN 9620 CONJ_TAC THEN 9621 FIRST_X_ASSUM(fn th => W(MP_TAC o PART_MATCH lhand th o lhand o snd)) THEN 9622 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN 9623 REWRITE_TAC [real_div] THEN REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN 9624 MATCH_MP_TAC REAL_LE_LMUL1 THEN ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE] THENL 9625 [REWRITE_TAC [GSYM real_div, REAL_MUL_ASSOC],ALL_TAC] THEN 9626 MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC [GSYM real_div, REAL_MUL_ASSOC] THEN 9627 ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE, ABS_POS], 9628 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN 9629 REWRITE_TAC [real_div, GSYM REAL_MUL_ASSOC] THEN 9630 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 9631 REWRITE_TAC [GSYM real_div, REAL_MUL_ASSOC] THEN 9632 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN 9633 REWRITE_TAC [real_div] THEN 9634 REWRITE_TAC [REAL_ARITH `` B1 * e * inv 2 * inv 2 * inv B * inv B1 * B = 9635 e * inv 2 * inv 2 * inv B * inv B1 * B1 * B:real``] THEN 9636 REWRITE_TAC [GSYM real_div] THEN 9637 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN 9638 REWRITE_TAC [REAL_HALF_DOUBLE] THEN ASM_SIMP_TAC std_ss [REAL_LT_HALF2]]); 9639 9640val UNIFORMLY_CONTINUOUS_ON_MUL = store_thm ("UNIFORMLY_CONTINUOUS_ON_MUL", 9641 ``!f g:real->real s. 9642 f uniformly_continuous_on s /\ g uniformly_continuous_on s /\ 9643 bounded(IMAGE f s) /\ bounded(IMAGE g s) 9644 ==> (\x. f x * g x) uniformly_continuous_on s``, 9645 REPEAT STRIP_TAC THEN 9646 MP_TAC(ISPECL [``(f:real->real)``, ``g:real->real``, 9647 ``\c (v:real). c * v``, ``s:real->bool``] 9648 BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE) THEN 9649 ASM_SIMP_TAC std_ss [o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN 9650 REWRITE_TAC[bilinear, linear] THEN BETA_TAC THEN REAL_ARITH_TAC); 9651 9652val UNIFORMLY_CONTINUOUS_ON_CMUL = store_thm ("UNIFORMLY_CONTINUOUS_ON_CMUL", 9653 ``!f c s. f uniformly_continuous_on s 9654 ==> (\x. c * f(x)) uniformly_continuous_on s``, 9655 REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN 9656 DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN 9657 POP_ASSUM (MP_TAC o Q.SPECL [`x:num->real`, `y:num->real`]) THEN 9658 DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN 9659 ASM_REWRITE_TAC[] THEN 9660 DISCH_THEN(MP_TAC o MATCH_MP LIM_CMUL) THEN 9661 ASM_SIMP_TAC std_ss [REAL_SUB_LDISTRIB, REAL_MUL_RZERO]); 9662 9663val UNIFORMLY_CONTINUOUS_ON_VMUL = store_thm ("UNIFORMLY_CONTINUOUS_ON_VMUL", 9664 ``!s:real->bool c v:real. 9665 c uniformly_continuous_on s 9666 ==> (\x. c x * v) uniformly_continuous_on s``, 9667 REPEAT GEN_TAC THEN 9668 DISCH_THEN(MP_TAC o ISPEC ``\x. (x * v:real)`` o MATCH_MP 9669 (REWRITE_RULE[CONJ_EQ_IMP] UNIFORMLY_CONTINUOUS_ON_COMPOSE)) THEN 9670 SIMP_TAC std_ss [o_DEF] THEN DISCH_THEN MATCH_MP_TAC THEN 9671 MATCH_MP_TAC LINEAR_UNIFORMLY_CONTINUOUS_ON THEN 9672 REWRITE_TAC [linear] THEN BETA_TAC THEN REAL_ARITH_TAC); 9673 9674val UNIFORMLY_CONTINUOUS_ON_NEG = store_thm ("UNIFORMLY_CONTINUOUS_ON_NEG", 9675 ``!f s. f uniformly_continuous_on s 9676 ==> (\x. -(f x)) uniformly_continuous_on s``, 9677 ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN 9678 REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_CMUL]); 9679 9680val UNIFORMLY_CONTINUOUS_ON_ADD = store_thm ("UNIFORMLY_CONTINUOUS_ON_ADD", 9681 ``!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s 9682 ==> (\x. f(x) + g(x)) uniformly_continuous_on s``, 9683 REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN 9684 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN 9685 DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN 9686 POP_ASSUM (MP_TAC o Q.SPECL [`x:num->real`, `y:num->real`]) THEN 9687 DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN 9688 ASM_SIMP_TAC std_ss [o_DEF] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN 9689 MATCH_MP_TAC EQ_IMPLIES THEN BETA_TAC THEN 9690 REWRITE_TAC[REAL_ADD_LID] THEN AP_THM_TAC THEN BINOP_TAC THEN 9691 REWRITE_TAC[FUN_EQ_THM] THEN BETA_TAC THEN REAL_ARITH_TAC); 9692 9693val UNIFORMLY_CONTINUOUS_ON_SUB = store_thm ("UNIFORMLY_CONTINUOUS_ON_SUB", 9694 ``!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s 9695 ==> (\x. f(x) - g(x)) uniformly_continuous_on s``, 9696 REWRITE_TAC[real_sub] THEN 9697 SIMP_TAC std_ss [UNIFORMLY_CONTINUOUS_ON_NEG, UNIFORMLY_CONTINUOUS_ON_ADD]); 9698 9699val UNIFORMLY_CONTINUOUS_ON_SUM = store_thm ("UNIFORMLY_CONTINUOUS_ON_SUM", 9700 ``!t f s. FINITE s /\ (!a. a IN s ==> (f a) uniformly_continuous_on t) 9701 ==> (\x. sum s (\a. f a x)) uniformly_continuous_on t``, 9702 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[CONJ_EQ_IMP] THEN 9703 KNOW_TAC ``!s. ((!a. a IN s ==> f a uniformly_continuous_on t) ==> 9704 (\x. sum s (\a. f a x)) uniformly_continuous_on t) = 9705 (\s. (!a. a IN s ==> f a uniformly_continuous_on t) ==> 9706 (\x. sum s (\a. f a x)) uniformly_continuous_on t) s`` THENL 9707 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 9708 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN 9709 SIMP_TAC std_ss [FORALL_IN_INSERT, NOT_IN_EMPTY, SUM_CLAUSES, 9710 UNIFORMLY_CONTINUOUS_ON_CONST, ETA_AX] THEN REPEAT STRIP_TAC THEN 9711 METIS_TAC [UNIFORMLY_CONTINUOUS_ON_ADD]); 9712 9713(* ------------------------------------------------------------------------- *) 9714(* Identity function is continuous in every sense. *) 9715(* ------------------------------------------------------------------------- *) 9716 9717val CONTINUOUS_WITHIN_ID = store_thm ("CONTINUOUS_WITHIN_ID", 9718 ``!a s. (\x. x) continuous (at a within s)``, 9719 REWRITE_TAC[continuous_within] THEN MESON_TAC[]); 9720 9721val CONTINUOUS_AT_ID = store_thm ("CONTINUOUS_AT_ID", 9722 ``!a. (\x. x) continuous (at a)``, 9723 REWRITE_TAC[continuous_at] THEN MESON_TAC[]); 9724 9725val CONTINUOUS_ON_ID = store_thm ("CONTINUOUS_ON_ID", 9726 ``!s. (\x. x) continuous_on s``, 9727 REWRITE_TAC[continuous_on] THEN MESON_TAC[]); 9728 9729val UNIFORMLY_CONTINUOUS_ON_ID = store_thm ("UNIFORMLY_CONTINUOUS_ON_ID", 9730 ``!s. (\x. x) uniformly_continuous_on s``, 9731 REWRITE_TAC[uniformly_continuous_on] THEN MESON_TAC[]); 9732 9733(* ------------------------------------------------------------------------- *) 9734(* Continuity of all kinds is preserved under composition. *) 9735(* ------------------------------------------------------------------------- *) 9736 9737val CONTINUOUS_WITHIN_COMPOSE = store_thm ("CONTINUOUS_WITHIN_COMPOSE", 9738 ``!f g x s. f continuous (at x within s) /\ 9739 g continuous (at (f x) within IMAGE f s) 9740 ==> (g o f) continuous (at x within s)``, 9741 REPEAT GEN_TAC THEN SIMP_TAC std_ss [continuous_within, o_THM, IN_IMAGE] THEN 9742 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 9743 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 9744 ASM_MESON_TAC[]); 9745 9746val CONTINUOUS_AT_COMPOSE = store_thm ("CONTINUOUS_AT_COMPOSE", 9747 ``!f g x. f continuous (at x) /\ g continuous (at (f x)) 9748 ==> (g o f) continuous (at x)``, 9749 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 9750 MESON_TAC[CONTINUOUS_WITHIN_COMPOSE, IN_IMAGE, CONTINUOUS_WITHIN_SUBSET, 9751 SUBSET_UNIV, IN_UNIV]); 9752 9753val CONTINUOUS_ON_COMPOSE = store_thm ("CONTINUOUS_ON_COMPOSE", 9754 ``!f g s. f continuous_on s /\ g continuous_on (IMAGE f s) 9755 ==> (g o f) continuous_on s``, 9756 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 9757 MESON_TAC[IN_IMAGE, CONTINUOUS_WITHIN_COMPOSE]); 9758 9759(* ------------------------------------------------------------------------- *) 9760(* Continuity in terms of open preimages. *) 9761(* ------------------------------------------------------------------------- *) 9762 9763val CONTINUOUS_WITHIN_OPEN = store_thm ("CONTINUOUS_WITHIN_OPEN", 9764 ``!f:real->real x u. 9765 f continuous (at x within u) <=> 9766 !t. open t /\ f(x) IN t 9767 ==> ?s. open s /\ x IN s /\ 9768 !x'. x' IN s /\ x' IN u ==> f(x') IN t``, 9769 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL 9770 [DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN 9771 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 9772 GEN_REWR_TAC LAND_CONV [open_def] THEN 9773 DISCH_THEN(MP_TAC o SPEC ``(f:real->real) x``) THEN 9774 ASM_MESON_TAC[IN_BALL, DIST_SYM, OPEN_BALL, CENTRE_IN_BALL, DIST_SYM], 9775 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 9776 FIRST_X_ASSUM(MP_TAC o SPEC ``ball((f:real->real) x,e)``) THEN 9777 ASM_SIMP_TAC std_ss [OPEN_BALL, CENTRE_IN_BALL] THEN 9778 MESON_TAC[open_def, IN_BALL, REAL_LT_TRANS, DIST_SYM]]); 9779 9780val CONTINUOUS_AT_OPEN = store_thm ("CONTINUOUS_AT_OPEN", 9781 ``!f:real->real x. 9782 f continuous (at x) <=> 9783 !t. open t /\ f(x) IN t 9784 ==> ?s. open s /\ x IN s /\ 9785 !x'. x' IN s ==> f(x') IN t``, 9786 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_at] THEN EQ_TAC THENL 9787 [DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN 9788 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 9789 GEN_REWR_TAC LAND_CONV [open_def] THEN 9790 DISCH_THEN(MP_TAC o SPEC ``(f:real->real) x``) THEN 9791 ASM_MESON_TAC[IN_BALL, DIST_SYM, OPEN_BALL, CENTRE_IN_BALL], 9792 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 9793 FIRST_X_ASSUM(MP_TAC o SPEC ``ball((f:real->real) x,e)``) THEN 9794 ASM_SIMP_TAC std_ss [OPEN_BALL, CENTRE_IN_BALL] THEN 9795 MESON_TAC[open_def, IN_BALL, REAL_LT_TRANS, DIST_SYM]]); 9796 9797val CONTINUOUS_ON_OPEN_GEN = store_thm ("CONTINUOUS_ON_OPEN_GEN", 9798 ``!f:real->real s t. 9799 IMAGE f s SUBSET t 9800 ==> (f continuous_on s <=> 9801 !u. open_in (subtopology euclidean t) u 9802 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u})``, 9803 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_on] THEN EQ_TAC THENL 9804 [SIMP_TAC std_ss [open_in, SUBSET_DEF, GSPECIFICATION] THEN 9805 DISCH_TAC THEN X_GEN_TAC ``u:real->bool`` THEN STRIP_TAC THEN 9806 X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN 9807 FIRST_X_ASSUM(MP_TAC o SPEC ``(f:real->real) x``) THEN ASM_SET_TAC[], 9808 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN 9809 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 9810 FIRST_X_ASSUM(MP_TAC o 9811 SPEC ``ball((f:real->real) x,e) INTER t``) THEN 9812 KNOW_TAC ``open_in (subtopology euclidean t) (ball ((f:real->real) x,e) INTER t)`` THENL 9813 [ASM_MESON_TAC[OPEN_IN_OPEN, INTER_COMM, OPEN_BALL], ALL_TAC] THEN 9814 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 9815 SIMP_TAC std_ss [open_in, SUBSET_DEF, IN_INTER, GSPECIFICATION, IN_BALL, IN_IMAGE] THEN 9816 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 9817 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF, FORALL_IN_IMAGE]) THEN 9818 FULL_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 9819 ASM_MESON_TAC[DIST_REFL, DIST_SYM]]); 9820 9821val CONTINUOUS_ON_OPEN = store_thm ("CONTINUOUS_ON_OPEN", 9822 ``!f:real->real s. 9823 f continuous_on s <=> 9824 !t. open_in (subtopology euclidean (IMAGE f s)) t 9825 ==> open_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}``, 9826 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_OPEN_GEN THEN 9827 REWRITE_TAC[SUBSET_REFL]); 9828 9829val CONTINUOUS_OPEN_IN_PREIMAGE_GEN = store_thm ("CONTINUOUS_OPEN_IN_PREIMAGE_GEN", 9830 ``!f:real->real s t u. 9831 f continuous_on s /\ IMAGE f s SUBSET t /\ 9832 open_in (subtopology euclidean t) u 9833 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u}``, 9834 METIS_TAC[CONTINUOUS_ON_OPEN_GEN]); 9835 9836val CONTINUOUS_ON_IMP_OPEN_IN = store_thm ("CONTINUOUS_ON_IMP_OPEN_IN", 9837 ``!f:real->real s t. f continuous_on s /\ 9838 open_in (subtopology euclidean (IMAGE f s)) t 9839 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9840 METIS_TAC[CONTINUOUS_ON_OPEN]); 9841 9842(* ------------------------------------------------------------------------- *) 9843(* Similarly in terms of closed sets. *) 9844(* ------------------------------------------------------------------------- *) 9845 9846val CONTINUOUS_ON_CLOSED_GEN = store_thm ("CONTINUOUS_ON_CLOSED_GEN", 9847 ``!f:real->real s t. 9848 IMAGE f s SUBSET t 9849 ==> (f continuous_on s <=> 9850 !u. closed_in (subtopology euclidean t) u 9851 ==> closed_in (subtopology euclidean s) 9852 {x | x IN s /\ f x IN u})``, 9853 REPEAT STRIP_TAC THEN FIRST_ASSUM(fn th => 9854 ONCE_REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THEN 9855 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``u:real->bool`` THEN 9856 FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THENL 9857 [REWRITE_TAC[closed_in], REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ]] THEN 9858 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 9859 DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN 9860 ASM_SIMP_TAC std_ss [SUBSET_RESTRICT] THEN 9861 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]); 9862 9863val CONTINUOUS_ON_CLOSED = store_thm ("CONTINUOUS_ON_CLOSED", 9864 ``!f:real->real s. 9865 f continuous_on s <=> 9866 !t. closed_in (subtopology euclidean (IMAGE f s)) t 9867 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}``, 9868 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CLOSED_GEN THEN 9869 REWRITE_TAC[SUBSET_REFL]); 9870 9871val CONTINUOUS_CLOSED_IN_PREIMAGE_GEN = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE_GEN", 9872 ``!f:real->real s t u. 9873 f continuous_on s /\ IMAGE f s SUBSET t /\ 9874 closed_in (subtopology euclidean t) u 9875 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN u}``, 9876 METIS_TAC[CONTINUOUS_ON_CLOSED_GEN]); 9877 9878val CONTINUOUS_ON_IMP_CLOSED_IN = store_thm ("CONTINUOUS_ON_IMP_CLOSED_IN", 9879 ``!f:real->real s t. f continuous_on s /\ 9880 closed_in (subtopology euclidean (IMAGE f s)) t 9881 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9882 METIS_TAC[CONTINUOUS_ON_CLOSED]); 9883 9884(* ------------------------------------------------------------------------- *) 9885(* Half-global and completely global cases. *) 9886(* ------------------------------------------------------------------------- *) 9887 9888val CONTINUOUS_OPEN_IN_PREIMAGE = store_thm ("CONTINUOUS_OPEN_IN_PREIMAGE", 9889 ``!f s t. 9890 f continuous_on s /\ open t 9891 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9892 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE 9893 ``x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)``] THEN 9894 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_OPEN]) THEN 9895 ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN 9896 ASM_REWRITE_TAC[]); 9897 9898val CONTINUOUS_CLOSED_IN_PREIMAGE = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE", 9899 ``!f s t. 9900 f continuous_on s /\ closed t 9901 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9902 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE 9903 ``x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)``] THEN 9904 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_CLOSED]) THEN 9905 ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC CLOSED_IN_CLOSED_INTER THEN 9906 ASM_REWRITE_TAC[]); 9907 9908val CONTINUOUS_OPEN_PREIMAGE = store_thm ("CONTINUOUS_OPEN_PREIMAGE", 9909 ``!f:real->real s t. 9910 f continuous_on s /\ open s /\ open t 9911 ==> open {x | x IN s /\ f(x) IN t}``, 9912 REPEAT STRIP_TAC THEN 9913 UNDISCH_TAC ``f continuous_on s`` THEN GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_OPEN] THEN 9914 REWRITE_TAC [OPEN_IN_OPEN] THEN 9915 DISCH_THEN(MP_TAC o SPEC ``IMAGE (f:real->real) s INTER t``) THEN 9916 KNOW_TAC ``(?t'. open t' /\ (IMAGE (f:real->real) s INTER t = IMAGE f s INTER t'))`` THENL 9917 [EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC [], 9918 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN 9919 SUBGOAL_THEN ``{x | x IN s /\ (f:real->real) x IN t} = 9920 s INTER t'`` SUBST1_TAC THENL 9921 [ASM_SET_TAC [], ASM_MESON_TAC [OPEN_INTER]]]); 9922 9923val CONTINUOUS_CLOSED_PREIMAGE = store_thm ("CONTINUOUS_CLOSED_PREIMAGE", 9924 ``!f:real->real s t. 9925 f continuous_on s /\ closed s /\ closed t 9926 ==> closed {x | x IN s /\ f(x) IN t}``, 9927 REPEAT STRIP_TAC THEN UNDISCH_TAC ``f continuous_on s`` THEN 9928 GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_CLOSED] THEN 9929 REWRITE_TAC [CLOSED_IN_CLOSED] THEN 9930 DISCH_THEN(MP_TAC o SPEC ``IMAGE (f:real->real) s INTER t``) THEN 9931 KNOW_TAC ``(?t'. closed t' /\ (IMAGE (f:real->real) s INTER t = IMAGE f s INTER t'))`` THENL 9932 [EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC [], 9933 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN 9934 SUBGOAL_THEN ``{x | x IN s /\ (f:real->real) x IN t} = 9935 s INTER t'`` SUBST1_TAC THENL 9936 [ASM_SET_TAC [], ASM_MESON_TAC [CLOSED_INTER]]]); 9937 9938val CONTINUOUS_OPEN_PREIMAGE_UNIV = store_thm ("CONTINUOUS_OPEN_PREIMAGE_UNIV", 9939 ``!f:real->real s. 9940 (!x. f continuous (at x)) /\ open s ==> open {x | f(x) IN s}``, 9941 REPEAT STRIP_TAC THEN 9942 MP_TAC(SPECL [``f:real->real``, ``univ(:real)``, ``s:real->bool``] 9943 CONTINUOUS_OPEN_PREIMAGE) THEN 9944 ASM_SIMP_TAC std_ss [OPEN_UNIV, IN_UNIV, CONTINUOUS_AT_IMP_CONTINUOUS_ON]); 9945 9946val CONTINUOUS_CLOSED_PREIMAGE_UNIV = store_thm ("CONTINUOUS_CLOSED_PREIMAGE_UNIV", 9947 ``!f:real->real s. 9948 (!x. f continuous (at x)) /\ closed s ==> closed {x | f(x) IN s}``, 9949 REPEAT STRIP_TAC THEN 9950 MP_TAC(SPECL [``f:real->real``, ``univ(:real)``, ``s:real->bool``] 9951 CONTINUOUS_CLOSED_PREIMAGE) THEN 9952 ASM_SIMP_TAC std_ss [CLOSED_UNIV, IN_UNIV, CONTINUOUS_AT_IMP_CONTINUOUS_ON]); 9953 9954val CONTINUOUS_OPEN_IN_PREIMAGE_EQ = store_thm ("CONTINUOUS_OPEN_IN_PREIMAGE_EQ", 9955 ``!f:real->real s. f continuous_on s <=> 9956 !t. open t ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9957 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CONTINUOUS_OPEN_IN_PREIMAGE] THEN 9958 REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN DISCH_TAC THEN 9959 X_GEN_TAC ``t:real->bool`` THEN GEN_REWR_TAC LAND_CONV [OPEN_IN_OPEN] THEN 9960 DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 9961 FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN 9962 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN SET_TAC[]); 9963 9964val CONTINUOUS_CLOSED_IN_PREIMAGE_EQ = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE_EQ", 9965 ``!f:real->real s. f continuous_on s <=> !t. closed t 9966 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``, 9967 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CONTINUOUS_CLOSED_IN_PREIMAGE] THEN 9968 REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN DISCH_TAC THEN 9969 X_GEN_TAC ``t:real->bool`` THEN 9970 GEN_REWR_TAC LAND_CONV [CLOSED_IN_CLOSED] THEN 9971 DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 9972 FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN 9973 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN SET_TAC[]); 9974 9975(* ------------------------------------------------------------------------- *) 9976(* Linear functions are (uniformly) continuous on any set. *) 9977(* ------------------------------------------------------------------------- *) 9978 9979val LINEAR_LIM_0 = store_thm ("LINEAR_LIM_0", 9980 ``!f. linear f ==> (f --> 0) (at (0))``, 9981 REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_AT] THEN 9982 FIRST_X_ASSUM(MP_TAC o MATCH_MP LINEAR_BOUNDED_POS) THEN 9983 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 9984 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN EXISTS_TAC ``e / B:real`` THEN 9985 ASM_SIMP_TAC std_ss [REAL_LT_DIV] THEN REWRITE_TAC[dist, REAL_SUB_RZERO] THEN 9986 ASM_MESON_TAC[REAL_MUL_SYM, REAL_LET_TRANS, REAL_LT_RDIV_EQ]); 9987 9988val LINEAR_CONTINUOUS_AT = store_thm ("LINEAR_CONTINUOUS_AT", 9989 ``!f:real->real a. linear f ==> f continuous (at a)``, 9990 REPEAT STRIP_TAC THEN 9991 MP_TAC(ISPEC ``\x. (f:real->real) (a + x) - f(a)`` LINEAR_LIM_0) THEN 9992 KNOW_TAC ``linear (\x. f (a + x) - f a)`` THENL 9993 [POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [linear] THEN 9994 REPEAT STRIP_TAC THEN REAL_ARITH_TAC, ALL_TAC] THEN 9995 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 9996 SIMP_TAC std_ss [GSYM LIM_NULL, CONTINUOUS_AT] THEN 9997 GEN_REWR_TAC RAND_CONV [LIM_AT_ZERO] THEN SIMP_TAC std_ss []); 9998 9999val LINEAR_CONTINUOUS_WITHIN = store_thm ("LINEAR_CONTINUOUS_WITHIN", 10000 ``!f:real->real s x. linear f ==> f continuous (at x within s)``, 10001 SIMP_TAC std_ss [CONTINUOUS_AT_WITHIN, LINEAR_CONTINUOUS_AT]); 10002 10003val LINEAR_CONTINUOUS_ON = store_thm ("LINEAR_CONTINUOUS_ON", 10004 ``!f:real->real s. linear f ==> f continuous_on s``, 10005 MESON_TAC[LINEAR_CONTINUOUS_AT, CONTINUOUS_AT_IMP_CONTINUOUS_ON]); 10006 10007val LINEAR_CONTINUOUS_COMPOSE = store_thm ("LINEAR_CONTINUOUS_COMPOSE", 10008 ``!net f:'a->real g:real->real. 10009 f continuous net /\ linear g ==> (\x. g(f x)) continuous net``, 10010 SIMP_TAC std_ss [continuous, LIM_LINEAR]); 10011 10012val LINEAR_CONTINUOUS_ON_COMPOSE = store_thm ("LINEAR_CONTINUOUS_ON_COMPOSE", 10013 ``!f:real->real g:real->real s. 10014 f continuous_on s /\ linear g ==> (\x. g(f x)) continuous_on s``, 10015 SIMP_TAC std_ss[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, 10016 LINEAR_CONTINUOUS_COMPOSE]); 10017 10018val CONTINUOUS_COMPONENT_COMPOSE = store_thm ("CONTINUOUS_COMPONENT_COMPOSE", 10019 ``!net f:'a->real i. f continuous net ==> (\x. f x) continuous net``, 10020 REPEAT GEN_TAC THEN 10021 SUBGOAL_THEN ``linear(\x:real. x)`` MP_TAC THENL 10022 [REWRITE_TAC[LINEAR_ID], REWRITE_TAC[GSYM IMP_CONJ_ALT]] THEN 10023 METIS_TAC [LINEAR_CONTINUOUS_COMPOSE]); 10024 10025val CONTINUOUS_ON_COMPONENT_COMPOSE = store_thm ("CONTINUOUS_ON_COMPONENT_COMPOSE", 10026 ``!f:real->real s. f continuous_on s 10027 ==> (\x. f x) continuous_on s``, 10028 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, 10029 CONTINUOUS_COMPONENT_COMPOSE]); 10030 10031(* ------------------------------------------------------------------------- *) 10032(* Also bilinear functions, in composition form. *) 10033(* ------------------------------------------------------------------------- *) 10034 10035val BILINEAR_CONTINUOUS_COMPOSE = store_thm ("BILINEAR_CONTINUOUS_COMPOSE", 10036 ``!net f:'a->real g:'a->real h:real->real->real. 10037 f continuous net /\ g continuous net /\ bilinear h 10038 ==> (\x. h (f x) (g x)) continuous net``, 10039 SIMP_TAC std_ss [continuous, LIM_BILINEAR]); 10040 10041val BILINEAR_CONTINUOUS_ON_COMPOSE = store_thm ("BILINEAR_CONTINUOUS_ON_COMPOSE", 10042 ``!f g h s. f continuous_on s /\ g continuous_on s /\ bilinear h 10043 ==> (\x. h (f x) (g x)) continuous_on s``, 10044 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, 10045 BILINEAR_CONTINUOUS_COMPOSE]); 10046 10047val BILINEAR_DOT = store_thm ("BILINEAR_DOT", 10048 ``bilinear (\x y:real. (x * y))``, 10049SIMP_TAC std_ss [bilinear, linear] THEN REAL_ARITH_TAC); 10050 10051val CONTINUOUS_DOT2 = store_thm ("CONTINUOUS_DOT2", 10052 ``!net f g:'a->real. 10053 f continuous net /\ g continuous net 10054 ==> (\x. f x * g x) continuous net``, 10055 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE 10056 [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`] 10057 BILINEAR_CONTINUOUS_COMPOSE) BILINEAR_DOT)) THEN BETA_TAC THEN REWRITE_TAC[]); 10058 10059val CONTINUOUS_ON_DOT2 = store_thm ("CONTINUOUS_ON_DOT2", 10060 ``!f:real->real g s. 10061 f continuous_on s /\ g continuous_on s 10062 ==> (\x. f x * g x) continuous_on s``, 10063 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE 10064 [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`] 10065 BILINEAR_CONTINUOUS_ON_COMPOSE) BILINEAR_DOT)) THEN BETA_TAC THEN REWRITE_TAC[]); 10066 10067(* ------------------------------------------------------------------------- *) 10068(* Preservation of compactness and connectedness under continuous function. *) 10069(* ------------------------------------------------------------------------- *) 10070 10071val COMPACT_CONTINUOUS_IMAGE = store_thm ("COMPACT_CONTINUOUS_IMAGE", 10072 ``!f:real->real s. 10073 f continuous_on s /\ compact s ==> compact(IMAGE f s)``, 10074 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on, compact] THEN 10075 STRIP_TAC THEN X_GEN_TAC ``y:num->real`` THEN 10076 SIMP_TAC std_ss [IN_IMAGE, SKOLEM_THM, FORALL_AND_THM] THEN 10077 DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN 10078 FIRST_X_ASSUM(MP_TAC o SPEC ``x:num->real``) THEN ASM_REWRITE_TAC[] THEN 10079 KNOW_TAC ``((?(l :real) (r :num -> num). 10080 l IN s /\ (!(m :num) (n :num). m < n ==> r m < r n) /\ 10081 ((x :num -> real) o r --> l) sequentially) ==> 10082 ?(l :real) (r :num -> num). 10083 (?(x :real). (l = f x) /\ x IN s) /\ 10084 (!(m :num) (n :num). m < n ==> r m < r n) /\ 10085 ((y :num -> real) o r --> l) sequentially) = 10086 ((?(r :num -> num) (l :real). 10087 l IN s /\ (!(m :num) (n :num). m < n ==> r m < r n) /\ 10088 ((x :num -> real) o r --> l) sequentially) ==> 10089 ?(r :num -> num) (l :real). 10090 (?(x :real). (l = f x) /\ x IN s) /\ 10091 (!(m :num) (n :num). m < n ==> r m < r n) /\ 10092 ((y :num -> real) o r --> l) sequentially)`` THENL 10093 [METIS_TAC [SWAP_EXISTS_THM], DISC_RW_KILL] THEN 10094 STRIP_TAC THEN EXISTS_TAC ``r:num->num`` THEN 10095 EXISTS_TAC ``(f:real->real) l`` THEN ASM_REWRITE_TAC[] THEN 10096 CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC] THEN 10097 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 10098 FIRST_X_ASSUM(MP_TAC o SPEC ``l:real``) THEN 10099 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN GEN_TAC THEN 10100 POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 10101 DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN 10102 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 10103 UNDISCH_TAC `` ((x :num -> real) o (r :num -> num) --> l) sequentially`` THEN 10104 GEN_REWR_TAC LAND_CONV [LIM_SEQUENTIALLY] THEN 10105 DISCH_THEN(MP_TAC o SPEC ``d:real``) THEN ASM_SIMP_TAC std_ss [o_THM] THEN 10106 ASM_MESON_TAC[]); 10107 10108val COMPACT_TRANSLATION = store_thm ("COMPACT_TRANSLATION", 10109 ``!s a:real. compact s ==> compact (IMAGE (\x. a + x) s)``, 10110 SIMP_TAC std_ss [COMPACT_CONTINUOUS_IMAGE, CONTINUOUS_ON_ADD, 10111 CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID]); 10112 10113val COMPACT_TRANSLATION_EQ = store_thm ("COMPACT_TRANSLATION_EQ", 10114 ``!a s. compact (IMAGE (\x:real. a + x) s) <=> compact s``, 10115 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[COMPACT_TRANSLATION] THEN 10116 DISCH_THEN(MP_TAC o ISPEC ``-a:real`` o MATCH_MP COMPACT_TRANSLATION) THEN 10117 SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID, 10118 REAL_ARITH ``-a + (a + x:real) = x``]); 10119 10120val COMPACT_LINEAR_IMAGE = store_thm ("COMPACT_LINEAR_IMAGE", 10121 ``!f:real->real s. compact s /\ linear f ==> compact(IMAGE f s)``, 10122 SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON, COMPACT_CONTINUOUS_IMAGE]); 10123 10124val CONNECTED_CONTINUOUS_IMAGE = store_thm ("CONNECTED_CONTINUOUS_IMAGE", 10125 ``!f:real->real s. 10126 f continuous_on s /\ connected s ==> connected(IMAGE f s)``, 10127 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN 10128 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 10129 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 10130 SIMP_TAC std_ss [CONNECTED_CLOPEN, NOT_FORALL_THM, NOT_IMP, DE_MORGAN_THM] THEN 10131 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 10132 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 10133 FIRST_X_ASSUM(fn th => MP_TAC(SPEC ``t:real->bool`` th) THEN 10134 MP_TAC(SPEC ``IMAGE (f:real->real) s DIFF t`` th)) THEN 10135 ASM_REWRITE_TAC[] THEN 10136 SUBGOAL_THEN ``{x | x IN s /\ (f:real->real) x IN IMAGE f s DIFF t} = 10137 s DIFF {x | x IN s /\ f x IN t}`` SUBST1_TAC THENL 10138 [UNDISCH_TAC ``t SUBSET IMAGE (f:real->real) s`` THEN 10139 SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_DIFF, GSPECIFICATION, SUBSET_DEF] THEN 10140 MESON_TAC[], 10141 REPEAT STRIP_TAC THEN 10142 EXISTS_TAC ``{x | x IN s /\ (f:real->real) x IN t}`` THEN 10143 ASM_REWRITE_TAC[] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 10144 SIMP_TAC std_ss [IN_IMAGE, SUBSET_DEF, GSPECIFICATION, NOT_IN_EMPTY, EXTENSION] THEN 10145 MESON_TAC[]]); 10146 10147val CONNECTED_TRANSLATION = store_thm ("CONNECTED_TRANSLATION", 10148 ``!a s. connected s ==> connected (IMAGE (\x:real. a + x) s)``, 10149 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN 10150 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_ID, CONTINUOUS_ON_CONST]); 10151 10152val CONNECTED_TRANSLATION_EQ = store_thm ("CONNECTED_TRANSLATION_EQ", 10153 ``!a s. connected (IMAGE (\x:real. a + x) s) <=> connected s``, 10154 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONNECTED_TRANSLATION] THEN 10155 DISCH_THEN(MP_TAC o ISPEC ``-a:real`` o MATCH_MP CONNECTED_TRANSLATION) THEN 10156 SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID, 10157 REAL_ARITH ``-a + (a + x:real) = x``]); 10158 10159val CONNECTED_LINEAR_IMAGE = store_thm ("CONNECTED_LINEAR_IMAGE", 10160 ``!f:real->real s. connected s /\ linear f ==> connected(IMAGE f s)``, 10161 SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON, CONNECTED_CONTINUOUS_IMAGE]); 10162 10163(* ------------------------------------------------------------------------- *) 10164(* Quotient maps are occasionally useful. *) 10165(* ------------------------------------------------------------------------- *) 10166 10167val QUASICOMPACT_OPEN_CLOSED = store_thm ("QUASICOMPACT_OPEN_CLOSED", 10168 ``!f:real->real s t. 10169 IMAGE f s SUBSET t 10170 ==> ((!u. u SUBSET t 10171 ==> (open_in (subtopology euclidean s) 10172 {x | x IN s /\ f x IN u} 10173 ==> open_in (subtopology euclidean t) u)) <=> 10174 (!u. u SUBSET t 10175 ==> (closed_in (subtopology euclidean s) 10176 {x | x IN s /\ f x IN u} 10177 ==> closed_in (subtopology euclidean t) u)))``, 10178 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 10179 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN 10180 X_GEN_TAC ``u:real->bool`` THEN 10181 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN 10182 ASM_SIMP_TAC std_ss [SET_RULE ``u SUBSET t ==> (t DIFF (t DIFF u) = u)``] THEN 10183 REWRITE_TAC [DIFF_SUBSET] THEN REPEAT STRIP_TAC THEN 10184 FIRST_X_ASSUM MATCH_MP_TAC THEN SIMP_TAC std_ss [SUBSET_RESTRICT] THEN 10185 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] 10186 ``open_in top x ==> (x = y) ==> open_in top y``)) THEN 10187 ASM_SET_TAC[]); 10188 10189val QUOTIENT_MAP_IMP_CONTINUOUS_OPEN = store_thm ("QUOTIENT_MAP_IMP_CONTINUOUS_OPEN", 10190 ``!f:real->real s t. 10191 IMAGE f s SUBSET t /\ 10192 (!u. u SUBSET t 10193 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10194 open_in (subtopology euclidean t) u)) 10195 ==> f continuous_on s``, 10196 METIS_TAC[OPEN_IN_IMP_SUBSET, CONTINUOUS_ON_OPEN_GEN]); 10197 10198val QUOTIENT_MAP_IMP_CONTINUOUS_CLOSED = store_thm ("QUOTIENT_MAP_IMP_CONTINUOUS_CLOSED", 10199 ``!f:real->real s t. 10200 IMAGE f s SUBSET t /\ 10201 (!u. u SUBSET t 10202 ==> (closed_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10203 closed_in (subtopology euclidean t) u)) 10204 ==> f continuous_on s``, 10205 METIS_TAC[CLOSED_IN_IMP_SUBSET, CONTINUOUS_ON_CLOSED_GEN]); 10206 10207val OPEN_MAP_IMP_QUOTIENT_MAP = store_thm ("OPEN_MAP_IMP_QUOTIENT_MAP", 10208 ``!f:real->real s. f continuous_on s /\ 10209 (!t. open_in (subtopology euclidean s) t 10210 ==> open_in (subtopology euclidean (IMAGE f s)) (IMAGE f t)) 10211 ==> !t. t SUBSET IMAGE f s 10212 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=> 10213 open_in (subtopology euclidean (IMAGE f s)) t)``, 10214 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 10215 [SUBGOAL_THEN 10216 ``(t = IMAGE f {x | x IN s /\ (f:real->real) x IN t})`` 10217 SUBST1_TAC THENL [ASM_SET_TAC[], ASM_SIMP_TAC std_ss []], 10218 UNDISCH_TAC ``f continuous_on s`` THEN GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_OPEN] THEN 10219 ASM_SIMP_TAC std_ss []]); 10220 10221val CLOSED_MAP_IMP_QUOTIENT_MAP = store_thm ("CLOSED_MAP_IMP_QUOTIENT_MAP", 10222 ``!f:real->real s. f continuous_on s /\ 10223 (!t. closed_in (subtopology euclidean s) t 10224 ==> closed_in (subtopology euclidean (IMAGE f s)) (IMAGE f t)) 10225 ==> !t. t SUBSET IMAGE f s 10226 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=> 10227 open_in (subtopology euclidean (IMAGE f s)) t)``, 10228 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 10229 [FIRST_X_ASSUM(MP_TAC o SPEC 10230 ``s DIFF {x | x IN s /\ (f:real->real) x IN t}``) THEN 10231 KNOW_TAC ``closed_in (subtopology euclidean (s :real -> bool)) 10232 (s DIFF {x | x IN s /\ (f :real -> real) x IN (t :real -> bool)})`` THENL 10233 [MATCH_MP_TAC CLOSED_IN_DIFF THEN 10234 ASM_SIMP_TAC std_ss [CLOSED_IN_SUBTOPOLOGY_REFL, 10235 TOPSPACE_EUCLIDEAN, SUBSET_UNIV], 10236 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 10237 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 10238 DISCH_THEN(MP_TAC o CONJUNCT2) THEN MATCH_MP_TAC EQ_IMPLIES THEN 10239 AP_TERM_TAC THEN ASM_SET_TAC[]], 10240 UNDISCH_TAC ``f continuous_on s`` THEN GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_OPEN] THEN 10241 ASM_SIMP_TAC std_ss []]); 10242 10243val CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP = store_thm ("CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP", 10244 ``!f:real->real g s t. 10245 f continuous_on s /\ IMAGE f s SUBSET t /\ 10246 g continuous_on t /\ IMAGE g t SUBSET s /\ 10247 (!y. y IN t ==> (f(g y) = y)) 10248 ==> (!u. u SUBSET t 10249 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10250 open_in (subtopology euclidean t) u))``, 10251 REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN REPEAT STRIP_TAC THEN EQ_TAC THENL 10252 [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``(IMAGE (g:real->real) t) INTER 10253 {x | x IN s /\ (f:real->real) x IN u}``) THEN 10254 SUBGOAL_THEN ``open_in (subtopology euclidean (IMAGE (g:real->real) t)) 10255 (IMAGE g t INTER {x | x IN s /\ (f:real->real) x IN u})`` 10256 (fn th => REWRITE_TAC[th]) THENL 10257 [POP_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN]) THEN 10258 SIMP_TAC std_ss [OPEN_IN_OPEN] THEN ASM_SET_TAC[], 10259 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]], 10260 DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 10261 SUBGOAL_THEN ``IMAGE (f:real->real) s = t`` 10262 (fn th => ASM_REWRITE_TAC[th]) THEN 10263 ASM_SET_TAC[]]); 10264 10265val CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP = store_thm ("CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP", 10266 ``!f:real->real g s. 10267 f continuous_on s /\ g continuous_on (IMAGE f s) /\ 10268 (!x. x IN s ==> (g(f x) = x)) 10269 ==> (!u. u SUBSET (IMAGE f s) 10270 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10271 open_in (subtopology euclidean (IMAGE f s)) u))``, 10272 REPEAT GEN_TAC THEN STRIP_TAC THEN 10273 MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN 10274 EXISTS_TAC ``g:real->real`` THEN 10275 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]); 10276 10277val QUOTIENT_MAP_OPEN_CLOSED = store_thm ("QUOTIENT_MAP_OPEN_CLOSED", 10278 ``!f:real->real s t. 10279 IMAGE f s SUBSET t 10280 ==> ((!u. u SUBSET t 10281 ==> (open_in (subtopology euclidean s) 10282 {x | x IN s /\ f x IN u} <=> 10283 open_in (subtopology euclidean t) u)) <=> 10284 (!u. u SUBSET t 10285 ==> (closed_in (subtopology euclidean s) 10286 {x | x IN s /\ f x IN u} <=> 10287 closed_in (subtopology euclidean t) u)))``, 10288 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 10289 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN 10290 X_GEN_TAC ``u:real->bool`` THEN 10291 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN 10292 ASM_SIMP_TAC std_ss [SET_RULE ``u SUBSET t ==> (t DIFF (t DIFF u) = u)``] THEN 10293 REWRITE_TAC [DIFF_SUBSET] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN 10294 SIMP_TAC std_ss [SUBSET_RESTRICT] THEN AP_TERM_TAC THEN ASM_SET_TAC[]); 10295 10296val CONTINUOUS_ON_COMPOSE_QUOTIENT = store_thm ("CONTINUOUS_ON_COMPOSE_QUOTIENT", 10297 ``!f:real->real g:real->real s t u. 10298 IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\ 10299 (!v. v SUBSET t 10300 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=> 10301 open_in (subtopology euclidean t) v)) /\ 10302 (g o f) continuous_on s 10303 ==> g continuous_on t``, 10304 REPEAT GEN_TAC THEN 10305 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 10306 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 10307 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 10308 FIRST_ASSUM(fn th => REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THEN 10309 SUBGOAL_THEN 10310 ``IMAGE ((g:real->real) o (f:real->real)) s SUBSET u`` 10311 (fn th => REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THENL 10312 [REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[], DISCH_TAC] THEN 10313 X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN 10314 FIRST_X_ASSUM(MP_TAC o SPEC ``v:real->bool``) THEN 10315 ASM_REWRITE_TAC[o_THM] THEN DISCH_TAC THEN 10316 FIRST_X_ASSUM(MP_TAC o SPEC ``{x | x IN t /\ (g:real->real) x IN v}``) THEN 10317 ASM_SIMP_TAC std_ss [SUBSET_RESTRICT] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN 10318 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[] 10319 ``open_in top s ==> (s = t) ==> open_in top t``)) THEN 10320 ASM_SET_TAC[]); 10321 10322val FUNCTION_FACTORS_LEFT_GEN = store_thm ("FUNCTION_FACTORS_LEFT_GEN", 10323 ``!P f g. (!x y. P x /\ P y /\ (g x = g y) ==> (f x = f y)) <=> 10324 (?h. !x. P x ==> (f(x) = h(g x)))``, 10325 ONCE_REWRITE_TAC[MESON[] 10326 ``(!x. P x ==> (f(x) = g(k x))) <=> (!y x. P x /\ (y = k x) ==> (f x = g y))``] THEN 10327 SIMP_TAC std_ss [GSYM SKOLEM_THM] THEN MESON_TAC[]); 10328 10329val LIFT_TO_QUOTIENT_SPACE = store_thm ("LIFT_TO_QUOTIENT_SPACE", 10330 ``!f:real->real h:real->real s t u. 10331 (IMAGE f s = t) /\ (!v. v SUBSET t 10332 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=> 10333 open_in (subtopology euclidean t) v)) /\ 10334 h continuous_on s /\ (IMAGE h s = u) /\ 10335 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (h x = h y)) 10336 ==> ?g. g continuous_on t /\ (IMAGE g t = u) /\ 10337 !x. x IN s ==> (h(x) = g(f x))``, 10338 REPEAT GEN_TAC THEN 10339 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 10340 SIMP_TAC std_ss [FUNCTION_FACTORS_LEFT_GEN] THEN 10341 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN 10342 EXISTS_TAC ``g:real->real`` THEN 10343 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 10344 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE_QUOTIENT THEN MAP_EVERY EXISTS_TAC 10345 [``f:real->real``, ``s:real->bool``, ``u:real->bool``] THEN 10346 ASM_SIMP_TAC std_ss [SUBSET_REFL] THEN CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 10347 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] 10348 CONTINUOUS_ON_EQ)) THEN ASM_SIMP_TAC std_ss [o_THM]); 10349 10350val QUOTIENT_MAP_COMPOSE = store_thm ("QUOTIENT_MAP_COMPOSE", 10351 ``!f:real->real g:real->real s t u. 10352 IMAGE f s SUBSET t /\ 10353 (!v. v SUBSET t 10354 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=> 10355 open_in (subtopology euclidean t) v)) /\ 10356 (!v. v SUBSET u 10357 ==> (open_in (subtopology euclidean t) {x | x IN t /\ g x IN v} <=> 10358 open_in (subtopology euclidean u) v)) 10359 ==> !v. v SUBSET u 10360 ==> (open_in (subtopology euclidean s) 10361 {x | x IN s /\ (g o f) x IN v} <=> 10362 open_in (subtopology euclidean u) v)``, 10363 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [o_THM] THEN 10364 SUBGOAL_THEN 10365 ``{x | x IN s /\ (g:real->real) ((f:real->real) x) IN v} = 10366 {x | x IN s /\ f x IN {x | x IN t /\ g x IN v}}`` 10367 SUBST1_TAC THENL [ASM_SET_TAC[], ASM_SIMP_TAC std_ss [SUBSET_RESTRICT]]); 10368 10369val QUOTIENT_MAP_FROM_COMPOSITION = store_thm ("QUOTIENT_MAP_FROM_COMPOSITION", 10370 ``!f:real->real g:real->real s t u. 10371 f continuous_on s /\ IMAGE f s SUBSET t /\ 10372 g continuous_on t /\ IMAGE g t SUBSET u /\ 10373 (!v. v SUBSET u 10374 ==> (open_in (subtopology euclidean s) 10375 {x | x IN s /\ (g o f) x IN v} <=> 10376 open_in (subtopology euclidean u) v)) 10377 ==> !v. v SUBSET u 10378 ==> (open_in (subtopology euclidean t) 10379 {x | x IN t /\ g x IN v} <=> 10380 open_in (subtopology euclidean u) v)``, 10381 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL 10382 [FIRST_X_ASSUM(MP_TAC o SPEC ``v:real->bool``) THEN 10383 ASM_SIMP_TAC std_ss [o_THM] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN 10384 SUBGOAL_THEN 10385 ``{x | x IN s /\ (g:real->real) ((f:real->real) x) IN v} = 10386 {x | x IN s /\ f x IN {x | x IN t /\ g x IN v}}`` 10387 SUBST1_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 10388 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN 10389 EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[], 10390 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN 10391 EXISTS_TAC ``u:real->bool`` THEN ASM_REWRITE_TAC[]]); 10392 10393val QUOTIENT_MAP_FROM_SUBSET = store_thm ("QUOTIENT_MAP_FROM_SUBSET", 10394 ``!f:real->real s t u. 10395 f continuous_on t /\ IMAGE f t SUBSET u /\ 10396 s SUBSET t /\ (IMAGE f s = u) /\ 10397 (!v. v SUBSET u 10398 ==> (open_in (subtopology euclidean s) 10399 {x | x IN s /\ f x IN v} <=> 10400 open_in (subtopology euclidean u) v)) 10401 ==> !v. v SUBSET u 10402 ==> (open_in (subtopology euclidean t) 10403 {x | x IN t /\ f x IN v} <=> 10404 open_in (subtopology euclidean u) v)``, 10405 REPEAT GEN_TAC THEN STRIP_TAC THEN 10406 MATCH_MP_TAC QUOTIENT_MAP_FROM_COMPOSITION THEN 10407 MAP_EVERY EXISTS_TAC [``\x:real. x``, ``s:real->bool``] THEN 10408 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ID, IMAGE_ID, o_THM]); 10409 10410val QUOTIENT_MAP_RESTRICT = store_thm ("QUOTIENT_MAP_RESTRICT", 10411 ``!f:real->real s t c. 10412 IMAGE f s SUBSET t /\ 10413 (!u. u SUBSET t 10414 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10415 open_in (subtopology euclidean t) u)) /\ 10416 (open_in (subtopology euclidean t) c \/ 10417 closed_in (subtopology euclidean t) c) 10418 ==> !u. u SUBSET c 10419 ==> (open_in (subtopology euclidean {x | x IN s /\ f x IN c}) 10420 {x | x IN {x | x IN s /\ f x IN c} /\ f x IN u} <=> 10421 open_in (subtopology euclidean c) u)``, 10422 REPEAT GEN_TAC THEN 10423 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 10424 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 10425 DISCH_THEN(fn th => MP_TAC th THEN MP_TAC (MATCH_MP 10426 (REWRITE_RULE[IMP_CONJ_ALT] QUOTIENT_MAP_IMP_CONTINUOUS_OPEN) th)) THEN 10427 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 10428 SUBGOAL_THEN ``IMAGE (f:real->real) {x | x IN s /\ f x IN c} SUBSET c`` 10429 ASSUME_TAC THENL [SET_TAC[], ALL_TAC] THEN 10430 FIRST_X_ASSUM DISJ_CASES_TAC THENL 10431 [FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET), 10432 ASM_SIMP_TAC std_ss [QUOTIENT_MAP_OPEN_CLOSED] THEN 10433 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET)] THEN 10434 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `u:real->bool`) THEN 10435 DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN 10436 (KNOW_TAC ``(u:real->bool) SUBSET t`` THENL 10437 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []]) THEN 10438 (MATCH_MP_TAC EQ_IMPLIES THEN BINOP_TAC THENL 10439 [MATCH_MP_TAC(MESON[] ``(t = s) /\ (P s <=> Q s) ==> (P s <=> Q t)``) THEN 10440 CONJ_TAC THENL [ASM_SET_TAC[], SIMP_TAC std_ss [GSPECIFICATION]], ALL_TAC]) THEN 10441 (EQ_TAC THENL 10442 [MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] OPEN_IN_SUBSET_TRANS) ORELSE 10443 MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] CLOSED_IN_SUBSET_TRANS), 10444 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] OPEN_IN_TRANS) ORELSE 10445 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CLOSED_IN_TRANS)]) THEN 10446 (MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN ORELSE 10447 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN ORELSE ASM_SIMP_TAC std_ss []) THEN 10448 ASM_SET_TAC[]); 10449 10450val CONNECTED_MONOTONE_QUOTIENT_PREIMAGE = store_thm ("CONNECTED_MONOTONE_QUOTIENT_PREIMAGE", 10451 ``!f:real->real s t. 10452 f continuous_on s /\ (IMAGE f s = t) /\ 10453 (!u. u SUBSET t 10454 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10455 open_in (subtopology euclidean t) u)) /\ 10456 (!y. y IN t ==> connected {x | x IN s /\ (f x = y)}) /\ 10457 connected t ==> connected s``, 10458 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [connected, NOT_EXISTS_THM] THEN 10459 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN CCONTR_TAC THEN 10460 FULL_SIMP_TAC std_ss [] THEN UNDISCH_TAC ``connected(t:real->bool)`` THEN 10461 SIMP_TAC std_ss [CONNECTED_OPEN_IN] THEN 10462 MAP_EVERY EXISTS_TAC 10463 [``IMAGE (f:real->real) (s INTER u)``, 10464 ``IMAGE (f:real->real) (s INTER v)``] THEN 10465 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY] THEN 10466 SUBGOAL_THEN 10467 ``IMAGE (f:real->real) (s INTER u) INTER IMAGE f (s INTER v) = {}`` 10468 ASSUME_TAC THENL 10469 [REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN 10470 X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 10471 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN 10472 KNOW_TAC ``y IN t:real->bool`` THENL 10473 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN REWRITE_TAC[connected]] THEN 10474 MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN 10475 ASM_SET_TAC[], ALL_TAC] THEN 10476 ONCE_REWRITE_TAC[CONJ_ASSOC] THEN 10477 CONJ_TAC THENL [CONJ_TAC, ASM_SET_TAC[]] THEN 10478 FIRST_X_ASSUM(fn th => 10479 W(MP_TAC o PART_MATCH (rand o rand) th o snd)) THENL 10480 [KNOW_TAC ``IMAGE (f:real->real) (s INTER u) SUBSET t:real->bool`` THENL 10481 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_THEN(SUBST1_TAC o SYM)], 10482 KNOW_TAC ``IMAGE (f:real->real) (s INTER v) SUBSET t:real->bool`` THENL 10483 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_THEN(SUBST1_TAC o SYM)]] THEN 10484 MATCH_MP_TAC(MESON[] 10485 ``({x | x IN s /\ f x IN IMAGE f u} = u) /\ open_in top u 10486 ==> open_in top {x | x IN s /\ f x IN IMAGE f u}``) THEN 10487 ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER] THEN ASM_SET_TAC[]); 10488 10489val CONNECTED_MONOTONE_QUOTIENT_PREIMAGE_GEN = store_thm ("CONNECTED_MONOTONE_QUOTIENT_PREIMAGE_GEN", 10490 ``!f:real->real s t c. 10491 (IMAGE f s = t) /\ (!u. u SUBSET t 10492 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10493 open_in (subtopology euclidean t) u)) /\ 10494 (!y. y IN t ==> connected {x | x IN s /\ (f x = y)}) /\ 10495 (open_in (subtopology euclidean t) c \/ 10496 closed_in (subtopology euclidean t) c) /\ 10497 connected c ==> connected {x | x IN s /\ f x IN c}``, 10498 REPEAT GEN_TAC THEN 10499 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 10500 MATCH_MP_TAC(ONCE_REWRITE_RULE[CONJ_EQ_IMP] 10501 (REWRITE_RULE[CONJ_ASSOC] CONNECTED_MONOTONE_QUOTIENT_PREIMAGE)) THEN 10502 SUBGOAL_THEN ``(c:real->bool) SUBSET t`` ASSUME_TAC THENL 10503 [ASM_MESON_TAC[OPEN_IN_IMP_SUBSET, CLOSED_IN_IMP_SUBSET], ALL_TAC] THEN 10504 EXISTS_TAC ``f:real->real`` THEN REPEAT CONJ_TAC THENL 10505 [FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] 10506 QUOTIENT_MAP_IMP_CONTINUOUS_OPEN)) THEN 10507 ASM_REWRITE_TAC[SUBSET_REFL] THEN 10508 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN 10509 SIMP_TAC std_ss [SUBSET_RESTRICT], 10510 ASM_SET_TAC[], 10511 MATCH_MP_TAC QUOTIENT_MAP_RESTRICT THEN 10512 METIS_TAC[SUBSET_REFL], 10513 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 10514 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN 10515 KNOW_TAC ``y IN t:real->bool`` THENL 10516 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN MATCH_MP_TAC EQ_IMPLIES] THEN 10517 AP_TERM_TAC THEN ASM_SET_TAC[]]); 10518 10519(* ------------------------------------------------------------------------- *) 10520(* More properties of open and closed maps. *) 10521(* ------------------------------------------------------------------------- *) 10522 10523val CLOSED_MAP_CLOSURES = store_thm ("CLOSED_MAP_CLOSURES", 10524 ``!f:real->real. 10525 (!s. closed s ==> closed(IMAGE f s)) <=> 10526 (!s. closure(IMAGE f s) SUBSET IMAGE f (closure s))``, 10527 GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 10528 [MATCH_MP_TAC CLOSURE_MINIMAL THEN 10529 ASM_SIMP_TAC std_ss [CLOSED_CLOSURE, CLOSURE_SUBSET, IMAGE_SUBSET], 10530 REWRITE_TAC[GSYM CLOSURE_SUBSET_EQ] THEN ASM_MESON_TAC[CLOSURE_CLOSED]]); 10531 10532val OPEN_MAP_INTERIORS = store_thm ("OPEN_MAP_INTERIORS", 10533 ``!f:real->real. 10534 (!s. open s ==> open(IMAGE f s)) <=> 10535 (!s. IMAGE f (interior s) SUBSET interior(IMAGE f s))``, 10536 GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 10537 [MATCH_MP_TAC INTERIOR_MAXIMAL THEN 10538 ASM_SIMP_TAC std_ss [OPEN_INTERIOR, INTERIOR_SUBSET, IMAGE_SUBSET], 10539 REWRITE_TAC[GSYM SUBSET_INTERIOR_EQ] THEN ASM_MESON_TAC[INTERIOR_OPEN]]); 10540 10541val OPEN_MAP_RESTRICT = store_thm ("OPEN_MAP_RESTRICT", 10542 ``!f:real->real s t t'. 10543 (!u. open_in (subtopology euclidean s) u 10544 ==> open_in (subtopology euclidean t) (IMAGE f u)) /\ 10545 t' SUBSET t 10546 ==> !u. open_in (subtopology euclidean {x | x IN s /\ f x IN t'}) u 10547 ==> open_in (subtopology euclidean t') (IMAGE f u)``, 10548 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN 10549 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, CONJ_EQ_IMP] THEN 10550 REPEAT DISCH_TAC THEN X_GEN_TAC ``c:real->bool`` THEN 10551 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN 10552ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]); 10553 10554val CLOSED_MAP_RESTRICT = store_thm ("CLOSED_MAP_RESTRICT", 10555 ``!f:real->real s t t'. 10556 (!u. closed_in (subtopology euclidean s) u 10557 ==> closed_in (subtopology euclidean t) (IMAGE f u)) /\ 10558 t' SUBSET t 10559 ==> !u. closed_in (subtopology euclidean {x | x IN s /\ f x IN t'}) u 10560 ==> closed_in (subtopology euclidean t') (IMAGE f u)``, 10561 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN 10562 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, CONJ_EQ_IMP] THEN 10563 REPEAT DISCH_TAC THEN X_GEN_TAC ``c:real->bool`` THEN 10564 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN 10565 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]); 10566 10567val QUOTIENT_MAP_OPEN_MAP_EQ = store_thm ("QUOTIENT_MAP_OPEN_MAP_EQ", 10568 ``!f:real->real s t. 10569 IMAGE f s SUBSET t /\ 10570 (!u. u SUBSET t 10571 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10572 open_in (subtopology euclidean t) u)) 10573 ==> ((!k. open_in (subtopology euclidean s) k 10574 ==> open_in (subtopology euclidean t) (IMAGE f k)) <=> 10575 (!k. open_in (subtopology euclidean s) k 10576 ==> open_in (subtopology euclidean s) 10577 {x | x IN s /\ f x IN IMAGE f k}))``, 10578 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN 10579 X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN 10580 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 10581 UNDISCH_TAC ``!u. u SUBSET t ==> 10582 (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10583 open_in (subtopology euclidean t) u)`` THEN 10584 DISCH_TAC THEN 10585 FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (f:real->real) k``) THEN 10586 ASM_SIMP_TAC std_ss [IMAGE_SUBSET] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_SET_TAC[]); 10587 10588val QUOTIENT_MAP_CLOSED_MAP_EQ = store_thm ("QUOTIENT_MAP_CLOSED_MAP_EQ", 10589 ``!f:real->real s t. 10590 IMAGE f s SUBSET t /\ 10591 (!u. u SUBSET t 10592 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 10593 open_in (subtopology euclidean t) u)) 10594 ==> ((!k. closed_in (subtopology euclidean s) k 10595 ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=> 10596 (!k. closed_in (subtopology euclidean s) k 10597 ==> closed_in (subtopology euclidean s) 10598 {x | x IN s /\ f x IN IMAGE f k}))``, 10599 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 10600 ASM_SIMP_TAC std_ss [QUOTIENT_MAP_OPEN_CLOSED] THEN 10601 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN 10602 X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN 10603 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 10604 UNDISCH_TAC ``!u. u SUBSET t ==> 10605 (closed_in (subtopology euclidean s) 10606 {x | x IN s /\ f x IN u} <=> 10607 closed_in (subtopology euclidean t) u)`` THEN 10608 DISCH_TAC THEN 10609 FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (f:real->real) k``) THEN 10610 ASM_SIMP_TAC std_ss [IMAGE_SUBSET] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_SET_TAC[]); 10611 10612val CLOSED_MAP_IMP_OPEN_MAP = store_thm ("CLOSED_MAP_IMP_OPEN_MAP", 10613 ``!f:real->real s t. 10614 (IMAGE f s = t) /\ 10615 (!u. closed_in (subtopology euclidean s) u 10616 ==> closed_in (subtopology euclidean t) (IMAGE f u)) /\ 10617 (!u. open_in (subtopology euclidean s) u 10618 ==> open_in (subtopology euclidean s) 10619 {x | x IN s /\ f x IN IMAGE f u}) 10620 ==> (!u. open_in (subtopology euclidean s) u 10621 ==> open_in (subtopology euclidean t) (IMAGE f u))``, 10622 REPEAT STRIP_TAC THEN 10623 SUBGOAL_THEN 10624 ``IMAGE (f:real->real) u = 10625 t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})`` 10626 SUBST1_TAC THENL 10627 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM_SET_TAC[], 10628 MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN 10629 FIRST_X_ASSUM MATCH_MP_TAC THEN 10630 MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN 10631 ASM_SIMP_TAC std_ss [CLOSED_IN_REFL]]); 10632 10633val OPEN_MAP_IMP_CLOSED_MAP = store_thm ("OPEN_MAP_IMP_CLOSED_MAP", 10634 ``!f:real->real s t. 10635 (IMAGE f s = t) /\ 10636 (!u. open_in (subtopology euclidean s) u 10637 ==> open_in (subtopology euclidean t) (IMAGE f u)) /\ 10638 (!u. closed_in (subtopology euclidean s) u 10639 ==> closed_in (subtopology euclidean s) 10640 {x | x IN s /\ f x IN IMAGE f u}) 10641 ==> (!u. closed_in (subtopology euclidean s) u 10642 ==> closed_in (subtopology euclidean t) (IMAGE f u))``, 10643 REPEAT STRIP_TAC THEN 10644 SUBGOAL_THEN 10645 ``IMAGE (f:real->real) u = 10646 t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})`` 10647 SUBST1_TAC THENL 10648 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM_SET_TAC[], 10649 MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN 10650 FIRST_X_ASSUM MATCH_MP_TAC THEN 10651 MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN 10652 ASM_SIMP_TAC std_ss [OPEN_IN_REFL]]); 10653 10654val OPEN_MAP_FROM_COMPOSITION_SURJECTIVE = store_thm ("OPEN_MAP_FROM_COMPOSITION_SURJECTIVE", 10655 ``!f:real->real g:real->real s t u. 10656 f continuous_on s /\ (IMAGE f s = t) /\ IMAGE g t SUBSET u /\ 10657 (!k. open_in (subtopology euclidean s) k 10658 ==> open_in (subtopology euclidean u) (IMAGE (g o f) k)) 10659 ==> (!k. open_in (subtopology euclidean t) k 10660 ==> open_in (subtopology euclidean u) (IMAGE g k))``, 10661 REPEAT STRIP_TAC THEN SUBGOAL_THEN 10662 ``IMAGE g k = IMAGE ((g:real->real) o (f:real->real)) 10663 {x | x IN s /\ f(x) IN k}`` SUBST1_TAC THENL 10664 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 10665 REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[], 10666 FIRST_X_ASSUM MATCH_MP_TAC THEN 10667 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN 10668 EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[SUBSET_REFL]]); 10669 10670val CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE = store_thm ("CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE", 10671 ``!f:real->real g:real->real s t u. 10672 f continuous_on s /\ (IMAGE f s = t) /\ IMAGE g t SUBSET u /\ 10673 (!k. closed_in (subtopology euclidean s) k 10674 ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k)) 10675 ==> (!k. closed_in (subtopology euclidean t) k 10676 ==> closed_in (subtopology euclidean u) (IMAGE g k))``, 10677 REPEAT STRIP_TAC THEN SUBGOAL_THEN 10678 ``IMAGE g k = IMAGE ((g:real->real) o (f:real->real)) 10679 {x | x IN s /\ f(x) IN k}`` SUBST1_TAC THENL 10680 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 10681 REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[], 10682 FIRST_X_ASSUM MATCH_MP_TAC THEN 10683 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN 10684 EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[SUBSET_REFL]]); 10685 10686val OPEN_MAP_FROM_COMPOSITION_INJECTIVE = store_thm ("OPEN_MAP_FROM_COMPOSITION_INJECTIVE", 10687 ``!f:real->real g:real->real s t u. 10688 IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\ 10689 g continuous_on t /\ (!x y. x IN t /\ y IN t /\ (g x = g y) ==> (x = y)) /\ 10690 (!k. open_in (subtopology euclidean s) k 10691 ==> open_in (subtopology euclidean u) (IMAGE (g o f) k)) 10692 ==> (!k. open_in (subtopology euclidean s) k 10693 ==> open_in (subtopology euclidean t) (IMAGE f k))``, 10694 REPEAT STRIP_TAC THEN SUBGOAL_THEN 10695 ``IMAGE f k = {x | x IN t /\ 10696 g(x) IN IMAGE ((g:real->real) o (f:real->real)) k}`` 10697 SUBST1_TAC THENL 10698 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 10699 REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[], 10700 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN 10701 EXISTS_TAC ``u:real->bool`` THEN ASM_SIMP_TAC std_ss []]); 10702 10703val CLOSED_MAP_FROM_COMPOSITION_INJECTIVE = store_thm ("CLOSED_MAP_FROM_COMPOSITION_INJECTIVE", 10704 ``!f:real->real g:real->real s t u. 10705 IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\ 10706 g continuous_on t /\ (!x y. x IN t /\ y IN t /\ (g x = g y) ==> (x = y)) /\ 10707 (!k. closed_in (subtopology euclidean s) k 10708 ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k)) 10709 ==> (!k. closed_in (subtopology euclidean s) k 10710 ==> closed_in (subtopology euclidean t) (IMAGE f k))``, 10711 REPEAT STRIP_TAC THEN SUBGOAL_THEN 10712 ``IMAGE f k = {x | x IN t /\ 10713 g(x) IN IMAGE ((g:real->real) o (f:real->real)) k}`` 10714 SUBST1_TAC THENL 10715 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 10716 REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[], 10717 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN 10718 EXISTS_TAC ``u:real->bool`` THEN ASM_SIMP_TAC std_ss []]); 10719 10720val OPEN_MAP_CLOSED_SUPERSET_PREIMAGE = store_thm ("OPEN_MAP_CLOSED_SUPERSET_PREIMAGE", 10721 ``!f:real->real s t u w. 10722 (!k. open_in (subtopology euclidean s) k 10723 ==> open_in (subtopology euclidean t) (IMAGE f k)) /\ 10724 closed_in (subtopology euclidean s) u /\ 10725 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u 10726 ==> ?v. closed_in (subtopology euclidean t) v /\ 10727 w SUBSET v /\ 10728 {x | x IN s /\ f(x) IN v} SUBSET u``, 10729 REPEAT STRIP_TAC THEN 10730 EXISTS_TAC ``t DIFF IMAGE (f:real->real) (s DIFF u)`` THEN 10731 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 10732 MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN 10733 FIRST_X_ASSUM MATCH_MP_TAC THEN 10734 ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL]); 10735 10736val OPEN_MAP_CLOSED_SUPERSET_PREIMAGE_EQ = store_thm ("OPEN_MAP_CLOSED_SUPERSET_PREIMAGE_EQ", 10737 ``!f:real->real s t. 10738 IMAGE f s SUBSET t 10739 ==> ((!k. open_in (subtopology euclidean s) k 10740 ==> open_in (subtopology euclidean t) (IMAGE f k)) <=> 10741 (!u w. closed_in (subtopology euclidean s) u /\ 10742 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u 10743 ==> ?v. closed_in (subtopology euclidean t) v /\ 10744 w SUBSET v /\ {x | x IN s /\ f(x) IN v} SUBSET u))``, 10745 REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN 10746 ASM_SIMP_TAC std_ss [OPEN_MAP_CLOSED_SUPERSET_PREIMAGE] THEN 10747 FIRST_X_ASSUM(MP_TAC o SPECL 10748 [``s DIFF k:real->bool``, ``t DIFF IMAGE (f:real->real) k``]) THEN 10749 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 10750 ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL] THEN 10751 KNOW_TAC ``t DIFF IMAGE (f:real->real) k SUBSET t /\ 10752 {x | x IN s /\ f x IN t DIFF IMAGE (f:real->real) k} SUBSET s DIFF k`` THENL 10753 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 10754 DISCH_THEN(X_CHOOSE_THEN ``v:real->bool`` STRIP_ASSUME_TAC) THEN 10755 SUBGOAL_THEN ``IMAGE (f:real->real) k = t DIFF v`` SUBST1_TAC THENL 10756 [ASM_SET_TAC[], ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL]]); 10757 10758val CLOSED_MAP_OPEN_SUPERSET_PREIMAGE = store_thm ("CLOSED_MAP_OPEN_SUPERSET_PREIMAGE", 10759 ``!f:real->real s t u w. 10760 (!k. closed_in (subtopology euclidean s) k 10761 ==> closed_in (subtopology euclidean t) (IMAGE f k)) /\ 10762 open_in (subtopology euclidean s) u /\ 10763 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u 10764 ==> ?v. open_in (subtopology euclidean t) v /\ 10765 w SUBSET v /\ 10766 {x | x IN s /\ f(x) IN v} SUBSET u``, 10767 REPEAT STRIP_TAC THEN 10768 EXISTS_TAC ``t DIFF IMAGE (f:real->real) (s DIFF u)`` THEN 10769 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 10770 MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN 10771 FIRST_X_ASSUM MATCH_MP_TAC THEN 10772 ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL]); 10773 10774val CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_EQ = store_thm ("CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_EQ", 10775 ``!f:real->real s t. 10776 IMAGE f s SUBSET t 10777 ==> ((!k. closed_in (subtopology euclidean s) k 10778 ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=> 10779 (!u w. open_in (subtopology euclidean s) u /\ 10780 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u 10781 ==> ?v. open_in (subtopology euclidean t) v /\ 10782 w SUBSET v /\ {x | x IN s /\ f(x) IN v} SUBSET u))``, 10783 REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN 10784 ASM_SIMP_TAC std_ss [CLOSED_MAP_OPEN_SUPERSET_PREIMAGE] THEN 10785 FIRST_X_ASSUM(MP_TAC o SPECL 10786 [``s DIFF k:real->bool``, ``t DIFF IMAGE (f:real->real) k``]) THEN 10787 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 10788 ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL] THEN 10789 KNOW_TAC ``t DIFF IMAGE (f:real->real) k SUBSET t /\ 10790 {x | x IN s /\ f x IN t DIFF IMAGE (f:real->real) k} SUBSET s DIFF k`` THENL 10791 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 10792 DISCH_THEN(X_CHOOSE_THEN ``v:real->bool`` STRIP_ASSUME_TAC) THEN 10793 SUBGOAL_THEN ``IMAGE (f:real->real) k = t DIFF v`` SUBST1_TAC THENL 10794 [ASM_SET_TAC[], ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL]]); 10795 10796val BIGUNION_GSPEC = store_thm ("BIGUNION_GSPEC", 10797 ``(!P f. BIGUNION {f x | P x} = {a | ?x. P x /\ a IN (f x)}) /\ 10798 (!P f. BIGUNION {f x y | P x y} = {a | ?x y. P x y /\ a IN (f x y)}) /\ 10799 (!P f. BIGUNION {f x y z | P x y z} = 10800 {a | ?x y z. P x y z /\ a IN (f x y z)})``, 10801 REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 10802 SIMP_TAC std_ss [IN_BIGUNION, GSPECIFICATION, EXISTS_PROD] THEN MESON_TAC[]); 10803 10804val CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_POINT = store_thm ("CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_POINT", 10805 ``!f:real->real s t. 10806 IMAGE f s SUBSET t 10807 ==> ((!k. closed_in (subtopology euclidean s) k 10808 ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=> 10809 (!u y. open_in (subtopology euclidean s) u /\ 10810 y IN t /\ {x | x IN s /\ (f(x) = y)} SUBSET u 10811 ==> ?v. open_in (subtopology euclidean t) v /\ 10812 y IN v /\ {x | x IN s /\ f(x) IN v} SUBSET u))``, 10813 REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_EQ] THEN 10814 EQ_TAC THEN DISCH_TAC THENL 10815 [MAP_EVERY X_GEN_TAC [``u:real->bool``, ``y:real``] THEN 10816 STRIP_TAC THEN 10817 FIRST_X_ASSUM(MP_TAC o SPECL [``u:real->bool``, ``{y:real}``]) THEN 10818 ASM_REWRITE_TAC[SING_SUBSET, IN_SING], 10819 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``w:real->bool``] THEN 10820 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN 10821 KNOW_TAC ``(!y. ?v. open_in (subtopology euclidean s) u /\ 10822 y IN t /\ {x | x IN s /\ (f x = y)} SUBSET u 10823 ==> open_in (subtopology euclidean t) v /\ 10824 y IN v /\ {x | x IN s /\ f x IN v} SUBSET u) 10825 ==> (?v. open_in (subtopology euclidean t) v /\ 10826 w SUBSET v /\ {x | x IN s /\ f x IN v} SUBSET u)`` THENL 10827 [ALL_TAC, METIS_TAC [GSYM RIGHT_EXISTS_IMP_THM]] THEN 10828 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 10829 X_GEN_TAC ``vv:real->real->bool`` THEN DISCH_TAC THEN 10830 EXISTS_TAC ``BIGUNION {(vv:real->real->bool) y | y IN w}`` THEN 10831 CONJ_TAC THENL 10832 [MATCH_MP_TAC OPEN_IN_BIGUNION THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN 10833 ASM_SET_TAC[], 10834 SIMP_TAC std_ss [BIGUNION_GSPEC] THEN 10835 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 10836 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, GSYM RIGHT_EXISTS_AND_THM, 10837 LEFT_IMP_EXISTS_THM] THEN 10838 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 10839 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN ASM_SET_TAC[]]]); 10840 10841val CONNECTED_OPEN_MONOTONE_PREIMAGE = store_thm ("CONNECTED_OPEN_MONOTONE_PREIMAGE", 10842 ``!f:real->real s t. 10843 f continuous_on s /\ (IMAGE f s = t) /\ 10844 (!c. open_in (subtopology euclidean s) c 10845 ==> open_in (subtopology euclidean t) (IMAGE f c)) /\ 10846 (!y. y IN t ==> connected {x | x IN s /\ (f x = y)}) 10847 ==> !c. connected c /\ c SUBSET t 10848 ==> connected {x | x IN s /\ f x IN c}``, 10849 REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``c:real->bool`` o MATCH_MP 10850 (ONCE_REWRITE_RULE[CONJ_EQ_IMP] OPEN_MAP_RESTRICT)) THEN 10851 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC(ISPECL 10852 [``f:real->real``, ``{x | x IN s /\ (f:real->real) x IN c}``] 10853 OPEN_MAP_IMP_QUOTIENT_MAP) THEN 10854 SUBGOAL_THEN ``IMAGE f {x | x IN s /\ (f:real->real) x IN c} = c`` 10855 ASSUME_TAC THENL [ASM_SET_TAC[], ASM_REWRITE_TAC[]] THEN 10856 KNOW_TAC ``(f:real->real) continuous_on {x | x IN s /\ f x IN c}`` THENL 10857 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 10858 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[], 10859 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN 10860 MATCH_MP_TAC CONNECTED_MONOTONE_QUOTIENT_PREIMAGE THEN 10861 MAP_EVERY EXISTS_TAC [``f:real->real``, ``c:real->bool``] THEN 10862 ASM_REWRITE_TAC[] THEN 10863 SIMP_TAC std_ss [SET_RULE 10864 ``y IN c ==> ({x | x IN {x | x IN s /\ f x IN c} /\ (f x = y)} = 10865 {x | x IN s /\ (f x = y)})``] THEN 10866 ASM_SET_TAC[]); 10867 10868val CONNECTED_CLOSED_MONOTONE_PREIMAGE = store_thm ("CONNECTED_CLOSED_MONOTONE_PREIMAGE", 10869 ``!f:real->real s t. 10870 f continuous_on s /\ (IMAGE f s = t) /\ 10871 (!c. closed_in (subtopology euclidean s) c 10872 ==> closed_in (subtopology euclidean t) (IMAGE f c)) /\ 10873 (!y. y IN t ==> connected {x | x IN s /\ (f x = y)}) 10874 ==> !c. connected c /\ c SUBSET t 10875 ==> connected {x | x IN s /\ f x IN c}``, 10876 REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``c:real->bool`` o MATCH_MP 10877 (ONCE_REWRITE_RULE[CONJ_EQ_IMP] CLOSED_MAP_RESTRICT)) THEN 10878 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC(ISPECL 10879 [``f:real->real``, ``{x | x IN s /\ (f:real->real) x IN c}``] 10880 CLOSED_MAP_IMP_QUOTIENT_MAP) THEN 10881 SUBGOAL_THEN ``IMAGE f {x | x IN s /\ (f:real->real) x IN c} = c`` 10882 ASSUME_TAC THENL [ASM_SET_TAC[], ASM_REWRITE_TAC[]] THEN 10883 KNOW_TAC ``(f:real->real) continuous_on {x | x IN s /\ f x IN c}`` THENL 10884 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 10885 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[], 10886 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN 10887 MATCH_MP_TAC CONNECTED_MONOTONE_QUOTIENT_PREIMAGE THEN 10888 MAP_EVERY EXISTS_TAC [``f:real->real``, ``c:real->bool``] THEN 10889 ASM_REWRITE_TAC[] THEN 10890 SIMP_TAC std_ss [SET_RULE 10891 ``y IN c ==> ({x | x IN {x | x IN s /\ f x IN c} /\ (f x = y)} = 10892 {x | x IN s /\ (f x = y)})``] THEN 10893 ASM_SET_TAC[]); 10894 10895(* ------------------------------------------------------------------------- *) 10896(* Proper maps, including projections out of compact sets. *) 10897(* ------------------------------------------------------------------------- *) 10898 10899val PROPER_MAP = store_thm ("PROPER_MAP", 10900 ``!f:real->real s t. 10901 IMAGE f s SUBSET t 10902 ==> ((!k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}) <=> 10903 (!k. closed_in (subtopology euclidean s) k 10904 ==> closed_in (subtopology euclidean t) (IMAGE f k)) /\ 10905 (!a. a IN t ==> compact {x | x IN s /\ (f x = a)}))``, 10906 REPEAT STRIP_TAC THEN EQ_TAC THENL 10907 [REPEAT STRIP_TAC THENL 10908 [ALL_TAC, 10909 ONCE_REWRITE_TAC[SET_RULE ``(x = a) <=> x IN {a}``] THEN 10910 FIRST_X_ASSUM MATCH_MP_TAC THEN 10911 ASM_REWRITE_TAC[SING_SUBSET, COMPACT_SING]] THEN 10912 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 10913 REWRITE_TAC[CLOSED_IN_LIMPT] THEN 10914 CONJ_TAC THENL [ASM_SET_TAC[], X_GEN_TAC ``y:real``] THEN 10915 REWRITE_TAC[LIMPT_SEQUENTIAL_INJ, IN_DELETE] THEN 10916 SIMP_TAC std_ss [IN_IMAGE, GSYM LEFT_EXISTS_AND_THM, SKOLEM_THM] THEN 10917 KNOW_TAC ``(?(x :num -> real) (f' :num -> real). 10918 ((!(n :num). 10919 ((f' n = (f :real -> real) (x n)) /\ 10920 x n IN (k :real -> bool)) /\ f' n <> (y :real)) /\ 10921 (!(m :num) (n :num). (f' m = f' n) <=> (m = n)) /\ 10922 ((f' --> y) sequentially :bool)) /\ y IN (t :real -> bool)) ==> 10923 ?(x :real). (y = f x) /\ x IN k`` THENL 10924 [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN 10925 SIMP_TAC std_ss [GSYM CONJ_ASSOC, FORALL_AND_THM] THEN 10926 SIMP_TAC std_ss [GSYM FUN_EQ_THM] THEN 10927 SIMP_TAC std_ss [UNWIND_THM2, FUN_EQ_THM] THEN 10928 DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN 10929 SUBGOAL_THEN 10930 ``~(BIGINTER {{a | a IN k /\ (f:real->real) a IN 10931 (y INSERT IMAGE (\i. f(x(n + i))) univ(:num))} | n IN univ(:num)} = {})`` 10932 MP_TAC THENL 10933 [MATCH_MP_TAC COMPACT_FIP THEN CONJ_TAC THENL 10934 [SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV] THEN X_GEN_TAC ``n:num`` THEN 10935 UNDISCH_TAC ``closed_in (subtopology euclidean s) k`` THEN DISCH_TAC THEN 10936 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [CLOSED_IN_CLOSED]) THEN 10937 DISCH_THEN(X_CHOOSE_THEN ``c:real->bool`` STRIP_ASSUME_TAC) THEN 10938 ONCE_REWRITE_TAC [METIS [] ``f a IN s = (\a. f a IN s) a``] THEN 10939 ASM_REWRITE_TAC[SET_RULE 10940 ``{x | x IN s INTER k /\ P x} = k INTER {x | x IN s /\ P x}``] THEN 10941 MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN 10942 BETA_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 10943 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 10944 MATCH_MP_TAC COMPACT_SEQUENCE_WITH_LIMIT THEN 10945 UNDISCH_TAC ``((\n. f ((x:num->real) n)) --> y) sequentially`` THEN DISCH_TAC THEN 10946 FIRST_ASSUM(MP_TAC o SPEC ``n:num`` o MATCH_MP SEQ_OFFSET) THEN 10947 BETA_TAC THEN GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [ADD_SYM] THEN 10948 SIMP_TAC std_ss [], 10949 SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_FINITE_SUBSET_IMAGE] THEN 10950 X_GEN_TAC ``i:num->bool`` THEN STRIP_TAC THEN 10951 UNDISCH_TAC ``FINITE (i:num->bool)`` THEN DISCH_TAC THEN 10952 FIRST_ASSUM(MP_TAC o ISPEC ``\n:num. n`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN 10953 SIMP_TAC std_ss [] THEN DISCH_THEN(X_CHOOSE_TAC ``m:num``) THEN 10954 SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, BIGINTER_IMAGE, GSPECIFICATION] THEN 10955 EXISTS_TAC ``(x:num->real) m`` THEN 10956 X_GEN_TAC ``p:num`` THEN DISCH_TAC THEN 10957 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 10958 REWRITE_TAC[IN_INSERT, IN_IMAGE, IN_UNIV] THEN DISJ2_TAC THEN 10959 EXISTS_TAC ``m - p:num`` THEN BETA_TAC THEN 10960 UNDISCH_TAC ``!x:num. x IN i ==> x <= m`` THEN DISCH_THEN (MP_TAC o SPEC ``p:num``) THEN 10961 ASM_REWRITE_TAC [] THEN ARITH_TAC], 10962 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN 10963 DISCH_THEN (X_CHOOSE_TAC ``x:real``) THEN EXISTS_TAC ``x:real`` THEN 10964 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [BIGINTER_GSPEC, GSPECIFICATION, IN_UNIV] THEN 10965 DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``0:num``) THEN 10966 SIMP_TAC std_ss [ADD_CLAUSES, IN_INSERT, IN_IMAGE, IN_UNIV] THEN 10967 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (DISJ_CASES_THEN MP_TAC)) THEN 10968 ASM_SIMP_TAC std_ss [] THEN DISCH_THEN(X_CHOOSE_TAC ``i:num``) THEN 10969 FIRST_X_ASSUM (MP_TAC o SPEC ``i + 1:num``) THEN 10970 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 10971 ASM_SIMP_TAC std_ss [IN_INSERT, IN_IMAGE, IN_UNIV] THEN ARITH_TAC], 10972 STRIP_TAC THEN X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN 10973 REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN 10974 X_GEN_TAC ``c:(real->bool)->bool`` THEN STRIP_TAC THEN 10975 SUBGOAL_THEN 10976 ``!a. a IN k 10977 ==> ?g. g SUBSET c /\ FINITE g /\ 10978 {x | x IN s /\ ((f:real->real) x = a)} SUBSET BIGUNION g`` 10979 MP_TAC THENL 10980 [X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN UNDISCH_THEN 10981 ``!a. a IN t ==> compact {x | x IN s /\ ((f:real->real) x = a)}`` 10982 (MP_TAC o SPEC ``a:real``) THEN 10983 KNOW_TAC ``(a :real) IN (t :real -> bool)`` THENL 10984 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 10985 POP_ASSUM K_TAC THEN REWRITE_TAC[COMPACT_EQ_HEINE_BOREL]] THEN 10986 DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_SET_TAC[], 10987 DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 10988 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 10989 X_GEN_TAC ``uu:real->(real->bool)->bool`` THEN DISCH_TAC] THEN 10990 SUBGOAL_THEN 10991 ``!a. a IN k ==> ?v. open v /\ a IN v /\ 10992 {x | x IN s /\ (f:real->real) x IN v} SUBSET BIGUNION(uu a)`` 10993 MP_TAC THENL 10994 [REPEAT STRIP_TAC THEN 10995 UNDISCH_THEN 10996 ``!k. closed_in (subtopology euclidean s) k 10997 ==> closed_in (subtopology euclidean t) (IMAGE (f:real->real) k)`` 10998 (MP_TAC o SPEC ``(s:real->bool) DIFF BIGUNION(uu(a:real))``) THEN 10999 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 11000 KNOW_TAC ``(s :real -> bool) DIFF 11001 BIGUNION ((uu :real -> (real -> bool) -> bool) (a :real)) SUBSET s /\ 11002 open_in (subtopology euclidean s) (s DIFF (s DIFF BIGUNION (uu a)))`` THENL 11003 [CONJ_TAC THENL [SET_TAC[], ALL_TAC] THEN 11004 REWRITE_TAC[SET_RULE ``s DIFF (s DIFF t) = s INTER t``] THEN 11005 MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN 11006 MATCH_MP_TAC OPEN_BIGUNION THEN ASM_SET_TAC[], 11007 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 11008 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 11009 REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN (X_CHOOSE_TAC ``v:real->bool``) THEN 11010 EXISTS_TAC ``v:real->bool`` THEN POP_ASSUM MP_TAC THEN 11011 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 11012 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC ``a:real``)) THEN 11013 ASM_REWRITE_TAC[] THEN 11014 KNOW_TAC ``a IN t:real->bool`` THENL [ASM_SET_TAC[], 11015 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN DISCH_TAC] THEN 11016 STRIP_TAC THEN ASM_SET_TAC[]], 11017 DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 11018 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 11019 X_GEN_TAC ``vv:real->(real->bool)`` THEN DISCH_TAC] THEN 11020 UNDISCH_TAC ``compact k`` THEN DISCH_TAC THEN 11021 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [COMPACT_EQ_HEINE_BOREL]) THEN 11022 DISCH_THEN(MP_TAC o SPEC ``IMAGE (vv:real->(real->bool)) k``) THEN 11023 KNOW_TAC ``(!(t :real -> bool). 11024 t IN IMAGE (vv :real -> real -> bool) (k :real -> bool) ==> 11025 (open t :bool)) /\ k SUBSET BIGUNION (IMAGE vv k)`` THENL 11026 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11027 POP_ASSUM K_TAC THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM]] THEN 11028 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r ==> s <=> q /\ p ==> r ==> s`] THEN 11029 SIMP_TAC real_ss [FORALL_FINITE_SUBSET_IMAGE] THEN 11030 X_GEN_TAC ``j:real->bool`` THEN REPEAT STRIP_TAC THEN 11031 EXISTS_TAC ``BIGUNION (IMAGE (uu:real->(real->bool)->bool) j)`` THEN 11032 REPEAT CONJ_TAC THENL 11033 [ASM_SET_TAC[], 11034 ASM_SIMP_TAC std_ss [FINITE_BIGUNION_EQ, FORALL_IN_IMAGE, IMAGE_FINITE] THEN 11035 ASM_SET_TAC[], 11036 SIMP_TAC std_ss [BIGUNION_IMAGE, SUBSET_DEF, IN_BIGUNION, GSPECIFICATION] THEN 11037 ASM_SET_TAC[]]]); 11038 11039val COMPACT_CONTINUOUS_IMAGE_EQ = store_thm ("COMPACT_CONTINUOUS_IMAGE_EQ", 11040 ``!f:real->real s. 11041 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 11042 ==> (f continuous_on s <=> 11043 !t. compact t /\ t SUBSET s ==> compact(IMAGE f t))``, 11044 REPEAT STRIP_TAC THEN EQ_TAC THENL 11045 [MESON_TAC[COMPACT_CONTINUOUS_IMAGE, CONTINUOUS_ON_SUBSET], DISCH_TAC] THEN 11046 FIRST_X_ASSUM(X_CHOOSE_TAC ``g:real->real`` o 11047 SIMP_RULE std_ss [INJECTIVE_ON_LEFT_INVERSE]) THEN 11048 REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN 11049 X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 11050 MP_TAC(ISPECL [``g:real->real``, ``IMAGE (f:real->real) s``, 11051 ``s:real->bool``] PROPER_MAP) THEN 11052 KNOW_TAC ``IMAGE (g :real -> real) 11053 (IMAGE (f :real -> real) (s :real -> bool)) SUBSET s`` THENL 11054 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11055 POP_ASSUM K_TAC] THEN 11056 MATCH_MP_TAC(TAUT `(q ==> s) /\ p ==> (p <=> q /\ r) ==> s`) THEN 11057 REPEAT STRIP_TAC THENL 11058 [SUBGOAL_THEN 11059 ``{x | x IN s /\ (f:real->real) x IN u} = IMAGE g u`` 11060 (fn th => ASM_MESON_TAC[th]), 11061 SUBGOAL_THEN 11062 ``{x | x IN IMAGE f s /\ (g:real->real) x IN k} = IMAGE f k`` 11063 (fn th => ASM_SIMP_TAC std_ss [th])] THEN 11064 UNDISCH_TAC `` closed_in 11065 (subtopology euclidean 11066 (IMAGE (f :real -> real) (s :real -> bool))) 11067 (u :real -> bool)`` THEN DISCH_TAC THEN 11068 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM_SET_TAC[]); 11069 11070val PROPER_MAP_FROM_COMPACT = store_thm ("PROPER_MAP_FROM_COMPACT", 11071 ``!f:real->real s k. 11072 f continuous_on s /\ IMAGE f s SUBSET t /\ compact s /\ 11073 closed_in (subtopology euclidean t) k 11074 ==> compact {x | x IN s /\ f x IN k}``, 11075 REPEAT STRIP_TAC THEN 11076 MATCH_MP_TAC CLOSED_IN_COMPACT THEN EXISTS_TAC ``s:real->bool`` THEN 11077 METIS_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_GEN]); 11078 11079val PROPER_MAP_COMPOSE = store_thm ("PROPER_MAP_COMPOSE", 11080 ``!f:real->real g:real->real s t u. 11081 IMAGE f s SUBSET t /\ 11082 (!k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}) /\ 11083 (!k. k SUBSET u /\ compact k ==> compact {x | x IN t /\ g x IN k}) 11084 ==> !k. k SUBSET u /\ compact k 11085 ==> compact {x | x IN s /\ (g o f) x IN k}``, 11086 REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN 11087 FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN 11088 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 11089 FIRST_X_ASSUM(MP_TAC o SPEC ``{x | x IN t /\ (g:real->real) x IN k}``) THEN 11090 KNOW_TAC ``{x | x IN (t :real -> bool) /\ 11091 (g :real -> real) x IN (k :real -> bool)} SUBSET t /\ 11092 compact {x | x IN t /\ g x IN k}`` THENL 11093 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11094 POP_ASSUM K_TAC THEN MATCH_MP_TAC EQ_IMPLIES] THEN 11095 AP_TERM_TAC THEN ASM_SET_TAC[]); 11096 11097val PROPER_MAP_FROM_COMPOSITION_LEFT = store_thm ("PROPER_MAP_FROM_COMPOSITION_LEFT", 11098 ``!f:real->real g:real->real s t u. 11099 f continuous_on s /\ (IMAGE f s = t) /\ 11100 g continuous_on t /\ IMAGE g t SUBSET u /\ 11101 (!k. k SUBSET u /\ compact k 11102 ==> compact {x | x IN s /\ (g o f) x IN k}) 11103 ==> !k. k SUBSET u /\ compact k ==> compact {x | x IN t /\ g x IN k}``, 11104 REWRITE_TAC[o_THM] THEN REPEAT STRIP_TAC THEN 11105 FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN ASM_REWRITE_TAC[] THEN 11106 DISCH_THEN(MP_TAC o ISPEC ``f:real->real`` o MATCH_MP 11107 (REWRITE_RULE[IMP_CONJ_ALT] COMPACT_CONTINUOUS_IMAGE)) THEN 11108 KNOW_TAC ``(f :real -> real) continuous_on 11109 {x | x IN (s :real -> bool) /\ 11110 (g :real -> real) (f x) IN (k :real -> bool)} `` THENL 11111 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 11112 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[], 11113 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 11114 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]]); 11115 11116val lemma = prove ( 11117 ``!s t. closed_in (subtopology euclidean s) t ==> compact s ==> compact t``, 11118 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_SUBSET, CLOSED_IN_CLOSED_EQ]); 11119 11120val PROPER_MAP_FROM_COMPOSITION_RIGHT = store_thm ("PROPER_MAP_FROM_COMPOSITION_RIGHT", 11121 ``!f:real->real g:real->real s t u. 11122 f continuous_on s /\ IMAGE f s SUBSET t /\ 11123 g continuous_on t /\ IMAGE g t SUBSET u /\ 11124 (!k. k SUBSET u /\ compact k 11125 ==> compact {x | x IN s /\ (g o f) x IN k}) 11126 ==> !k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}``, 11127 REWRITE_TAC[o_THM] THEN REPEAT STRIP_TAC THEN 11128 FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (g:real->real) k``) THEN 11129 KNOW_TAC ``IMAGE (g :real -> real) (k :real -> bool) SUBSET (u :real -> bool) /\ 11130 compact (IMAGE g k)`` THENL 11131 [CONJ_TAC THENL [ASM_SET_TAC[], MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE] THEN 11132 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET], 11133 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 11134 MATCH_MP_TAC lemma THEN 11135 MATCH_MP_TAC CLOSED_IN_SUBSET_TRANS THEN 11136 EXISTS_TAC ``s:real->bool`` THEN 11137 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 11138 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN 11139 EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[] THEN 11140 MATCH_MP_TAC CLOSED_SUBSET THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED]]); 11141 11142(* ------------------------------------------------------------------------- *) 11143(* Pasting functions together on open sets. *) 11144(* ------------------------------------------------------------------------- *) 11145 11146val PASTING_LEMMA = store_thm ("PASTING_LEMMA", 11147 ``!f:'a->real->real g t s k. 11148 (!i. i IN k 11149 ==> open_in (subtopology euclidean s) (t i) /\ 11150 (f i) continuous_on (t i)) /\ 11151 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j 11152 ==> (f i x = f j x)) /\ 11153 (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ (g x = f j x)) 11154 ==> g continuous_on s``, 11155 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN 11156 STRIP_TAC THEN X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 11157 SUBGOAL_THEN 11158 ``{x | x IN s /\ g x IN u} = 11159 BIGUNION {{x | x IN (t i) /\ ((f:'a->real->real) i x) IN u} | 11160 i IN k}`` 11161 SUBST1_TAC THENL 11162 [SUBGOAL_THEN ``!i. i IN k ==> ((t:'a->real->bool) i) SUBSET s`` 11163 ASSUME_TAC THENL 11164 [ASM_MESON_TAC[OPEN_IN_SUBSET, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY], 11165 SIMP_TAC std_ss [BIGUNION_GSPEC] THEN ASM_SET_TAC[]], 11166 MATCH_MP_TAC OPEN_IN_BIGUNION THEN SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 11167 METIS_TAC[OPEN_IN_TRANS]]); 11168 11169val PASTING_LEMMA_EXISTS = store_thm ("PASTING_LEMMA_EXISTS", 11170 ``!f:'a->real->real t s k. 11171 s SUBSET BIGUNION {t i | i IN k} /\ 11172 (!i. i IN k 11173 ==> open_in (subtopology euclidean s) (t i) /\ 11174 (f i) continuous_on (t i)) /\ 11175 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j 11176 ==> (f i x = f j x)) 11177 ==> ?g. g continuous_on s /\ 11178 (!x i. i IN k /\ x IN s INTER t i ==> (g x = f i x))``, 11179 REPEAT STRIP_TAC THEN 11180 EXISTS_TAC ``\x. (f:'a->real->real)(@i. i IN k /\ x IN t i) x`` THEN 11181 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN MATCH_MP_TAC PASTING_LEMMA THEN 11182 MAP_EVERY EXISTS_TAC 11183 [``f:'a->real->real``, ``t:'a->real->bool``, ``k:'a->bool``] THEN 11184 ASM_SET_TAC[]); 11185 11186val CONTINUOUS_ON_UNION_LOCAL_OPEN = store_thm ("CONTINUOUS_ON_UNION_LOCAL_OPEN", 11187 ``!f:real->real s. 11188 open_in (subtopology euclidean (s UNION t)) s /\ 11189 open_in (subtopology euclidean (s UNION t)) t /\ 11190 f continuous_on s /\ f continuous_on t 11191 ==> f continuous_on (s UNION t)``, 11192 REPEAT STRIP_TAC THEN MP_TAC(ISPECL 11193 [``(\i:(real->bool). (f:real->real))``, ``f:real->real``, 11194 ``(\i:(real->bool). i)``, ``s UNION (t:real->bool)``, ``{s:real->bool;t}``] 11195 PASTING_LEMMA) THEN DISCH_THEN MATCH_MP_TAC THEN 11196 ASM_SIMP_TAC std_ss [FORALL_IN_INSERT, EXISTS_IN_INSERT, NOT_IN_EMPTY] THEN 11197 REWRITE_TAC[IN_UNION]); 11198 11199val CONTINUOUS_ON_UNION_OPEN = store_thm ("CONTINUOUS_ON_UNION_OPEN", 11200 ``!f s t. open s /\ open t /\ f continuous_on s /\ f continuous_on t 11201 ==> f continuous_on (s UNION t)``, 11202 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN 11203 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN 11204 ASM_SIMP_TAC std_ss [OPEN_UNION] THEN SET_TAC[]); 11205 11206val CONTINUOUS_ON_CASES_LOCAL_OPEN = store_thm ("CONTINUOUS_ON_CASES_LOCAL_OPEN", 11207 ``!P f g:real->real s t. 11208 open_in (subtopology euclidean (s UNION t)) s /\ 11209 open_in (subtopology euclidean (s UNION t)) t /\ 11210 f continuous_on s /\ g continuous_on t /\ 11211 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x)) 11212 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)``, 11213 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN 11214 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL 11215 [EXISTS_TAC ``f:real->real``, EXISTS_TAC ``g:real->real``] THEN 11216 ASM_SIMP_TAC std_ss [] THEN METIS_TAC[]); 11217 11218val CONTINUOUS_ON_CASES_OPEN = store_thm ("CONTINUOUS_ON_CASES_OPEN", 11219 ``!P f g s t. 11220 open s /\ 11221 open t /\ 11222 f continuous_on s /\ 11223 g continuous_on t /\ 11224 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x)) 11225 ==> (\x. if P x then f x else g x) continuous_on s UNION t``, 11226 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL_OPEN THEN 11227 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN 11228 ASM_SIMP_TAC std_ss [OPEN_UNION] THEN SET_TAC[]); 11229 11230(* ------------------------------------------------------------------------- *) 11231(* Likewise on closed sets, with a finiteness assumption. *) 11232(* ------------------------------------------------------------------------- *) 11233 11234val PASTING_LEMMA_CLOSED = store_thm ("PASTING_LEMMA_CLOSED", 11235 ``!f:'a->real->real g t s k. 11236 FINITE k /\ 11237 (!i. i IN k 11238 ==> closed_in (subtopology euclidean s) (t i) /\ 11239 (f i) continuous_on (t i)) /\ 11240 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j 11241 ==> (f i x = f j x)) /\ 11242 (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ (g x = f j x)) 11243 ==> g continuous_on s``, 11244 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN 11245 STRIP_TAC THEN X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 11246 SUBGOAL_THEN 11247 ``{x | x IN s /\ g x IN u} = 11248 BIGUNION {{x | x IN (t i) /\ ((f:'a->real->real) i x) IN u} | 11249 i IN k}`` 11250 SUBST1_TAC THENL 11251 [SUBGOAL_THEN ``!i. i IN k ==> ((t:'a->real->bool) i) SUBSET s`` 11252 ASSUME_TAC THENL 11253 [ASM_MESON_TAC[CLOSED_IN_SUBSET, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY], 11254 SIMP_TAC std_ss [BIGUNION_GSPEC] THEN ASM_SET_TAC[]], 11255 MATCH_MP_TAC CLOSED_IN_BIGUNION THEN 11256 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, IMAGE_FINITE, FORALL_IN_IMAGE] THEN 11257 METIS_TAC[CLOSED_IN_TRANS]]); 11258 11259val PASTING_LEMMA_EXISTS_CLOSED = store_thm ("PASTING_LEMMA_EXISTS_CLOSED", 11260 ``!f:'a->real->real t s k. 11261 FINITE k /\ 11262 s SUBSET BIGUNION {t i | i IN k} /\ 11263 (!i. i IN k 11264 ==> closed_in (subtopology euclidean s) (t i) /\ 11265 (f i) continuous_on (t i)) /\ 11266 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j 11267 ==> (f i x = f j x)) 11268 ==> ?g. g continuous_on s /\ 11269 (!x i. i IN k /\ x IN s INTER t i ==> (g x = f i x))``, 11270 REPEAT STRIP_TAC THEN 11271 EXISTS_TAC ``\x. (f:'a->real->real)(@i. i IN k /\ x IN t i) x`` THEN 11272 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 11273 MATCH_MP_TAC PASTING_LEMMA_CLOSED THEN 11274 MAP_EVERY EXISTS_TAC 11275 [``f:'a->real->real``, ``t:'a->real->bool``, ``k:'a->bool``] THEN 11276 ASM_SET_TAC[]); 11277 11278(* ------------------------------------------------------------------------- *) 11279(* Closure of halflines, halfspaces and hyperplanes. *) 11280(* ------------------------------------------------------------------------- *) 11281 11282val LIM_LIFT_DOT = store_thm ("LIM_LIFT_DOT", 11283 ``!f:real->real a. 11284 (f --> l) net ==> ((\y. a * f(y)) --> (a * l)) net``, 11285 METIS_TAC [LIM_CMUL]); 11286 11287val CONTINUOUS_AT_LIFT_DOT = store_thm ("CONTINUOUS_AT_LIFT_DOT", 11288 ``!a:real x. (\y. a * y) continuous at x``, 11289 REPEAT GEN_TAC THEN SIMP_TAC std_ss [CONTINUOUS_AT, o_THM] THEN 11290 KNOW_TAC ``((\y. a * (\y. y) y:real) --> (a * x)) (at x)`` THENL 11291 [ALL_TAC, SIMP_TAC std_ss []] THEN 11292 MATCH_MP_TAC LIM_LIFT_DOT THEN REWRITE_TAC[LIM_AT] THEN METIS_TAC[]); 11293 11294val CONTINUOUS_ON_LIFT_DOT = store_thm ("CONTINUOUS_ON_LIFT_DOT", 11295 ``!s. (\y. a * y) continuous_on s``, 11296 SIMP_TAC std_ss [CONTINUOUS_AT_IMP_CONTINUOUS_ON, CONTINUOUS_AT_LIFT_DOT]); 11297 11298val CLOSED_INTERVAL_LEFT = store_thm ("CLOSED_INTERVAL_LEFT", 11299 ``!b:real. 11300 closed {x:real | x <= b}``, 11301 SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_APPROACHABLE, GSPECIFICATION] THEN 11302 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN 11303 FIRST_X_ASSUM(MP_TAC o SPEC ``(x:real) - (b:real)``) THEN 11304 ASM_REWRITE_TAC[REAL_SUB_LT] THEN 11305 DISCH_THEN(X_CHOOSE_THEN ``z:real`` MP_TAC) THEN 11306 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 11307 REWRITE_TAC[dist] THEN ASM_REAL_ARITH_TAC); 11308 11309val CLOSED_INTERVAL_RIGHT = store_thm ("CLOSED_INTERVAL_RIGHT", 11310 ``!a:real. 11311 closed {x:real | a <= x}``, 11312 SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_APPROACHABLE, GSPECIFICATION] THEN 11313 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN 11314 FIRST_X_ASSUM(MP_TAC o SPEC ``(a:real) - (x:real)``) THEN 11315 ASM_REWRITE_TAC[REAL_SUB_LT] THEN 11316 DISCH_THEN(X_CHOOSE_THEN ``z:real`` MP_TAC) THEN 11317 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 11318 REWRITE_TAC[dist] THEN ASM_REAL_ARITH_TAC); 11319 11320val CLOSED_HALFSPACE_LE = store_thm ("CLOSED_HALFSPACE_LE", 11321 ``!a:real b. closed {x | a * x <= b}``, 11322 REPEAT GEN_TAC THEN 11323 MP_TAC(ISPEC ``univ(:real)`` CONTINUOUS_ON_LIFT_DOT) THEN 11324 SIMP_TAC std_ss [CONTINUOUS_ON_CLOSED, GSYM CLOSED_IN, SUBTOPOLOGY_UNIV] THEN 11325 DISCH_THEN(MP_TAC o SPEC 11326 ``IMAGE (\x. x) {r | ?x:real. (a * x = r) /\ r <= b}``) THEN 11327 KNOW_TAC ``closed_in (subtopology euclidean (IMAGE (\y. a * y) univ(:real))) 11328 (IMAGE (\x. x) {r | ?x. (a * x = r) /\ r <= b})`` THENL 11329 [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11330 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 11331 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE, IN_UNIV] THEN 11332 METIS_TAC []] THEN 11333 REWRITE_TAC[CLOSED_IN_CLOSED] THEN 11334 EXISTS_TAC ``{x | (x:real) <= (b)}`` THEN 11335 SIMP_TAC std_ss [CLOSED_INTERVAL_LEFT] THEN 11336 SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_UNIV, GSPECIFICATION, IN_INTER] THEN 11337 METIS_TAC []); 11338 11339val CLOSED_HALFSPACE_GE = store_thm ("CLOSED_HALFSPACE_GE", 11340 ``!a:real b. closed {x | a * x >= b}``, 11341 REWRITE_TAC[REAL_ARITH ``a >= b <=> -a <= -b:real``] THEN 11342 REWRITE_TAC[GSYM REAL_MUL_LNEG, CLOSED_HALFSPACE_LE]); 11343 11344val CLOSED_HYPERPLANE = store_thm ("CLOSED_HYPERPLANE", 11345 ``!a b. closed {x | a * x = b}``, 11346 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN 11347 REWRITE_TAC[REAL_ARITH ``b <= a * x <=> a * x >= b:real``] THEN 11348 REWRITE_TAC[SET_RULE `` {x | a * x <= b /\ a * x >= b} = 11349 {x | a * x <= b} INTER {x | a * x >= b}``] THEN 11350 SIMP_TAC std_ss [CLOSED_INTER, CLOSED_HALFSPACE_LE, CLOSED_HALFSPACE_GE]); 11351 11352val CLOSURE_HYPERPLANE = store_thm ("CLOSURE_HYPERPLANE", 11353 ``!a b. closure {x | a * x = b} = {x | a * x = b}``, 11354 SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_HYPERPLANE]); 11355 11356val CLOSED_STANDARD_HYPERPLANE = store_thm ("CLOSED_STANDARD_HYPERPLANE", 11357 ``!a. closed {x:real | x = a}``, 11358 REPEAT GEN_TAC THEN 11359 MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSED_HYPERPLANE) THEN 11360 REAL_ARITH_TAC); 11361 11362val CLOSED_HALFSPACE_COMPONENT_LE = store_thm ("CLOSED_HALFSPACE_COMPONENT_LE", 11363 ``!a. closed {x:real | x <= a}``, 11364 REPEAT GEN_TAC THEN 11365 MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSED_HALFSPACE_LE) THEN 11366 REAL_ARITH_TAC); 11367 11368val CLOSED_HALFSPACE_COMPONENT_GE = store_thm ("CLOSED_HALFSPACE_COMPONENT_GE", 11369 ``!a. closed {x:real | x >= a}``, 11370 REPEAT GEN_TAC THEN 11371 MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSED_HALFSPACE_GE) THEN 11372 REAL_ARITH_TAC); 11373 11374(* ------------------------------------------------------------------------- *) 11375(* Openness of halfspaces. *) 11376(* ------------------------------------------------------------------------- *) 11377 11378val OPEN_HALFSPACE_LT = store_thm ("OPEN_HALFSPACE_LT", 11379 ``!a b. open {x | a * x < b}``, 11380 REWRITE_TAC[GSYM REAL_NOT_LE] THEN 11381 SIMP_TAC std_ss [SET_RULE ``{x | ~p x} = UNIV DIFF {x | p x}``] THEN 11382 REWRITE_TAC[GSYM closed_def, GSYM real_ge, CLOSED_HALFSPACE_GE]); 11383 11384val OPEN_HALFSPACE_COMPONENT_LT = store_thm ("OPEN_HALFSPACE_COMPONENT_LT", 11385 ``!a. open {x:real | x < a}``, 11386 REPEAT GEN_TAC THEN 11387 MP_TAC(ISPECL [``1:real``, ``a:real``] OPEN_HALFSPACE_LT) THEN 11388 ASM_SIMP_TAC std_ss [REAL_MUL_LID]); 11389 11390val OPEN_HALFSPACE_GT = store_thm ("OPEN_HALFSPACE_GT", 11391 ``!a b. open {x | a * x > b}``, 11392 REWRITE_TAC[REAL_ARITH ``x > y <=> ~(x <= y:real)``] THEN 11393 SIMP_TAC std_ss [SET_RULE ``{x | ~p x} = UNIV DIFF {x | p x}``] THEN 11394 REWRITE_TAC[GSYM closed_def, CLOSED_HALFSPACE_LE]); 11395 11396val OPEN_HALFSPACE_COMPONENT_GT = store_thm ("OPEN_HALFSPACE_COMPONENT_GT", 11397 ``!a. open {x:real | x > a}``, 11398 REPEAT GEN_TAC THEN 11399 MP_TAC(ISPECL [``1:real``, ``a:real``] OPEN_HALFSPACE_GT) THEN 11400 ASM_SIMP_TAC std_ss [REAL_MUL_LID]); 11401 11402val OPEN_POSITIVE_MULTIPLES = store_thm ("OPEN_POSITIVE_MULTIPLES", 11403 ``!s:real->bool. open s ==> open {c * x | &0 < c /\ x IN s}``, 11404 SIMP_TAC std_ss [open_def, FORALL_IN_GSPEC] THEN GEN_TAC THEN DISCH_TAC THEN 11405 MAP_EVERY X_GEN_TAC [``c:real``, ``x:real``] THEN STRIP_TAC THEN 11406 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_SIMP_TAC std_ss [] THEN 11407 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 11408 EXISTS_TAC ``c * e:real`` THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL] THEN 11409 X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 11410 FIRST_X_ASSUM(MP_TAC o SPEC ``inv(c) * y:real``) THEN 11411 KNOW_TAC ``(dist (inv (c :real) * (y :real),(x :real)) :real) < (e :real)`` THENL 11412 [SUBGOAL_THEN ``x:real = inv c * c * x`` SUBST1_TAC THENL 11413 [ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID, 11414 REAL_LT_IMP_NE], 11415 ONCE_REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN 11416 ASM_SIMP_TAC std_ss [DIST_MUL, abs, REAL_LT_INV_EQ, REAL_LT_IMP_LE] THEN 11417 ONCE_REWRITE_TAC[METIS [REAL_MUL_SYM, GSYM real_div] ``inv c * x:real = x / c:real``] THEN 11418 METIS_TAC[REAL_LT_LDIV_EQ, REAL_MUL_SYM]], 11419 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11420 DISCH_TAC THEN SRW_TAC [][] THEN 11421 EXISTS_TAC ``c:real`` THEN EXISTS_TAC ``inv(c) * y:real`` THEN 11422 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_LT_IMP_NE] THEN 11423 REAL_ARITH_TAC]); 11424 11425val OPEN_INTERVAL_LEFT = store_thm ("OPEN_INTERVAL_LEFT", 11426 ``!b:real. open {x:real | x < b}``, 11427 REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT]); 11428 11429val OPEN_INTERVAL_RIGHT = store_thm ("OPEN_INTERVAL_RIGHT", 11430 ``!a:real. open {x:real | a < x}``, 11431 REWRITE_TAC[GSYM real_gt, OPEN_HALFSPACE_COMPONENT_GT]); 11432 11433val OPEN_POSITIVE_ORTHANT = store_thm ("OPEN_POSITIVE_ORTHANT", 11434 ``open {x:real | &0 < x}``, 11435 MP_TAC(ISPEC ``0:real`` OPEN_INTERVAL_RIGHT) THEN 11436 REWRITE_TAC[]); 11437 11438(* ------------------------------------------------------------------------- *) 11439(* Closures and interiors of halfspaces. *) 11440(* ------------------------------------------------------------------------- *) 11441 11442val INTERIOR_HALFSPACE_LE = store_thm ("INTERIOR_HALFSPACE_LE", 11443 ``!a:real b. 11444 ~(a = 0) ==> (interior {x | a * x <= b} = {x | a * x < b})``, 11445 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN 11446 SIMP_TAC std_ss [OPEN_HALFSPACE_LT, SUBSET_DEF, GSPECIFICATION, REAL_LT_IMP_LE] THEN 11447 X_GEN_TAC ``s:real->bool`` THEN STRIP_TAC THEN 11448 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN ASM_SIMP_TAC std_ss [REAL_LT_LE] THEN 11449 DISCH_TAC THEN UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN 11450 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN 11451 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 11452 DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 11453 REWRITE_TAC[SUBSET_DEF, IN_CBALL] THEN 11454 DISCH_THEN(MP_TAC o SPEC ``x + e / abs(a) * a:real``) THEN 11455 REWRITE_TAC[METIS [dist, REAL_ADD_SUB2, ABS_NEG] ``dist(x:real,x + y) = abs y``] THEN 11456 ASM_SIMP_TAC std_ss [ABS_MUL, ABS_DIV, ABS_ABS, REAL_DIV_RMUL, 11457 ABS_ZERO, REAL_ARITH ``&0 < x ==> abs x <= x:real``] THEN 11458 DISCH_TAC THEN 11459 FIRST_X_ASSUM(MP_TAC o SPEC ``x + e / abs(a) * a:real``) THEN 11460 ASM_REWRITE_TAC [REAL_LDISTRIB] THEN 11461 REWRITE_TAC [REAL_ARITH ``a * (b * a) = b * (a * a:real)``] THEN 11462 MATCH_MP_TAC(REAL_ARITH ``&0 < e ==> ~(b + e <= b:real)``) THEN 11463 ASM_SIMP_TAC std_ss [REAL_LT_MUL, REAL_LT_DIV, GSYM ABS_NZ, REAL_POASQ]); 11464 11465val INTERIOR_HALFSPACE_GE = store_thm ("INTERIOR_HALFSPACE_GE", 11466 ``!a:real b. 11467 ~(a = 0) ==> (interior {x | a * x >= b} = {x | a * x > b})``, 11468 REPEAT STRIP_TAC THEN 11469 ONCE_REWRITE_TAC[REAL_ARITH ``a >= b <=> -a <= -b:real``, 11470 REAL_ARITH ``a > b <=> -a < -b:real``] THEN 11471 ASM_SIMP_TAC std_ss [REAL_NEG_LMUL, INTERIOR_HALFSPACE_LE, REAL_NEG_EQ0]); 11472 11473val INTERIOR_HALFSPACE_COMPONENT_LE = store_thm ("INTERIOR_HALFSPACE_COMPONENT_LE", 11474 ``!a. interior {x:real | x <= a} = {x | x < a}``, 11475 REPEAT GEN_TAC THEN 11476 MP_TAC(ISPECL [``1:real``, ``a:real``] INTERIOR_HALFSPACE_LE) THEN 11477 ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]); 11478 11479val INTERIOR_HALFSPACE_COMPONENT_GE = store_thm ("INTERIOR_HALFSPACE_COMPONENT_GE", 11480 ``!a. interior {x:real | x >= a} = {x | x > a}``, 11481 REPEAT GEN_TAC THEN 11482 MP_TAC(ISPECL [``1:real``, ``a:real``] INTERIOR_HALFSPACE_GE) THEN 11483 ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]); 11484 11485val CLOSURE_HALFSPACE_LT = store_thm ("CLOSURE_HALFSPACE_LT", 11486 ``!a:real b. 11487 ~(a = 0) ==> (closure {x | a * x < b} = {x | a * x <= b})``, 11488 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN 11489 SIMP_TAC std_ss [SET_RULE ``UNIV DIFF {x | P x} = {x | ~P x}``] THEN 11490 ASM_SIMP_TAC std_ss [REAL_ARITH ``~(x < b) <=> x >= b:real``, INTERIOR_HALFSPACE_GE] THEN 11491 SIMP_TAC std_ss [EXTENSION, IN_DIFF, IN_UNIV, GSPECIFICATION] THEN REAL_ARITH_TAC); 11492 11493val CLOSURE_HALFSPACE_GT = store_thm ("CLOSURE_HALFSPACE_GT", 11494 ``!a:real b. 11495 ~(a = 0) ==> (closure {x | a * x > b} = {x | a * x >= b})``, 11496 REPEAT STRIP_TAC THEN 11497 ONCE_REWRITE_TAC[REAL_ARITH ``a >= b <=> -a <= -b:real``, 11498 REAL_ARITH ``a > b <=> -a < -b:real``] THEN 11499 ASM_SIMP_TAC std_ss [REAL_NEG_LMUL, CLOSURE_HALFSPACE_LT, REAL_NEG_EQ0]); 11500 11501val CLOSURE_HALFSPACE_COMPONENT_LT = store_thm ("CLOSURE_HALFSPACE_COMPONENT_LT", 11502 ``!a. closure {x:real | x < a} = {x | x <= a}``, 11503 REPEAT GEN_TAC THEN 11504 MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSURE_HALFSPACE_LT) THEN 11505 ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]); 11506 11507val CLOSURE_HALFSPACE_COMPONENT_GT = store_thm ("CLOSURE_HALFSPACE_COMPONENT_GT", 11508 ``!a. closure {x:real | x > a} = {x | x >= a}``, 11509 REPEAT GEN_TAC THEN 11510 MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSURE_HALFSPACE_GT) THEN 11511 ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]); 11512 11513val INTERIOR_HYPERPLANE = store_thm ("INTERIOR_HYPERPLANE", 11514 ``!a b. ~(a = 0) ==> (interior {x | a * x = b} = {})``, 11515 REWRITE_TAC[REAL_ARITH ``(x = y) <=> x <= y /\ x >= y:real``] THEN 11516 SIMP_TAC std_ss [SET_RULE ``{x | p x /\ q x} = {x | p x} INTER {x | q x}``] THEN 11517 REWRITE_TAC[INTERIOR_INTER] THEN 11518 REWRITE_TAC [GSYM DE_MORGAN_THM, REAL_ARITH ``x <= y /\ x >= y:real <=> (x = y)``] THEN 11519 ASM_SIMP_TAC std_ss [INTERIOR_HALFSPACE_LE, INTERIOR_HALFSPACE_GE] THEN 11520 SIMP_TAC std_ss [EXTENSION, IN_INTER, GSPECIFICATION, NOT_IN_EMPTY] THEN 11521 REAL_ARITH_TAC); 11522 11523val FRONTIER_HALFSPACE_LE = store_thm ("FRONTIER_HALFSPACE_LE", 11524 ``!a:real b. ~((a = 0) /\ (b = &0)) 11525 ==> (frontier {x | a * x <= b} = {x | a * x = b})``, 11526 REPEAT GEN_TAC THEN ASM_CASES_TAC ``a:real = 0`` THEN 11527 ASM_SIMP_TAC std_ss [REAL_MUL_LZERO] THENL 11528 [ASM_CASES_TAC ``&0 <= b:real`` THEN 11529 ASM_SIMP_TAC std_ss [GSPEC_T, FRONTIER_UNIV, GSPEC_F, FRONTIER_EMPTY], 11530 ASM_SIMP_TAC std_ss [frontier, INTERIOR_HALFSPACE_LE, CLOSURE_CLOSED, 11531 CLOSED_HALFSPACE_LE] THEN 11532 SIMP_TAC std_ss [EXTENSION, IN_DIFF, GSPECIFICATION] THEN REAL_ARITH_TAC]); 11533 11534val FRONTIER_HALFSPACE_GE = store_thm ("FRONTIER_HALFSPACE_GE", 11535 ``!a:real b. ~((a = 0) /\ (b = &0)) 11536 ==> (frontier {x | a * x >= b} = {x | a * x = b})``, 11537 REPEAT STRIP_TAC THEN 11538 MP_TAC(ISPECL [``-a:real``, ``-b:real``] FRONTIER_HALFSPACE_LE) THEN 11539 ASM_REWRITE_TAC [REAL_NEG_EQ0, REAL_NEG_LMUL] THEN 11540 REWRITE_TAC [GSYM REAL_NEG_LMUL] THEN REWRITE_TAC [REAL_EQ_NEG] THEN 11541 SIMP_TAC std_ss [REAL_LE_NEG2, real_ge]); 11542 11543val FRONTIER_HALFSPACE_LT = store_thm ("FRONTIER_HALFSPACE_LT", 11544 ``!a:real b. ~((a = 0) /\ (b = &0)) 11545 ==> (frontier {x | a * x < b} = {x | a * x = b})``, 11546 REPEAT GEN_TAC THEN ASM_CASES_TAC ``a:real = 0`` THEN 11547 ASM_SIMP_TAC std_ss [REAL_NEG_LMUL] THENL 11548 [ASM_CASES_TAC ``&0 < b:real`` THEN REWRITE_TAC [REAL_MUL_LZERO] THEN 11549 ASM_SIMP_TAC std_ss [GSPEC_T, FRONTIER_UNIV, GSPEC_F, FRONTIER_EMPTY], 11550 ASM_SIMP_TAC std_ss [frontier, CLOSURE_HALFSPACE_LT, INTERIOR_OPEN, 11551 OPEN_HALFSPACE_LT] THEN 11552 SIMP_TAC std_ss [EXTENSION, IN_DIFF, GSPECIFICATION] THEN REAL_ARITH_TAC]); 11553 11554val FRONTIER_HALFSPACE_GT = store_thm ("FRONTIER_HALFSPACE_GT", 11555 ``!a:real b. ~((a = 0) /\ (b = &0)) 11556 ==> (frontier {x | a * x > b} = {x | a * x = b})``, 11557 REPEAT STRIP_TAC THEN 11558 MP_TAC(ISPECL [``-a:real``, ``-b:real``] FRONTIER_HALFSPACE_LT) THEN 11559 ASM_REWRITE_TAC[REAL_NEG_EQ0, REAL_MUL_LNEG] THEN 11560 SIMP_TAC std_ss [REAL_LT_NEG, REAL_EQ_NEG, real_gt]); 11561 11562val INTERIOR_STANDARD_HYPERPLANE = store_thm ("INTERIOR_STANDARD_HYPERPLANE", 11563 ``!a. interior {x:real | x = a} = {}``, 11564 REPEAT GEN_TAC THEN 11565 MP_TAC(ISPECL [``1:real``, ``a:real``] INTERIOR_HYPERPLANE) THEN 11566 ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]); 11567 11568(* ------------------------------------------------------------------------- *) 11569(* Unboundedness of halfspaces. *) 11570(* ------------------------------------------------------------------------- *) 11571 11572val UNBOUNDED_HALFSPACE_COMPONENT_LE = store_thm 11573 ("UNBOUNDED_HALFSPACE_COMPONENT_LE", 11574 ``!a. ~bounded {x:real | x <= a}``, 11575 REPEAT GEN_TAC 11576 >> ASM_SIMP_TAC std_ss [bounded_def, FORALL_IN_GSPEC] 11577 >> X_GEN_TAC ``B:real`` 11578 >> EXISTS_TAC ``-((&1:real) + max (abs B) (abs a))`` 11579 >> REWRITE_TAC [ABS_NEG, REAL_NOT_LE, REAL_NEG_ADD] 11580 >> RW_TAC bool_ss [abs, max_def] 11581 >> FULL_SIMP_TAC real_ss [REAL_NOT_LE] 11582 >| (* 12 goals *) 11583 [ ASM_REAL_ARITH_TAC, (* 1 *) 11584 ASM_REAL_ARITH_TAC, (* 2 *) 11585 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 3 *) 11586 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 4 *) 11587 Cases_on `0 <= B` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 5 *) 11588 Cases_on `0 <= B` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 6 *) 11589 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 7 *) 11590 ASM_REAL_ARITH_TAC, (* 8 *) 11591 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 9 *) 11592 Cases_on `0 <= B` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 10 *) 11593 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 11 *) 11594 Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC ]); 11595 11596val UNBOUNDED_HALFSPACE_COMPONENT_GE = store_thm 11597 ("UNBOUNDED_HALFSPACE_COMPONENT_GE", 11598 ``!a. ~bounded {x:real | x >= a}``, 11599 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_NEGATIONS) THEN 11600 MP_TAC(SPECL [``-a:real``] UNBOUNDED_HALFSPACE_COMPONENT_LE) THEN 11601 REWRITE_TAC[GSYM MONO_NOT_EQ] THEN MATCH_MP_TAC EQ_IMPLIES THEN 11602 AP_TERM_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN CONJ_TAC THENL 11603 [MESON_TAC[REAL_NEG_NEG], 11604 SIMP_TAC std_ss [GSPECIFICATION] THEN REAL_ARITH_TAC]); 11605 11606val UNBOUNDED_HALFSPACE_COMPONENT_LT = store_thm ("UNBOUNDED_HALFSPACE_COMPONENT_LT", 11607 ``!a. ~bounded {x:real | x < a}``, 11608 ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN 11609 REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_LT, 11610 UNBOUNDED_HALFSPACE_COMPONENT_LE]); 11611 11612val UNBOUNDED_HALFSPACE_COMPONENT_GT = store_thm ("UNBOUNDED_HALFSPACE_COMPONENT_GT", 11613 ``!a. ~bounded {x:real | x > a}``, 11614 ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN 11615 REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_GT, 11616 UNBOUNDED_HALFSPACE_COMPONENT_GE]); 11617 11618(* ------------------------------------------------------------------------- *) 11619(* Equality of continuous functions on closure and related results. *) 11620(* ------------------------------------------------------------------------- *) 11621 11622val FORALL_IN_CLOSURE = store_thm ("FORALL_IN_CLOSURE", 11623 ``!f:real->real s t. 11624 closed t /\ f continuous_on (closure s) /\ 11625 (!x. x IN s ==> f x IN t) 11626 ==> (!x. x IN closure s ==> f x IN t)``, 11627 REWRITE_TAC[SET_RULE ``(!x. x IN s ==> f x IN t) <=> 11628 s SUBSET {x | x IN s /\ f x IN t}``] THEN 11629 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN 11630 ASM_REWRITE_TAC[CLOSED_CLOSURE] THEN CONJ_TAC THENL 11631 [MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[], 11632 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN 11633 ASM_REWRITE_TAC[CLOSED_CLOSURE]]); 11634 11635val FORALL_IN_CLOSURE_EQ = store_thm ("FORALL_IN_CLOSURE_EQ", 11636 ``!f s t. 11637 closed t /\ f continuous_on closure s 11638 ==> ((!x. x IN closure s ==> f x IN t) <=> 11639 (!x. x IN s ==> f x IN t))``, 11640 METIS_TAC[FORALL_IN_CLOSURE, CLOSURE_SUBSET, SUBSET_DEF]); 11641 11642val CONTINUOUS_LE_ON_CLOSURE = store_thm ("CONTINUOUS_LE_ON_CLOSURE", 11643 ``!f:real->real s a. 11644 f continuous_on closure(s) /\ (!x. x IN s ==> f(x) <= a) 11645 ==> !x. x IN closure(s) ==> f(x) <= a``, 11646 REPEAT GEN_TAC THEN STRIP_TAC THEN 11647 KNOW_TAC `` !(x :real). x IN closure (s :real -> bool) 11648 ==> (f :real -> real) x IN {y | y <= (a :real)}`` THENL 11649 [ALL_TAC, SET_TAC []] THEN 11650 MATCH_MP_TAC FORALL_IN_CLOSURE THEN 11651 ASM_SIMP_TAC std_ss [ETA_AX, CLOSED_HALFSPACE_COMPONENT_LE] THEN ASM_SET_TAC []); 11652 11653val CONTINUOUS_GE_ON_CLOSURE = store_thm ("CONTINUOUS_GE_ON_CLOSURE", 11654 ``!f:real->real s a. 11655 f continuous_on closure(s) /\ (!x. x IN s ==> a <= f(x)) 11656 ==> !x. x IN closure(s) ==> a <= f(x)``, 11657 REPEAT GEN_TAC THEN STRIP_TAC THEN 11658 KNOW_TAC `` !(x :real). x IN closure (s :real -> bool) 11659 ==> (f :real -> real) x IN {y | y >= (a :real)}`` THENL 11660 [ALL_TAC, SET_TAC [real_ge]] THEN 11661 MATCH_MP_TAC FORALL_IN_CLOSURE THEN 11662 ASM_SIMP_TAC std_ss [ETA_AX, CLOSED_HALFSPACE_COMPONENT_GE] THEN ASM_SET_TAC [real_ge]); 11663 11664val CONTINUOUS_CONSTANT_ON_CLOSURE = store_thm ("CONTINUOUS_CONSTANT_ON_CLOSURE", 11665 ``!f:real->real s a. 11666 f continuous_on closure(s) /\ (!x. x IN s ==> (f(x) = a)) 11667 ==> !x. x IN closure(s) ==> (f(x) = a)``, 11668 REWRITE_TAC[SET_RULE 11669 ``x IN s ==> (f x = a) <=> x IN s ==> f x IN {a}``] THEN 11670 REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC FORALL_IN_CLOSURE THEN 11671 ASM_REWRITE_TAC[CLOSED_SING]); 11672 11673val CONTINUOUS_AGREE_ON_CLOSURE = store_thm ("CONTINUOUS_AGREE_ON_CLOSURE", 11674 ``!g h:real->real. 11675 g continuous_on closure s /\ h continuous_on closure s /\ 11676 (!x. x IN s ==> (g x = h x)) 11677 ==> !x. x IN closure s ==> (g x = h x)``, 11678 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN STRIP_TAC THEN 11679 ONCE_REWRITE_TAC [METIS [] ``(g x - h x = 0) = ((\x. g x - h x) x = 0:real)``] THEN 11680 MATCH_MP_TAC CONTINUOUS_CONSTANT_ON_CLOSURE THEN 11681 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_SUB]); 11682 11683val CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT", 11684 ``!f:real->real s a. 11685 f continuous_on s 11686 ==> closed_in (subtopology euclidean s) {x | x IN s /\ (f x = a)}``, 11687 REPEAT STRIP_TAC THEN 11688 ONCE_REWRITE_TAC[SET_RULE 11689 ``{x | x IN s /\ (f(x) = a)} = {x | x IN s /\ f(x) IN {a}}``] THEN 11690 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN 11691 ASM_REWRITE_TAC[CLOSED_SING]); 11692 11693val CONTINUOUS_CLOSED_PREIMAGE_CONSTANT = store_thm ("CONTINUOUS_CLOSED_PREIMAGE_CONSTANT", 11694 ``!f:real->real s. 11695 f continuous_on s /\ closed s ==> closed {x | x IN s /\ (f(x) = a)}``, 11696 REPEAT STRIP_TAC THEN 11697 ASM_CASES_TAC ``{x | x IN s /\ ((f:real->real)(x) = a)} = {}`` THEN 11698 ASM_REWRITE_TAC[CLOSED_EMPTY] THEN ONCE_REWRITE_TAC[SET_RULE 11699 ``{x | x IN s /\ (f(x) = a)} = {x | x IN s /\ f(x) IN {a}}``] THEN 11700 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN 11701 ASM_REWRITE_TAC[CLOSED_SING] THEN ASM_SET_TAC[]); 11702 11703(* ------------------------------------------------------------------------- *) 11704(* Theorems relating continuity and uniform continuity to closures. *) 11705(* ------------------------------------------------------------------------- *) 11706 11707val CONTINUOUS_ON_CLOSURE = store_thm ("CONTINUOUS_ON_CLOSURE", 11708 ``!f:real->real s. 11709 f continuous_on closure s <=> 11710 !x e. x IN closure s /\ &0 < e 11711 ==> ?d. &0 < d /\ 11712 !y. y IN s /\ dist(y,x) < d ==> dist(f y,f x) < e``, 11713 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on] THEN 11714 EQ_TAC THENL [METIS_TAC[REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET], ALL_TAC] THEN 11715 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 11716 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 11717 FIRST_ASSUM(MP_TAC o SPECL [``x:real``, ``e / &2:real``]) THEN 11718 KNOW_TAC ``x IN closure s:real->bool /\ 0 < e / 2:real`` THENL 11719 [ASM_REWRITE_TAC[REAL_HALF], DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [])] THEN 11720 DISCH_TAC THEN FIRST_ASSUM (fn th => REWRITE_TAC [th]) THEN 11721 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 11722 EXISTS_TAC ``d / &2:real`` THEN ASM_REWRITE_TAC[REAL_HALF] THEN 11723 X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 11724 FIRST_X_ASSUM(MP_TAC o SPECL [``y:real``, ``e / &2:real``]) THEN 11725 ASM_REWRITE_TAC[REAL_HALF] THEN 11726 DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN 11727 MP_TAC(ISPECL [``y:real``, ``s:real->bool``] CLOSURE_APPROACHABLE) THEN 11728 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min k (d / &2:real)``) THEN 11729 ASM_REWRITE_TAC[REAL_HALF, REAL_LT_MIN] THEN 11730 KNOW_TAC ``!a b c e. abs(a - b) < e / &2 /\ abs(b - c) < e / &2:real ==> 11731 abs(a - c) < e / 2 + e / 2:real`` THENL 11732 [REAL_ARITH_TAC, DISCH_TAC] THEN STRIP_TAC THEN 11733 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN REWRITE_TAC [dist] THEN 11734 FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC ``(f:real->real) y'`` THEN CONJ_TAC THENL 11735 [REWRITE_TAC [GSYM dist] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN 11736 FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [], 11737 REWRITE_TAC [GSYM dist] THEN FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [] THEN 11738 MATCH_MP_TAC DIST_TRIANGLE_LT THEN EXISTS_TAC ``y:real`` THEN 11739 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN MATCH_MP_TAC REAL_LT_ADD2 THEN 11740 METIS_TAC [DIST_SYM]]); 11741 11742val CONTINUOUS_ON_CLOSURE_SEQUENTIALLY = store_thm ("CONTINUOUS_ON_CLOSURE_SEQUENTIALLY", 11743 ``!f:real->real s. 11744 f continuous_on closure s <=> 11745 !x a. a IN closure s /\ (!n. x n IN s) /\ (x --> a) sequentially 11746 ==> ((f o x) --> f a) sequentially``, 11747 REWRITE_TAC[CONTINUOUS_ON_CLOSURE] THEN 11748 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 11749 REWRITE_TAC[AND_IMP_INTRO, GSYM continuous_within] THEN 11750 REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]); 11751 11752val UNIFORMLY_CONTINUOUS_ON_CLOSURE = store_thm ("UNIFORMLY_CONTINUOUS_ON_CLOSURE", 11753 ``!f:real->real s. 11754 f uniformly_continuous_on s /\ f continuous_on closure s 11755 ==> f uniformly_continuous_on closure s``, 11756 REPEAT GEN_TAC THEN 11757 REWRITE_TAC[uniformly_continuous_on] THEN STRIP_TAC THEN 11758 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 11759 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &3:real``) THEN 11760 KNOW_TAC ``0 < e / 3:real`` THENL 11761 [FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 11762 ASM_REAL_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 11763 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 11764 EXISTS_TAC ``d / &3:real`` THEN CONJ_TAC THENL 11765 [FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 11766 REWRITE_TAC [REAL_MUL_LZERO] THEN ASM_REWRITE_TAC [], ALL_TAC] THEN 11767 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 11768 UNDISCH_TAC ``f continuous_on closure s`` THEN DISCH_TAC THEN 11769 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [continuous_on]) THEN 11770 DISCH_THEN(fn th => 11771 MP_TAC(SPEC ``y:real`` th) THEN MP_TAC(SPEC ``x:real`` th)) THEN 11772 ASM_REWRITE_TAC[] THEN 11773 DISCH_THEN(MP_TAC o SPEC ``e / &3:real``) THEN ASM_REWRITE_TAC [] THEN 11774 DISCH_THEN(X_CHOOSE_THEN ``d1:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 11775 MP_TAC(ISPECL [``x:real``, ``s:real->bool``] CLOSURE_APPROACHABLE) THEN 11776 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min d1 (d / &3:real)``) THEN 11777 KNOW_TAC ``0 < min d1 (d / 3:real)`` THENL 11778 [REWRITE_TAC [min_def] THEN COND_CASES_TAC THEN 11779 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 11780 REWRITE_TAC [REAL_MUL_LZERO] THEN ASM_REWRITE_TAC [], 11781 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 11782 REWRITE_TAC[REAL_LT_MIN] THEN 11783 DISCH_THEN(X_CHOOSE_THEN ``x':real`` STRIP_ASSUME_TAC) THEN 11784 DISCH_THEN(MP_TAC o SPEC ``x':real``) THEN 11785 ASM_SIMP_TAC std_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET] THEN DISCH_TAC THEN 11786 DISCH_THEN(MP_TAC o SPEC ``e / &3:real``) THEN ASM_REWRITE_TAC [] THEN 11787 DISCH_THEN(X_CHOOSE_THEN ``d2:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 11788 MP_TAC(ISPECL [``y:real``, ``s:real->bool``] CLOSURE_APPROACHABLE) THEN 11789 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min d2 (d / &3:real)``) THEN 11790 KNOW_TAC ``0 < min d2 (d / 3:real)`` THENL 11791 [REWRITE_TAC [min_def] THEN COND_CASES_TAC THEN 11792 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 11793 REWRITE_TAC [REAL_MUL_LZERO] THEN ASM_REWRITE_TAC [], 11794 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 11795 REWRITE_TAC[REAL_LT_MIN] THEN 11796 DISCH_THEN(X_CHOOSE_THEN ``y':real`` STRIP_ASSUME_TAC) THEN 11797 DISCH_THEN(MP_TAC o SPEC ``y':real``) THEN 11798 ASM_SIMP_TAC std_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET] THEN DISCH_TAC THEN 11799 FIRST_X_ASSUM(MP_TAC o SPECL [``x':real``, ``y':real``]) THEN 11800 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 11801 METIS_TAC[dist, ABS_SUB, REAL_ARITH 11802 ``abs(y - x) * 3 < d /\ abs(x' - x) * 3 < d /\ abs(y' - y) * 3 < d 11803 ==> abs(y' - x') < d:real``]); 11804 11805(* ------------------------------------------------------------------------- *) 11806(* Cauchy continuity, and the extension of functions to closures. *) 11807(* ------------------------------------------------------------------------- *) 11808 11809val UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS = store_thm 11810 ("UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS", 11811 ``!f:real->real s. 11812 f uniformly_continuous_on s 11813 ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))``, 11814 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on, cauchy, o_DEF] THEN 11815 MESON_TAC[]); 11816 11817val CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS = store_thm 11818 ("CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS", 11819 ``!f:real->real s. 11820 f continuous_on s /\ closed s 11821 ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))``, 11822 REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED, CONTINUOUS_ON_SEQUENTIALLY] THEN 11823 REWRITE_TAC[complete] THEN MESON_TAC[CONVERGENT_IMP_CAUCHY]); 11824 11825val CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA = store_thm 11826 ("CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA", 11827 ``!f:real->real s. 11828 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x)) 11829 ==> !a x. (!n. (x n) IN s) /\ (x --> a) sequentially 11830 ==> ?l. ((f o x) --> l) sequentially /\ 11831 !y. (!n. (y n) IN s) /\ (y --> a) sequentially 11832 ==> ((f o y) --> l) sequentially``, 11833 REPEAT STRIP_TAC THEN 11834 FIRST_ASSUM(MP_TAC o SPEC ``x:num->real``) THEN 11835 KNOW_TAC ``cauchy x /\ (!n. x n IN s)`` THENL 11836 [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY], 11837 DISCH_THEN (fn th => REWRITE_TAC [th])] THEN 11838 REWRITE_TAC [GSYM CONVERGENT_EQ_CAUCHY] THEN 11839 DISCH_THEN (X_CHOOSE_TAC ``l:real``) THEN EXISTS_TAC ``l:real`` THEN 11840 ASM_REWRITE_TAC [] THEN 11841 X_GEN_TAC ``y:num->real`` THEN STRIP_TAC THEN 11842 FIRST_ASSUM(MP_TAC o SPEC ``y:num->real``) THEN 11843 KNOW_TAC ``cauchy y /\ (!n. y n IN s)`` THENL 11844 [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY], 11845 DISCH_THEN (fn th => REWRITE_TAC [th])] THEN 11846 REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN 11847 DISCH_THEN(X_CHOOSE_THEN ``l':real`` STRIP_ASSUME_TAC) THEN 11848 SUBGOAL_THEN ``l:real = l'`` (fn th => ASM_REWRITE_TAC[th]) THEN 11849 ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN 11850 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN 11851 EXISTS_TAC ``\n:num. (f:real->real)(x n) - f(y n)`` THEN 11852 RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN 11853 ASM_SIMP_TAC std_ss [LIM_SUB, TRIVIAL_LIMIT_SEQUENTIALLY] THEN 11854 FIRST_X_ASSUM(MP_TAC o SPEC 11855 ``\n. if EVEN n then x(n DIV 2):real else y(n DIV 2)``) THEN 11856 REWRITE_TAC[cauchy, o_THM, LIM_SEQUENTIALLY] THEN 11857 KNOW_TAC ``(!(e :real). 11858 (0 :real) < e ==> 11859 ?(N :num). 11860 !(m :num) (n :num). 11861 m >= N /\ n >= N ==> 11862 (dist 11863 ((\(n :num). 11864 if EVEN n then (x :num -> real) (n DIV (2 :num)) 11865 else (y :num -> real) (n DIV (2 :num))) m, 11866 (\(n :num). 11867 if EVEN n then x (n DIV (2 :num)) 11868 else y (n DIV (2 :num))) n) :real) < e) /\ 11869 (!(n :num). (\(n :num). 11870 if EVEN n then x (n DIV (2 :num)) else y (n DIV (2 :num))) n IN 11871 (s :real -> bool))`` THENL 11872 [ (* goal 1 (of 2) *) 11873 CONJ_TAC THENL [ALL_TAC, METIS_TAC[]] THEN 11874 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN MAP_EVERY UNDISCH_TAC 11875 [``((y:num->real) --> a) sequentially``, 11876 ``((x:num->real) --> a) sequentially``] THEN 11877 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 11878 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_HALF] THEN 11879 DISCH_THEN(X_CHOOSE_TAC ``N1:num``) THEN 11880 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_HALF] THEN 11881 DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN 11882 EXISTS_TAC ``2 * (N1 + N2:num)`` THEN 11883 MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``] THEN STRIP_TAC THEN 11884 UNDISCH_TAC ``!n. (y:num->real) n IN s`` THEN DISCH_TAC THEN 11885 UNDISCH_TAC ``!n. (x:num->real) n IN s`` THEN DISCH_TAC THEN 11886 POP_ASSUM K_TAC THEN POP_ASSUM K_TAC THEN 11887 REPEAT(FIRST_X_ASSUM(fn th => 11888 MP_TAC(SPEC ``m DIV 2`` th) THEN MP_TAC(SPEC ``n DIV 2`` th))) THEN 11889 KNOW_TAC ``N1 <= n DIV 2`` THENL 11890 [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN 11891 ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11892 POP_ASSUM K_TAC THEN DISCH_TAC] THEN 11893 KNOW_TAC ``N1 <= m DIV 2`` THENL 11894 [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN 11895 ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11896 POP_ASSUM K_TAC THEN DISCH_TAC] THEN 11897 KNOW_TAC ``N2 <= n DIV 2`` THENL 11898 [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN 11899 ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11900 POP_ASSUM K_TAC THEN DISCH_TAC] THEN 11901 KNOW_TAC ``N2 <= m DIV 2`` THENL 11902 [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN 11903 ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11904 POP_ASSUM K_TAC THEN DISCH_TAC] THEN 11905 REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN 11906 FULL_SIMP_TAC std_ss [dist, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 11907 Cases_on `EVEN m` >> Cases_on `EVEN n` >> fs [] >| (* 4 subgoals *) 11908 [ MP_TAC (Q.SPECL [`x (m DIV 2) - a`, `x (n DIV 2) - a`] ABS_TRIANGLE_NEG), 11909 MP_TAC (Q.SPECL [`x (m DIV 2) - a`, `y (n DIV 2) - a`] ABS_TRIANGLE_NEG), 11910 MP_TAC (Q.SPECL [`y (m DIV 2) - a`, `x (n DIV 2) - a`] ABS_TRIANGLE_NEG), 11911 MP_TAC (Q.SPECL [`y (m DIV 2) - a`, `y (n DIV 2) - a`] ABS_TRIANGLE_NEG) ] 11912 >> ASM_REAL_ARITH_TAC, 11913 (* goal 2 (of 2) *) 11914 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 11915 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN 11916 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN 11917 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 11918 X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 11919 FIRST_X_ASSUM(MP_TAC o SPECL [``2 * n:num``, ``2 * n + 1:num``]) THEN 11920 KNOW_TAC ``2 * n >= N /\ 2 * n + 1 >= N:num`` THENL 11921 [ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 11922 SIMP_TAC arith_ss [EVEN_ADD, EVEN_MULT] THEN 11923 KNOW_TAC ``((2 * n) DIV 2 = n) /\ ((2 * n + 1) DIV 2 = n)`` THENL 11924 [SIMP_TAC arith_ss [DIV_EQ_X, ARITH_PROVE ``0 < 2:num``], ALL_TAC] THEN 11925 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 11926 REWRITE_TAC[dist, REAL_SUB_RZERO] ]); 11927 11928val CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE = store_thm ("CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE", 11929 ``!f:real->real s. 11930 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x)) 11931 ==> ?g. g continuous_on closure s /\ (!x. x IN s ==> (g x = f x))``, 11932 REPEAT STRIP_TAC THEN 11933 SUBGOAL_THEN 11934 ``!a:real. ?x. 11935 a IN closure s ==> (!n. x n IN s) /\ (x --> a) sequentially`` 11936 MP_TAC THENL [MESON_TAC[CLOSURE_SEQUENTIAL], ALL_TAC] THEN 11937 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 11938 X_GEN_TAC ``X:real->num->real`` THEN DISCH_TAC THEN 11939 FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA) THEN 11940 DISCH_THEN(MP_TAC o GEN ``a:real`` o 11941 SPECL [``a:real``, ``(X:real->num->real) a``]) THEN 11942 KNOW_TAC ``(!(a :real). a IN closure (s :real -> bool) ==> 11943 ?(l :real). 11944 (((f :real -> real) o X a --> l) sequentially :bool) /\ 11945 !(y :num -> real). 11946 (!(n :num). y n IN s) /\ ((y --> a) sequentially :bool) ==> 11947 ((f o y --> l) sequentially :bool)) ==> 11948 ?(g :real -> real). 11949 g continuous_on closure s /\ !(x :real). x IN s ==> (g x = f x)`` THENL 11950 [ALL_TAC, METIS_TAC []] THEN DISCH_TAC THEN 11951 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 11952 SIMP_TAC std_ss [SKOLEM_THM] THEN 11953 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN 11954 POP_ASSUM MP_TAC THEN STRIP_TAC THEN 11955 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL 11956 [X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN 11957 FIRST_X_ASSUM(MP_TAC o SPEC ``a:real``) THEN 11958 ASM_SIMP_TAC std_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET] THEN 11959 DISCH_THEN(MP_TAC o SPEC ``(\n. a):num->real`` o CONJUNCT2) THEN 11960 ASM_SIMP_TAC std_ss [LIM_CONST_EQ, o_DEF, TRIVIAL_LIMIT_SEQUENTIALLY], 11961 STRIP_TAC] THEN 11962 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CLOSURE_SEQUENTIALLY] THEN 11963 MAP_EVERY X_GEN_TAC [``x:num->real``, ``a:real``] THEN STRIP_TAC THEN 11964 MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN 11965 EXISTS_TAC ``(f:real->real) o (x:num->real)`` THEN ASM_SIMP_TAC std_ss [] THEN 11966 MATCH_MP_TAC ALWAYS_EVENTUALLY THEN ASM_SIMP_TAC std_ss [o_THM]); 11967 11968val UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE = store_thm ("UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE", 11969 ``!f:real->real s. 11970 f uniformly_continuous_on s 11971 ==> ?g. g uniformly_continuous_on closure s /\ (!x. x IN s ==> (g x = f x)) /\ 11972 !h. h continuous_on closure s /\ (!x. x IN s ==> (h x = f x)) 11973 ==> !x. x IN closure s ==> (h x = g x)``, 11974 REPEAT STRIP_TAC THEN 11975 FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE o 11976 MATCH_MP UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS) THEN 11977 STRIP_TAC THEN EXISTS_TAC ``g:real->real`` THEN 11978 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THENL 11979 [METIS_TAC[UNIFORMLY_CONTINUOUS_ON_CLOSURE, UNIFORMLY_CONTINUOUS_ON_EQ], 11980 METIS_TAC[CONTINUOUS_AGREE_ON_CLOSURE]]); 11981 11982val CAUCHY_CONTINUOUS_IMP_CONTINUOUS = store_thm ("CAUCHY_CONTINUOUS_IMP_CONTINUOUS", 11983 ``!f:real->real s. 11984 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x)) 11985 ==> f continuous_on s``, 11986 REPEAT STRIP_TAC THEN 11987 FIRST_ASSUM(CHOOSE_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN 11988 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, CLOSURE_SUBSET, CONTINUOUS_ON_EQ]); 11989 11990val BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE = store_thm ("BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE", 11991 ``!f:real->real s. 11992 f uniformly_continuous_on s /\ bounded s ==> bounded(IMAGE f s)``, 11993 REPEAT STRIP_TAC THEN FIRST_ASSUM 11994 (MP_TAC o MATCH_MP UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN 11995 DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN 11996 MATCH_MP_TAC BOUNDED_SUBSET THEN 11997 EXISTS_TAC ``IMAGE (g:real->real) (closure s)`` THEN CONJ_TAC THENL 11998 [ASM_MESON_TAC[COMPACT_CLOSURE, UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS, 11999 COMPACT_IMP_BOUNDED, COMPACT_CONTINUOUS_IMAGE], 12000 MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[]]); 12001 12002(* ------------------------------------------------------------------------- *) 12003(* Occasionally useful invariance properties. *) 12004(* ------------------------------------------------------------------------- *) 12005 12006val CONTINUOUS_AT_COMPOSE_EQ = store_thm ("CONTINUOUS_AT_COMPOSE_EQ", 12007 ``!f:real->real g:real->real h:real->real. 12008 g continuous at x /\ h continuous at (g x) /\ 12009 (!y. g(h y) = y) /\ (h(g x) = x) 12010 ==> ((f continuous at (g x) <=> (\x. f(g x)) continuous at x))``, 12011 REPEAT STRIP_TAC THEN EQ_TAC THEN 12012 ASM_SIMP_TAC std_ss [REWRITE_RULE[o_DEF] CONTINUOUS_AT_COMPOSE] THEN 12013 DISCH_TAC THEN 12014 SUBGOAL_THEN 12015 ``((f:real->real) o (g:real->real) o (h:real->real)) 12016 continuous at (g(x:real))`` 12017 MP_TAC THENL 12018 [REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN 12019 ASM_REWRITE_TAC[o_DEF], 12020 ASM_SIMP_TAC std_ss [o_DEF, ETA_AX]]); 12021 12022val CONTINUOUS_AT_TRANSLATION = store_thm ("CONTINUOUS_AT_TRANSLATION", 12023 ``!a z f:real->real. 12024 f continuous at (a + z) <=> (\x. f(a + x)) continuous at z``, 12025 REPEAT GEN_TAC THEN 12026 ONCE_REWRITE_TAC [METIS [] ``a + z = (\z. a + z) z:real``] THEN 12027 MATCH_MP_TAC CONTINUOUS_AT_COMPOSE_EQ THEN 12028 EXISTS_TAC ``\x:real. x - a`` THEN 12029 SIMP_TAC std_ss [CONTINUOUS_ADD, CONTINUOUS_SUB, 12030 CONTINUOUS_AT_ID, CONTINUOUS_CONST] THEN 12031 REAL_ARITH_TAC); 12032 12033(* ------------------------------------------------------------------------- *) 12034(* Interior of an injective image. *) 12035(* ------------------------------------------------------------------------- *) 12036 12037val INTERIOR_IMAGE_SUBSET = store_thm ("INTERIOR_IMAGE_SUBSET", 12038 ``!f:real->real s. 12039 (!x. f continuous at x) /\ (!x y. (f x = f y) ==> (x = y)) 12040 ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)``, 12041 REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET_DEF] THEN 12042 SIMP_TAC std_ss [interior, GSPECIFICATION] THEN 12043 X_GEN_TAC ``y:real`` THEN 12044 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 12045 SIMP_TAC std_ss [IN_IMAGE, GSPECIFICATION] THEN 12046 SUBGOAL_THEN ``y IN IMAGE (f:real->real) s`` MP_TAC THENL 12047 [ASM_SET_TAC[], ALL_TAC] THEN 12048 REWRITE_TAC[IN_IMAGE] THEN 12049 STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN 12050 ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN 12051 EXISTS_TAC ``{x | (f:real->real)(x) IN t}`` THEN 12052 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN CONJ_TAC THENL 12053 [MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN ASM_MESON_TAC[], 12054 ASM_SET_TAC[]]); 12055 12056(* ------------------------------------------------------------------------- *) 12057(* Making a continuous function avoid some value in a neighbourhood. *) 12058(* ------------------------------------------------------------------------- *) 12059 12060val CONTINUOUS_WITHIN_AVOID = store_thm ("CONTINUOUS_WITHIN_AVOID", 12061 ``!f:real->real x s a. 12062 f continuous (at x within s) /\ x IN s /\ ~(f x = a) 12063 ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)``, 12064 REPEAT STRIP_TAC THEN 12065 UNDISCH_TAC ``f continuous (at x within s)`` THEN DISCH_TAC THEN 12066 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [continuous_within]) THEN 12067 DISCH_THEN(MP_TAC o SPEC ``abs((f:real->real) x - a)``) THEN 12068 ASM_REWRITE_TAC[GSYM ABS_NZ, REAL_SUB_0] THEN 12069 DISCH_THEN (X_CHOOSE_TAC ``d:real``) THEN EXISTS_TAC ``d:real`` THEN 12070 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN 12071 REWRITE_TAC[] THEN DISCH_TAC THEN X_GEN_TAC ``y:real`` THEN 12072 POP_ASSUM (MP_TAC o SPEC ``y:real``) THEN 12073 MATCH_MP_TAC MONO_IMP THEN SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 12074 12075val CONTINUOUS_AT_AVOID = store_thm ("CONTINUOUS_AT_AVOID", 12076 ``!f:real->real x a. 12077 f continuous (at x) /\ ~(f x = a) 12078 ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)``, 12079 MP_TAC CONTINUOUS_WITHIN_AVOID THEN 12080 DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN 12081 POP_ASSUM (MP_TAC o SPECL [``f:real->real``,``x:real``]) THEN 12082 DISCH_THEN(MP_TAC o SPEC ``univ(:real)``) THEN 12083 DISCH_TAC THEN X_GEN_TAC ``a:real`` THEN POP_ASSUM (MP_TAC o SPEC ``a:real``) THEN 12084 REWRITE_TAC[WITHIN_UNIV, IN_UNIV]); 12085 12086val CONTINUOUS_ON_AVOID = store_thm ("CONTINUOUS_ON_AVOID", 12087 ``!f:real->real x s a. 12088 f continuous_on s /\ x IN s /\ ~(f x = a) 12089 ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)``, 12090 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 12091 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_WITHIN_AVOID THEN 12092 ASM_SIMP_TAC std_ss []); 12093 12094val CONTINUOUS_ON_OPEN_AVOID = store_thm ("CONTINUOUS_ON_OPEN_AVOID", 12095 ``!f:real->real x s a. 12096 f continuous_on s /\ open s /\ x IN s /\ ~(f x = a) 12097 ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)``, 12098 REPEAT GEN_TAC THEN ASM_CASES_TAC ``open(s:real->bool)`` THEN 12099 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_AT] THEN 12100 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_AVOID THEN 12101 ASM_SIMP_TAC std_ss []); 12102 12103(* ------------------------------------------------------------------------- *) 12104(* Proving a function is constant by proving open-ness of level set. *) 12105(* ------------------------------------------------------------------------- *) 12106 12107val CONTINUOUS_LEVELSET_OPEN_IN_CASES = store_thm ("CONTINUOUS_LEVELSET_OPEN_IN_CASES", 12108 ``!f:real->real s a. 12109 connected s /\ 12110 f continuous_on s /\ 12111 open_in (subtopology euclidean s) {x | x IN s /\ (f x = a)} 12112 ==> (!x. x IN s ==> ~(f x = a)) \/ (!x. x IN s ==> (f x = a))``, 12113 REWRITE_TAC[SET_RULE ``(!x. x IN s ==> ~(f x = a)) <=> 12114 ({x | x IN s /\ (f x = a)} = {})``, 12115 SET_RULE ``(!x. x IN s ==> (f x = a)) <=> 12116 ({x | x IN s /\ (f x = a)} = s)``] THEN 12117 REWRITE_TAC[CONNECTED_CLOPEN] THEN REPEAT STRIP_TAC THEN 12118 FIRST_X_ASSUM MATCH_MP_TAC THEN 12119 ASM_SIMP_TAC std_ss [CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT]); 12120 12121val CONTINUOUS_LEVELSET_OPEN_IN = store_thm ("CONTINUOUS_LEVELSET_OPEN_IN", 12122 ``!f:real->real s a. 12123 connected s /\ 12124 f continuous_on s /\ 12125 open_in (subtopology euclidean s) {x | x IN s /\ (f x = a)} /\ 12126 (?x. x IN s /\ (f x = a)) 12127 ==> (!x. x IN s ==> (f x = a))``, 12128 METIS_TAC[CONTINUOUS_LEVELSET_OPEN_IN_CASES]); 12129 12130val CONTINUOUS_LEVELSET_OPEN = store_thm ("CONTINUOUS_LEVELSET_OPEN", 12131 ``!f:real->real s a. 12132 connected s /\ 12133 f continuous_on s /\ 12134 open {x | x IN s /\ (f x = a)} /\ 12135 (?x. x IN s /\ (f x = a)) 12136 ==> (!x. x IN s ==> (f x = a))``, 12137 REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 12138 MATCH_MP_TAC CONTINUOUS_LEVELSET_OPEN_IN THEN 12139 ASM_REWRITE_TAC[OPEN_IN_OPEN] THEN 12140 EXISTS_TAC ``{x | x IN s /\ ((f:real->real) x = a)}`` THEN 12141 ASM_REWRITE_TAC[] THEN SET_TAC[]); 12142 12143(* ------------------------------------------------------------------------- *) 12144(* Some arithmetical combinations (more to prove). *) 12145(* ------------------------------------------------------------------------- *) 12146 12147val OPEN_SCALING = store_thm ("OPEN_SCALING", 12148 ``!s:real->bool c. ~(c = &0) /\ open s ==> open(IMAGE (\x. c * x) s)``, 12149 REPEAT GEN_TAC THEN SIMP_TAC std_ss [open_def, FORALL_IN_IMAGE] THEN 12150 STRIP_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 12151 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 12152 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 12153 EXISTS_TAC ``e * abs(c:real)`` THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL, GSYM ABS_NZ] THEN 12154 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN 12155 EXISTS_TAC ``inv(c) * y:real`` THEN 12156 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_MUL_LID] THEN 12157 FIRST_X_ASSUM MATCH_MP_TAC THEN 12158 SUBGOAL_THEN ``x = inv(c) * c * x:real`` SUBST1_TAC THENL 12159 [ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID], 12160 REWRITE_TAC[dist, GSYM REAL_MUL_ASSOC, GSYM REAL_SUB_LDISTRIB, ABS_MUL] THEN 12161 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC std_ss [ABS_INV] THEN 12162 ASM_SIMP_TAC std_ss [GSYM real_div, REAL_LT_LDIV_EQ, GSYM ABS_NZ] THEN 12163 ASM_REWRITE_TAC[GSYM dist]]); 12164 12165val OPEN_NEGATIONS = store_thm ("OPEN_NEGATIONS", 12166 ``!s:real->bool. open s ==> open (IMAGE (\x. -x) s)``, 12167 SUBGOAL_THEN ``(\x. -x) = \x:real. -(&1) * x`` 12168 (fn th => SIMP_TAC std_ss [th, OPEN_SCALING, REAL_ARITH ``~(-(&1) = &0:real)``]) THEN 12169 REWRITE_TAC[FUN_EQ_THM] THEN REAL_ARITH_TAC); 12170 12171val OPEN_TRANSLATION = store_thm ("OPEN_TRANSLATION", 12172 ``!s a:real. open s ==> open(IMAGE (\x. a + x) s)``, 12173 REPEAT STRIP_TAC THEN 12174 MP_TAC(ISPECL [``\x:real. x - a``, ``s:real->bool``] 12175 CONTINUOUS_OPEN_PREIMAGE_UNIV) THEN 12176 ASM_SIMP_TAC std_ss [CONTINUOUS_SUB, CONTINUOUS_AT_ID, CONTINUOUS_CONST] THEN 12177 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 12178 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE, IN_UNIV] THEN 12179 ASM_MESON_TAC[REAL_ARITH ``(a + x) - a = x:real``, 12180 REAL_ARITH ``a + (x - a) = x:real``]); 12181 12182val OPEN_TRANSLATION_EQ = store_thm ("OPEN_TRANSLATION_EQ", 12183 ``!a s. open (IMAGE (\x:real. a + x) s) <=> open s``, 12184 REPEAT GEN_TAC THEN EQ_TAC THENL 12185 [ALL_TAC, REWRITE_TAC [OPEN_TRANSLATION]] THEN 12186 REWRITE_TAC [open_def] THEN DISCH_TAC THEN GEN_TAC THEN 12187 DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN 12188 KNOW_TAC ``a + x IN IMAGE (\x:real. a + x) s`` THENL 12189 [SIMP_TAC std_ss [IN_IMAGE, REAL_EQ_LADD] THEN METIS_TAC [], 12190 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 12191 STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC [] THEN 12192 GEN_TAC THEN DISCH_TAC THEN FULL_SIMP_TAC std_ss [dist, IN_IMAGE] THEN 12193 FIRST_X_ASSUM (MP_TAC o SPEC ``a + x':real``) THEN 12194 ASM_SIMP_TAC real_ss [REAL_ARITH ``a + b - (a + c) = b - c:real``] THEN 12195 REWRITE_TAC [REAL_EQ_LADD] THEN METIS_TAC []); 12196 12197val OPEN_AFFINITY = store_thm ("OPEN_AFFINITY", 12198 ``!s a:real c. 12199 open s /\ ~(c = &0) ==> open (IMAGE (\x. a + c * x) s)``, 12200 REPEAT STRIP_TAC THEN 12201 SUBGOAL_THEN ``(\x:real. a + c * x) = (\x. a + x) o (\x. c * x)`` 12202 SUBST1_TAC THENL [REWRITE_TAC[o_DEF], ALL_TAC] THEN 12203 ASM_SIMP_TAC std_ss [IMAGE_COMPOSE, OPEN_TRANSLATION, OPEN_SCALING]); 12204 12205val INTERIOR_TRANSLATION = store_thm ("INTERIOR_TRANSLATION", 12206 ``!a:real s. 12207 interior (IMAGE (\x. a + x) s) = IMAGE (\x. a + x) (interior s)``, 12208 REPEAT STRIP_TAC THEN 12209 KNOW_TAC ``(!t. ?s. IMAGE ((\x. a + x):real->real) s = t)`` THENL 12210 [REWRITE_TAC [SURJECTIVE_IMAGE] THEN GEN_TAC THEN EXISTS_TAC ``-a + y:real`` THEN 12211 SIMP_TAC std_ss [] THEN REAL_ARITH_TAC, DISCH_TAC] THEN 12212 REWRITE_TAC [interior] THEN 12213 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN 12214 GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 12215 [FIRST_ASSUM (MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 12216 DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC [IN_IMAGE] THEN 12217 SIMP_TAC std_ss [] THEN STRIP_TAC THEN EXISTS_TAC ``x':real`` THEN 12218 ASM_REWRITE_TAC [] THEN 12219 FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN STRIP_TAC THEN 12220 EXISTS_TAC ``s':real->bool`` THEN REPEAT CONJ_TAC THENL 12221 [METIS_TAC [OPEN_TRANSLATION_EQ], 12222 UNDISCH_TAC ``IMAGE ((\x. a + x):real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN 12223 DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_SIMP_TAC std_ss [IN_IMAGE] THEN 12224 REWRITE_TAC [REAL_EQ_LADD] THEN METIS_TAC [], 12225 REWRITE_TAC [SUBSET_DEF] THEN X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 12226 UNDISCH_TAC ``IMAGE ((\x. a + x):real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN 12227 DISCH_THEN (MP_TAC o SPEC ``a + y:real``) THEN SIMP_TAC std_ss [IN_IMAGE] THEN 12228 KNOW_TAC ``(?x:real. (a + y = a + x) /\ x IN s')`` THENL 12229 [METIS_TAC [], ALL_TAC] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 12230 DISCH_TAC THEN UNDISCH_TAC ``t SUBSET IMAGE ((\x. a + x):real->real) s`` THEN 12231 REWRITE_TAC [SUBSET_DEF] THEN DISCH_THEN (MP_TAC o SPEC ``a + y:real``) THEN 12232 ASM_REWRITE_TAC [] THEN SIMP_TAC std_ss [IN_IMAGE, REAL_EQ_LADD]], ALL_TAC] THEN 12233 FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN 12234 STRIP_TAC THEN EXISTS_TAC ``IMAGE (\x:real. a + x) t`` THEN 12235 REPEAT CONJ_TAC THENL 12236 [METIS_TAC [OPEN_TRANSLATION_EQ], 12237 SIMP_TAC std_ss [IN_IMAGE] THEN EXISTS_TAC ``x':real`` THEN 12238 ASM_REWRITE_TAC [], 12239 MATCH_MP_TAC IMAGE_SUBSET THEN ASM_REWRITE_TAC []]); 12240 12241val OPEN_SUMS = store_thm ("OPEN_SUMS", 12242 ``!s t:real->bool. 12243 open s \/ open t ==> open {x + y | x IN s /\ y IN t}``, 12244 REPEAT GEN_TAC THEN REWRITE_TAC[open_def] THEN STRIP_TAC THEN 12245 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 12246 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THENL 12247 [FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``), 12248 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``)] THEN 12249 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN 12250 EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN 12251 X_GEN_TAC ``z:real`` THEN DISCH_TAC THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN 12252 METIS_TAC[REAL_ADD_SYM, REAL_ARITH ``(z - y) + y:real = z``, dist, 12253 REAL_ARITH ``abs(z:real - (x + y)) < e ==> abs(z - y - x) < e``]); 12254 12255(* ------------------------------------------------------------------------- *) 12256(* Upper and lower hemicontinuous functions, relation in the case of *) 12257(* preimage map to open and closed maps, and fact that upper and lower *) 12258(* hemicontinuity together imply continuity in the sense of the Hausdorff *) 12259(* metric (at points where the function gives a bounded and nonempty set). *) 12260(* ------------------------------------------------------------------------- *) 12261 12262val UPPER_HEMICONTINUOUS = store_thm ("UPPER_HEMICONTINUOUS", 12263 ``!f:real->real->bool t s. 12264 (!x. x IN s ==> f(x) SUBSET t) 12265 ==> ((!u. open_in (subtopology euclidean t) u 12266 ==> open_in (subtopology euclidean s) 12267 {x | x IN s /\ f(x) SUBSET u}) <=> 12268 (!u. closed_in (subtopology euclidean t) u 12269 ==> closed_in (subtopology euclidean s) 12270 {x | x IN s /\ ~(f(x) INTER u = {})}))``, 12271 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 12272 FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN 12273 MATCH_MP_TAC MONO_IMP THEN 12274 SIMP_TAC std_ss [OPEN_IN_DIFF, CLOSED_IN_DIFF, OPEN_IN_REFL, CLOSED_IN_REFL] THENL 12275 [REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ], REWRITE_TAC[closed_in]] THEN 12276 SIMP_TAC std_ss [TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, SUBSET_RESTRICT] THEN 12277 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]); 12278 12279val LOWER_HEMICONTINUOUS = store_thm ("LOWER_HEMICONTINUOUS", 12280 ``!f:real->real->bool t s. 12281 (!x. x IN s ==> f(x) SUBSET t) 12282 ==> ((!u. closed_in (subtopology euclidean t) u 12283 ==> closed_in (subtopology euclidean s) 12284 {x | x IN s /\ f(x) SUBSET u}) <=> 12285 (!u. open_in (subtopology euclidean t) u 12286 ==> open_in (subtopology euclidean s) 12287 {x | x IN s /\ ~(f(x) INTER u = {})}))``, 12288 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN 12289 FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN 12290 MATCH_MP_TAC MONO_IMP THEN 12291 SIMP_TAC std_ss [OPEN_IN_DIFF, CLOSED_IN_DIFF, OPEN_IN_REFL, CLOSED_IN_REFL] THENL 12292 [REWRITE_TAC[closed_in], REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ]] THEN 12293 SIMP_TAC std_ss [TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, SUBSET_RESTRICT] THEN 12294 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]); 12295 12296val OPEN_MAP_IFF_LOWER_HEMICONTINUOUS_PREIMAGE = store_thm ("OPEN_MAP_IFF_LOWER_HEMICONTINUOUS_PREIMAGE", 12297 ``!f:real->real s t. 12298 IMAGE f s SUBSET t 12299 ==> ((!u. open_in (subtopology euclidean s) u 12300 ==> open_in (subtopology euclidean t) (IMAGE f u)) <=> 12301 (!u. closed_in (subtopology euclidean s) u 12302 ==> closed_in (subtopology euclidean t) 12303 {y | y IN t /\ 12304 {x | x IN s /\ (f x = y)} SUBSET u}))``, 12305 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 12306 [X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN 12307 FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN 12308 ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL] THEN 12309 SIMP_TAC std_ss [OPEN_IN_CLOSED_IN_EQ, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 12310 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 12311 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 12312 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[], 12313 X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN 12314 FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN 12315 ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL] THEN 12316 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 12317 REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 12318 DISCH_THEN(fn th => CONJ_TAC THENL [ASM_SET_TAC[], MP_TAC th]) THEN 12319 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]]); 12320 12321val CLOSED_MAP_IFF_UPPER_HEMICONTINUOUS_PREIMAGE = store_thm ("CLOSED_MAP_IFF_UPPER_HEMICONTINUOUS_PREIMAGE", 12322 ``!f:real->real s t. 12323 IMAGE f s SUBSET t 12324 ==> ((!u. closed_in (subtopology euclidean s) u 12325 ==> closed_in (subtopology euclidean t) (IMAGE f u)) <=> 12326 (!u. open_in (subtopology euclidean s) u 12327 ==> open_in (subtopology euclidean t) 12328 {y | y IN t /\ 12329 {x | x IN s /\ (f x = y)} SUBSET u}))``, 12330 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 12331 [X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN 12332 FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN 12333 ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL] THEN 12334 SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 12335 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 12336 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 12337 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[], 12338 X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN 12339 FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN 12340 ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL] THEN 12341 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN 12342 REWRITE_TAC[closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 12343 DISCH_THEN(fn th => CONJ_TAC THENL [ASM_SET_TAC[], MP_TAC th]) THEN 12344 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]]); 12345 12346val UPPER_LOWER_HEMICONTINUOUS_EXPLICIT = store_thm ("UPPER_LOWER_HEMICONTINUOUS_EXPLICIT", 12347 ``!f:real->real->bool t s. 12348 (!x. x IN s ==> f(x) SUBSET t) /\ 12349 (!u. open_in (subtopology euclidean t) u 12350 ==> open_in (subtopology euclidean s) 12351 {x | x IN s /\ f(x) SUBSET u}) /\ 12352 (!u. closed_in (subtopology euclidean t) u 12353 ==> closed_in (subtopology euclidean s) 12354 {x | x IN s /\ f(x) SUBSET u}) 12355 ==> !x e. x IN s /\ &0 < e /\ bounded(f x) /\ ~(f x = {}) 12356 ==> ?d. &0 < d /\ 12357 !x'. x' IN s /\ dist(x,x') < d 12358 ==> (!y. y IN f x 12359 ==> ?y'. y' IN f x' /\ dist(y,y') < e) /\ 12360 (!y'. y' IN f x' 12361 ==> ?y. y IN f x /\ dist(y',y) < e)``, 12362 REPEAT STRIP_TAC THEN 12363 UNDISCH_TAC 12364 ``!u. open_in (subtopology euclidean t) u 12365 ==> open_in (subtopology euclidean s) 12366 {x | x IN s /\ (f:real->real->bool)(x) SUBSET u}`` THEN 12367 DISCH_THEN(MP_TAC o SPEC 12368 ``t INTER 12369 {a + b | a IN (f:real->real->bool) x /\ b IN ball(0,e)}``) THEN 12370 SIMP_TAC std_ss [OPEN_SUMS, OPEN_BALL, OPEN_IN_OPEN_INTER] THEN 12371 SIMP_TAC std_ss [open_in, SUBSET_RESTRICT] THEN 12372 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 12373 ASM_SIMP_TAC std_ss [GSPECIFICATION, SUBSET_INTER] THEN 12374 KNOW_TAC ``(f :real -> real -> bool) (x :real) SUBSET 12375 {a + b | a IN f x /\ b IN ball ((0 :real),(e :real))}`` THENL 12376 [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN 12377 METIS_TAC[CENTRE_IN_BALL, REAL_ADD_RID], 12378 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 12379 DISCH_THEN(X_CHOOSE_THEN ``d1:real`` 12380 (CONJUNCTS_THEN2 ASSUME_TAC ASSUME_TAC))] THEN 12381 UNDISCH_TAC 12382 ``!u. closed_in (subtopology euclidean t) u 12383 ==> closed_in (subtopology euclidean s) 12384 {x | x IN s /\ (f:real->real->bool)(x) SUBSET u}`` THEN 12385 ASM_SIMP_TAC std_ss [LOWER_HEMICONTINUOUS] THEN DISCH_THEN(MP_TAC o 12386 GEN ``a:real`` o SPEC ``t INTER ball(a:real,e / &2)``) THEN 12387 SIMP_TAC std_ss [OPEN_BALL, OPEN_IN_OPEN_INTER] THEN 12388 MP_TAC(SPEC ``closure((f:real->real->bool) x)`` 12389 COMPACT_EQ_HEINE_BOREL) THEN 12390 ASM_REWRITE_TAC[COMPACT_CLOSURE] THEN DISCH_THEN(MP_TAC o SPEC 12391 ``{ball(a:real,e / &2) | a IN (f:real->real->bool) x}``) THEN 12392 SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, OPEN_BALL] THEN 12393 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN 12394 SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE] THEN 12395 KNOW_TAC ``closure ((f :real -> real -> bool) (x :real)) SUBSET 12396 BIGUNION (IMAGE (\(a :real). ball (a,(e :real) / (2 :real))) (f x))`` THENL 12397 [SIMP_TAC std_ss [CLOSURE_APPROACHABLE, SUBSET_DEF, BIGUNION_IMAGE, GSPECIFICATION] THEN 12398 REWRITE_TAC[IN_BALL] THEN ASM_SIMP_TAC std_ss [REAL_HALF], 12399 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 12400 DISCH_THEN(X_CHOOSE_THEN ``c:real->bool`` STRIP_ASSUME_TAC) THEN 12401 DISCH_TAC THEN FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP 12402 (METIS[CLOSURE_SUBSET, SUBSET_TRANS] 12403 ``closure s SUBSET t ==> s SUBSET t``)) THEN 12404 SUBGOAL_THEN 12405 ``open_in (subtopology euclidean s) 12406 (BIGINTER {{x | x IN s /\ 12407 ~((f:real->real->bool) x INTER t INTER ball(a,e / &2) = {})} | 12408 a IN c})`` 12409 MP_TAC THENL 12410 [MATCH_MP_TAC OPEN_IN_BIGINTER THEN 12411 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, IMAGE_FINITE, 12412 GSYM INTER_ASSOC] THEN ASM_SIMP_TAC std_ss [IMAGE_EQ_EMPTY] THEN 12413 ASM_SET_TAC[], ALL_TAC] THEN 12414 REWRITE_TAC[open_in] THEN 12415 DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN 12416 KNOW_TAC ``(x :real) IN 12417 BIGINTER {{x | 12418 x IN (s :real -> bool) /\ 12419 (f :real -> real -> bool) x INTER (t :real -> bool) INTER 12420 ball (a,(e :real) / (2 :real)) <> ({} :real -> bool)} | 12421 a IN (c :real -> bool)}`` THENL 12422 [SIMP_TAC std_ss [BIGINTER_GSPEC, GSPECIFICATION] THEN 12423 X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN 12424 ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN 12425 EXISTS_TAC ``a:real`` THEN 12426 ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, REAL_HALF] THEN 12427 ASM_SET_TAC[], 12428 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 12429 DISCH_THEN(X_CHOOSE_THEN ``d2:real`` 12430 (CONJUNCTS_THEN2 ASSUME_TAC ASSUME_TAC))] THEN 12431 EXISTS_TAC ``min d1 d2:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 12432 X_GEN_TAC ``x':real`` THEN STRIP_TAC THEN CONJ_TAC THENL 12433 [ALL_TAC, 12434 UNDISCH_TAC ``!x'':real. 12435 x'' IN s /\ dist (x'',x) < d1 ==> 12436 f x'' SUBSET {a + b | a IN f x /\ b IN ball (0,e)}`` THEN 12437 DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC ``x':real``) THEN 12438 ASM_REWRITE_TAC[] THEN 12439 KNOW_TAC ``dist (x',x) < d1:real`` THENL 12440 [ASM_MESON_TAC[DIST_SYM], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 12441 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD, IN_BALL] THEN 12442 SIMP_TAC std_ss [REAL_ARITH ``(x:real = a + b) <=> (x - a = b)``, 12443 DIST_0, ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN 12444 REWRITE_TAC[dist]] THEN 12445 UNDISCH_TAC ``!x':real. 12446 x' IN s /\ dist (x',x) < d2 ==> 12447 x' IN 12448 BIGINTER 12449 {{x | x IN s /\ f x INTER t INTER ball (a,e / 2) <> {}} | 12450 a IN c}`` THEN DISCH_TAC THEN 12451 FIRST_X_ASSUM (MP_TAC o SPEC ``x':real``) THEN 12452 ASM_SIMP_TAC std_ss [BIGINTER_GSPEC, GSPECIFICATION] THEN 12453 KNOW_TAC ``dist (x',x) < d2:real`` THENL 12454 [ASM_MESON_TAC[DIST_SYM], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 12455 DISCH_TAC THEN 12456 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 12457 UNDISCH_TAC ``(f:real->real->bool) x SUBSET 12458 BIGUNION (IMAGE (\a. ball (a,e / &2)) c)`` THEN 12459 REWRITE_TAC[SUBSET_DEF] THEN DISCH_THEN(MP_TAC o SPEC ``y:real``) THEN 12460 ASM_SIMP_TAC std_ss [BIGUNION_IMAGE, GSPECIFICATION, IN_BALL] THEN 12461 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 12462 UNDISCH_TAC ``!(a' :real). 12463 a' IN (c :real -> bool) ==> 12464 (f :real -> real -> bool) (x' :real) INTER 12465 (t :real -> bool) INTER ball (a',(e :real) / (2 :real)) <> 12466 ({} :real -> bool)`` THEN DISCH_TAC THEN 12467 FIRST_X_ASSUM (MP_TAC o SPEC ``a:real``) THEN 12468 ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER, IN_BALL] THEN 12469 DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN 12470 POP_ASSUM MP_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 12471 METIS_TAC[DIST_TRIANGLE_HALF_L, DIST_SYM]); 12472 12473(* ------------------------------------------------------------------------- *) 12474(* Connected components, considered as a "connectedness" relation or a set. *) 12475(* ------------------------------------------------------------------------- *) 12476 12477val connected_component = new_definition ("connected_component", 12478 ``connected_component s x y <=> 12479 ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t``); 12480 12481val CONNECTED_COMPONENT_IN = store_thm ("CONNECTED_COMPONENT_IN", 12482 ``!s x y. connected_component s x y ==> x IN s /\ y IN s``, 12483 REWRITE_TAC[connected_component] THEN SET_TAC[]); 12484 12485val CONNECTED_COMPONENT_REFL = store_thm ("CONNECTED_COMPONENT_REFL", 12486 ``!s x:real. x IN s ==> connected_component s x x``, 12487 REWRITE_TAC[connected_component] THEN REPEAT STRIP_TAC THEN 12488 EXISTS_TAC ``{x:real}`` THEN REWRITE_TAC[CONNECTED_SING] THEN 12489 ASM_SET_TAC[]); 12490 12491val CONNECTED_COMPONENT_REFL_EQ = store_thm ("CONNECTED_COMPONENT_REFL_EQ", 12492 ``!s x:real. connected_component s x x <=> x IN s``, 12493 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_REFL] THEN 12494 REWRITE_TAC[connected_component] THEN SET_TAC[]); 12495 12496val CONNECTED_COMPONENT_SYM = store_thm ("CONNECTED_COMPONENT_SYM", 12497 ``!s x y:real. connected_component s x y ==> connected_component s y x``, 12498 REWRITE_TAC[connected_component] THEN MESON_TAC[]); 12499 12500val CONNECTED_COMPONENT_TRANS = store_thm ("CONNECTED_COMPONENT_TRANS", 12501 ``!s x y:real. 12502 connected_component s x y /\ connected_component s y z 12503 ==> connected_component s x z``, 12504 REPEAT GEN_TAC THEN REWRITE_TAC[connected_component] THEN 12505 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC ``t:real->bool``) 12506 (X_CHOOSE_TAC ``u:real->bool``)) THEN 12507 EXISTS_TAC ``t UNION u:real->bool`` THEN 12508 ASM_REWRITE_TAC[IN_UNION, UNION_SUBSET] THEN 12509 MATCH_MP_TAC CONNECTED_UNION THEN ASM_SET_TAC[]); 12510 12511val CONNECTED_COMPONENT_OF_SUBSET = store_thm ("CONNECTED_COMPONENT_OF_SUBSET", 12512 ``!s t x. s SUBSET t /\ connected_component s x y 12513 ==> connected_component t x y``, 12514 REWRITE_TAC[connected_component] THEN SET_TAC[]); 12515 12516val CONNECTED_COMPONENT_SET = store_thm ("CONNECTED_COMPONENT_SET", 12517 ``!s x. connected_component s x = 12518 { y | ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t}``, 12519 SIMP_TAC std_ss [GSPECIFICATION, EXTENSION] THEN 12520 SIMP_TAC std_ss [IN_DEF, connected_component]); 12521 12522val CONNECTED_COMPONENT_BIGUNION = store_thm ("CONNECTED_COMPONENT_BIGUNION", 12523 ``!s x. connected_component s x = 12524 BIGUNION {t | connected t /\ x IN t /\ t SUBSET s}``, 12525 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]); 12526 12527val CONNECTED_COMPONENT_SUBSET = store_thm ("CONNECTED_COMPONENT_SUBSET", 12528 ``!s x. (connected_component s x) SUBSET s``, 12529 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]); 12530 12531val CONNECTED_CONNECTED_COMPONENT_SET = store_thm ("CONNECTED_CONNECTED_COMPONENT_SET", 12532 ``!s. connected s <=> !x:real. x IN s ==> (connected_component s x = s)``, 12533 GEN_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_BIGUNION] THEN EQ_TAC THENL 12534 [SET_TAC[], ALL_TAC] THEN 12535 ASM_CASES_TAC ``s:real->bool = {}`` THEN 12536 ASM_REWRITE_TAC[CONNECTED_EMPTY] THEN 12537 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 12538 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 12539 DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN ASM_REWRITE_TAC[] THEN 12540 DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC CONNECTED_BIGUNION THEN 12541 ASM_SET_TAC[]); 12542 12543val CONNECTED_COMPONENT_UNIV = store_thm ("CONNECTED_COMPONENT_UNIV", 12544 ``!x. connected_component univ(:real) x = univ(:real)``, 12545 MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET, CONNECTED_UNIV, IN_UNIV]); 12546 12547val CONNECTED_COMPONENT_EQ_UNIV = store_thm ("CONNECTED_COMPONENT_EQ_UNIV", 12548 ``!s x. (connected_component s x = univ(:real)) <=> (s = univ(:real))``, 12549 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CONNECTED_COMPONENT_UNIV] THEN 12550 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (s = UNIV) ==> (t = UNIV)``) THEN 12551 REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]); 12552 12553val CONNECTED_COMPONENT_EQ_SELF = store_thm ("CONNECTED_COMPONENT_EQ_SELF", 12554 ``!s x. connected s /\ x IN s ==> (connected_component s x = s)``, 12555 MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET]); 12556 12557val CONNECTED_IFF_CONNECTED_COMPONENT = store_thm ("CONNECTED_IFF_CONNECTED_COMPONENT", 12558 ``!s. connected s <=> 12559 !x y. x IN s /\ y IN s ==> connected_component s x y``, 12560 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT_SET] THEN 12561 REWRITE_TAC[EXTENSION] THEN MESON_TAC[IN_DEF, CONNECTED_COMPONENT_IN]); 12562 12563val CONNECTED_COMPONENT_MAXIMAL = store_thm ("CONNECTED_COMPONENT_MAXIMAL", 12564 ``!s t x:real. 12565 x IN t /\ connected t /\ t SUBSET s 12566 ==> t SUBSET (connected_component s x)``, 12567 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]); 12568 12569val CONNECTED_COMPONENT_MONO = store_thm ("CONNECTED_COMPONENT_MONO", 12570 ``!s t x. s SUBSET t 12571 ==> (connected_component s x) SUBSET (connected_component t x)``, 12572 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]); 12573 12574val CONNECTED_CONNECTED_COMPONENT = store_thm ("CONNECTED_CONNECTED_COMPONENT", 12575 ``!s x. connected(connected_component s x)``, 12576 REWRITE_TAC[CONNECTED_COMPONENT_BIGUNION] THEN 12577 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_BIGUNION THEN SET_TAC[]); 12578 12579val CONNECTED_COMPONENT_EQ_EMPTY = store_thm ("CONNECTED_COMPONENT_EQ_EMPTY", 12580 ``!s x:real. (connected_component s x = {}) <=> ~(x IN s)``, 12581 REPEAT GEN_TAC THEN EQ_TAC THENL 12582 [REWRITE_TAC[EXTENSION, NOT_IN_EMPTY] THEN 12583 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 12584 SIMP_TAC std_ss [IN_DEF, CONNECTED_COMPONENT_REFL_EQ], 12585 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]]); 12586 12587val CONNECTED_COMPONENT_EMPTY = store_thm ("CONNECTED_COMPONENT_EMPTY", 12588 ``!x. connected_component {} x = {}``, 12589 REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY, NOT_IN_EMPTY]); 12590 12591val CONNECTED_COMPONENT_EQ = store_thm ("CONNECTED_COMPONENT_EQ", 12592 ``!s x y. y IN connected_component s x 12593 ==> ((connected_component s y = connected_component s x))``, 12594 REWRITE_TAC[EXTENSION, IN_DEF] THEN 12595 MESON_TAC[CONNECTED_COMPONENT_SYM, CONNECTED_COMPONENT_TRANS]); 12596 12597val CLOSED_CONNECTED_COMPONENT = store_thm ("CLOSED_CONNECTED_COMPONENT", 12598 ``!s x:real. closed s ==> closed(connected_component s x)``, 12599 REPEAT STRIP_TAC THEN 12600 ASM_CASES_TAC ``(x:real) IN s`` THENL 12601 [ALL_TAC, ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY, CLOSED_EMPTY]] THEN 12602 REWRITE_TAC[GSYM CLOSURE_EQ] THEN 12603 MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[CLOSURE_SUBSET] THEN 12604 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN 12605 SIMP_TAC std_ss [CONNECTED_CLOSURE, CONNECTED_CONNECTED_COMPONENT] THEN 12606 CONJ_TAC THENL 12607 [MATCH_MP_TAC(REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET) THEN 12608 ASM_SIMP_TAC std_ss [IN_DEF, CONNECTED_COMPONENT_REFL_EQ], 12609 MATCH_MP_TAC CLOSURE_MINIMAL THEN 12610 ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_SUBSET]]); 12611 12612val CONNECTED_COMPONENT_DISJOINT = store_thm ("CONNECTED_COMPONENT_DISJOINT", 12613 ``!s a b. DISJOINT (connected_component s a) (connected_component s b) <=> 12614 ~(a IN connected_component s b)``, 12615 REWRITE_TAC[DISJOINT_DEF, EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN 12616 REWRITE_TAC[IN_DEF] THEN 12617 MESON_TAC[CONNECTED_COMPONENT_SYM, CONNECTED_COMPONENT_TRANS]); 12618 12619val CONNECTED_COMPONENT_NONOVERLAP = store_thm ("CONNECTED_COMPONENT_NONOVERLAP", 12620 ``!s a b:real. 12621 ((connected_component s a) INTER (connected_component s b) = {}) <=> 12622 ~(a IN s) \/ ~(b IN s) \/ 12623 ~(connected_component s a = connected_component s b)``, 12624 REPEAT GEN_TAC THEN 12625 ASM_CASES_TAC ``(a:real) IN s`` THEN ASM_REWRITE_TAC[] THEN 12626 RULE_ASSUM_TAC(SIMP_RULE std_ss [GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN 12627 ASM_SIMP_TAC std_ss [INTER_EMPTY] THEN 12628 ASM_CASES_TAC ``(b:real) IN s`` THEN ASM_REWRITE_TAC[] THEN 12629 RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN 12630 ASM_REWRITE_TAC[INTER_EMPTY] THEN ASM_CASES_TAC 12631 ``connected_component s (a:real) = connected_component s b`` THEN 12632 ASM_REWRITE_TAC[INTER_IDEMPOT, CONNECTED_COMPONENT_EQ_EMPTY] THEN 12633 POP_ASSUM MP_TAC THEN 12634 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 12635 REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN 12636 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM DISJOINT_DEF]) THEN 12637 REWRITE_TAC[CONNECTED_COMPONENT_DISJOINT]); 12638 12639val CONNECTED_COMPONENT_OVERLAP = store_thm ("CONNECTED_COMPONENT_OVERLAP", 12640 ``!s a b:real. 12641 ~((connected_component s a) INTER (connected_component s b) = {}) <=> 12642 a IN s /\ b IN s /\ 12643 (connected_component s a = connected_component s b)``, 12644 REWRITE_TAC[CONNECTED_COMPONENT_NONOVERLAP, DE_MORGAN_THM]); 12645 12646val CONNECTED_COMPONENT_SYM_EQ = store_thm ("CONNECTED_COMPONENT_SYM_EQ", 12647 ``!s x y. connected_component s x y <=> connected_component s y x``, 12648 MESON_TAC[CONNECTED_COMPONENT_SYM]); 12649 12650val CONNECTED_COMPONENT_EQ_EQ = store_thm ("CONNECTED_COMPONENT_EQ_EQ", 12651 ``!s x y:real. 12652 (connected_component s x = connected_component s y) <=> 12653 ~(x IN s) /\ ~(y IN s) \/ 12654 x IN s /\ y IN s /\ connected_component s x y``, 12655 REPEAT GEN_TAC THEN ASM_CASES_TAC ``(y:real) IN s`` THENL 12656 [ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_REWRITE_TAC[] THENL 12657 [REWRITE_TAC[FUN_EQ_THM] THEN 12658 ASM_MESON_TAC[CONNECTED_COMPONENT_TRANS, CONNECTED_COMPONENT_REFL, 12659 CONNECTED_COMPONENT_SYM], 12660 ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]], 12661 RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN 12662 ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY] THEN 12663 ONCE_REWRITE_TAC[CONNECTED_COMPONENT_SYM_EQ] THEN 12664 ASM_REWRITE_TAC[EMPTY_DEF] THEN ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]]); 12665 12666val CONNECTED_EQ_CONNECTED_COMPONENT_EQ = store_thm ("CONNECTED_EQ_CONNECTED_COMPONENT_EQ", 12667 ``!s. connected s <=> 12668 !x y. x IN s /\ y IN s 12669 ==> (connected_component s x = connected_component s y)``, 12670 SIMP_TAC std_ss [CONNECTED_COMPONENT_EQ_EQ] THEN 12671 REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT]); 12672 12673val CONNECTED_COMPONENT_IDEMP = store_thm ("CONNECTED_COMPONENT_IDEMP", 12674 ``!s x:real. connected_component (connected_component s x) x = 12675 connected_component s x``, 12676 REWRITE_TAC[FUN_EQ_THM, connected_component] THEN 12677 REPEAT GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN EQ_TAC THEN 12678 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 12679 ASM_MESON_TAC[CONNECTED_COMPONENT_MAXIMAL, SUBSET_TRANS, 12680 CONNECTED_COMPONENT_SUBSET]); 12681 12682val CONNECTED_COMPONENT_UNIQUE = store_thm ("CONNECTED_COMPONENT_UNIQUE", 12683 ``!s c x:real. 12684 x IN c /\ c SUBSET s /\ connected c /\ 12685 (!c'. x IN c' /\ c' SUBSET s /\ connected c' 12686 ==> c' SUBSET c) 12687 ==> (connected_component s x = c)``, 12688 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 12689 [FIRST_X_ASSUM MATCH_MP_TAC THEN 12690 REWRITE_TAC[CONNECTED_COMPONENT_SUBSET, CONNECTED_CONNECTED_COMPONENT] THEN 12691 REWRITE_TAC[IN_DEF] THEN ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_REFL_EQ] THEN 12692 ASM_SET_TAC[], 12693 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]]); 12694 12695val JOINABLE_CONNECTED_COMPONENT_EQ = store_thm ("JOINABLE_CONNECTED_COMPONENT_EQ", 12696 ``!s t x y:real. 12697 connected t /\ t SUBSET s /\ 12698 ~(connected_component s x INTER t = {}) /\ 12699 ~(connected_component s y INTER t = {}) 12700 ==> (connected_component s x = connected_component s y)``, 12701 REPEAT GEN_TAC THEN 12702 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 12703 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 12704 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER] THEN DISCH_THEN(CONJUNCTS_THEN2 12705 (X_CHOOSE_THEN ``w:real`` STRIP_ASSUME_TAC) 12706 (X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC)) THEN 12707 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN 12708 SIMP_TAC std_ss [IN_DEF] THEN 12709 MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN 12710 EXISTS_TAC ``z:real`` THEN CONJ_TAC THENL [ASM_MESON_TAC[IN_DEF], ALL_TAC] THEN 12711 MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN 12712 EXISTS_TAC ``w:real`` THEN CONJ_TAC THENL 12713 [REWRITE_TAC[connected_component] THEN 12714 EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[], 12715 ASM_MESON_TAC[IN_DEF, CONNECTED_COMPONENT_SYM]]); 12716 12717val BIGUNION_CONNECTED_COMPONENT = store_thm ("BIGUNION_CONNECTED_COMPONENT", 12718 ``!s:real->bool. BIGUNION {connected_component s x |x| x IN s} = s``, 12719 GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 12720 SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_GSPEC, CONNECTED_COMPONENT_SUBSET] THEN 12721 SIMP_TAC std_ss [SUBSET_DEF, BIGUNION_GSPEC, GSPECIFICATION] THEN 12722 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN EXISTS_TAC ``x:real`` THEN 12723 ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN_DEF] THEN 12724 ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_REFL_EQ]); 12725 12726val COMPLEMENT_CONNECTED_COMPONENT_BIGUNION = store_thm ("COMPLEMENT_CONNECTED_COMPONENT_BIGUNION", 12727 ``!s x:real. 12728 s DIFF connected_component s x = 12729 BIGUNION({connected_component s y | y | y IN s} DELETE 12730 (connected_component s x))``, 12731 REPEAT GEN_TAC THEN 12732 GEN_REWR_TAC (LAND_CONV o LAND_CONV) 12733 [GSYM BIGUNION_CONNECTED_COMPONENT] THEN 12734 MATCH_MP_TAC(SET_RULE 12735 ``(!x. x IN s DELETE a ==> DISJOINT a x) 12736 ==> (BIGUNION s DIFF a = BIGUNION (s DELETE a))``) THEN 12737 SIMP_TAC std_ss [CONJ_EQ_IMP, FORALL_IN_GSPEC, IN_DELETE] THEN 12738 SIMP_TAC std_ss [CONNECTED_COMPONENT_DISJOINT, CONNECTED_COMPONENT_EQ_EQ] THEN 12739 MESON_TAC[IN_DEF, SUBSET_DEF, CONNECTED_COMPONENT_SUBSET]); 12740 12741val CLOSED_IN_CONNECTED_COMPONENT = store_thm ("CLOSED_IN_CONNECTED_COMPONENT", 12742 ``!s x:real. closed_in (subtopology euclidean s) (connected_component s x)``, 12743 REPEAT GEN_TAC THEN 12744 ASM_CASES_TAC ``connected_component s (x:real) = {}`` THEN 12745 ASM_REWRITE_TAC[CLOSED_IN_EMPTY] THEN 12746 RULE_ASSUM_TAC(REWRITE_RULE[CONNECTED_COMPONENT_EQ_EMPTY]) THEN 12747 REWRITE_TAC[CLOSED_IN_CLOSED] THEN 12748 EXISTS_TAC ``closure(connected_component s x):real->bool`` THEN 12749 REWRITE_TAC[CLOSED_CLOSURE] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 12750 REWRITE_TAC[SUBSET_INTER, CONNECTED_COMPONENT_SUBSET, CLOSURE_SUBSET] THEN 12751 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN REWRITE_TAC[INTER_SUBSET] THEN 12752 CONJ_TAC THENL 12753 [ASM_REWRITE_TAC[IN_INTER] THEN 12754 MATCH_MP_TAC(REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET) THEN 12755 ASM_SIMP_TAC std_ss [IN_DEF, CONNECTED_COMPONENT_REFL_EQ], 12756 MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN 12757 EXISTS_TAC ``connected_component s (x:real)`` THEN 12758 SIMP_TAC std_ss [INTER_SUBSET, CONNECTED_CONNECTED_COMPONENT, 12759 SUBSET_INTER, CONNECTED_COMPONENT_SUBSET, CLOSURE_SUBSET]]); 12760 12761val BIGUNION_DIFF = store_thm ("BIGUNION_DIFF", 12762 ``!s t. BIGUNION s DIFF t = BIGUNION {x DIFF t | x IN s}``, 12763 SIMP_TAC std_ss [BIGUNION_GSPEC] THEN SET_TAC[]); 12764 12765val OPEN_IN_CONNECTED_COMPONENT = store_thm ("OPEN_IN_CONNECTED_COMPONENT", 12766 ``!s x:real. 12767 FINITE {connected_component s x |x| x IN s} 12768 ==> open_in (subtopology euclidean s) (connected_component s x)``, 12769 REPEAT STRIP_TAC THEN 12770 SUBGOAL_THEN 12771 ``connected_component s (x:real) = 12772 s DIFF (BIGUNION {connected_component s y |y| y IN s} DIFF 12773 connected_component s x)`` 12774 SUBST1_TAC THENL 12775 [REWRITE_TAC[BIGUNION_CONNECTED_COMPONENT] THEN 12776 MATCH_MP_TAC(SET_RULE ``t SUBSET s ==> (t = s DIFF (s DIFF t))``) THEN 12777 SIMP_TAC std_ss [CONNECTED_COMPONENT_SUBSET], 12778 MATCH_MP_TAC OPEN_IN_DIFF THEN 12779 SIMP_TAC std_ss [OPEN_IN_SUBTOPOLOGY_REFL, TOPSPACE_EUCLIDEAN, SUBSET_UNIV] THEN 12780 SIMP_TAC std_ss [BIGUNION_DIFF] THEN 12781 MATCH_MP_TAC CLOSED_IN_BIGUNION THEN SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 12782 CONJ_TAC THENL [METIS_TAC [GSYM IMAGE_DEF, IMAGE_FINITE], ALL_TAC] THEN 12783 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 12784 SUBGOAL_THEN 12785 ``(connected_component s y DIFF connected_component s x = 12786 connected_component s y) \/ 12787 (connected_component s (y:real) DIFF connected_component s x = {})`` 12788 (DISJ_CASES_THEN SUBST1_TAC) 12789 THENL 12790 [MATCH_MP_TAC(SET_RULE 12791 ``(~(s INTER t = {}) ==> (s = t)) ==> (s DIFF t = s) \/ (s DIFF t = {})``) THEN 12792 SIMP_TAC std_ss [CONNECTED_COMPONENT_OVERLAP], 12793 REWRITE_TAC[CLOSED_IN_CONNECTED_COMPONENT], 12794 REWRITE_TAC[CLOSED_IN_EMPTY]]]); 12795 12796val CONNECTED_COMPONENT_EQUIVALENCE_RELATION = store_thm ("CONNECTED_COMPONENT_EQUIVALENCE_RELATION", 12797 ``!R s:real->bool. 12798 (!x y. R x y ==> R y x) /\ 12799 (!x y z. R x y /\ R y z ==> R x z) /\ 12800 (!a. a IN s 12801 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\ 12802 !x. x IN t ==> R a x) 12803 ==> !a b. connected_component s a b ==> R a b``, 12804 REPEAT STRIP_TAC THEN 12805 MP_TAC(ISPECL [``R:real->real->bool``, ``connected_component s (a:real)``] 12806 CONNECTED_EQUIVALENCE_RELATION) THEN 12807 ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN 12808 KNOW_TAC ``(!(a' :real). 12809 a' IN connected_component (s :real -> bool) (a :real) ==> 12810 ?(t :real -> bool). 12811 open_in (subtopology euclidean (connected_component s a)) t /\ 12812 a' IN t /\ 12813 !(x :real). x IN t ==> (R :real -> real -> bool) a' x)`` THENL 12814 [X_GEN_TAC ``c:real`` THEN DISCH_TAC THEN 12815 FIRST_X_ASSUM(MP_TAC o SPEC ``c:real``) THEN 12816 KNOW_TAC ``(c :real) IN (s :real -> bool)`` THENL 12817 [ASM_MESON_TAC[CONNECTED_COMPONENT_SUBSET, SUBSET_DEF], 12818 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 12819 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 12820 EXISTS_TAC ``t INTER connected_component s (a:real)`` THEN 12821 ASM_SIMP_TAC std_ss [IN_INTER, OPEN_IN_OPEN] THEN 12822 UNDISCH_TAC ``open_in (subtopology euclidean s) t`` THEN DISCH_TAC THEN 12823 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN]) THEN 12824 SIMP_TAC std_ss [] THEN 12825 MP_TAC(ISPECL [``s:real->bool``, ``a:real``] 12826 CONNECTED_COMPONENT_SUBSET) THEN 12827 SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 12828 DISCH_THEN MATCH_MP_TAC THEN ASM_SIMP_TAC std_ss [IN_DEF] THEN 12829 REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN 12830 ASM_MESON_TAC[CONNECTED_COMPONENT_IN]]); 12831 12832val CONNECTED_COMPONENT_INTERMEDIATE_SUBSET = store_thm ("CONNECTED_COMPONENT_INTERMEDIATE_SUBSET", 12833 ``!t u a:real. 12834 connected_component u a SUBSET t /\ t SUBSET u 12835 ==> (connected_component t a = connected_component u a)``, 12836 REPEAT GEN_TAC THEN ASM_CASES_TAC ``(a:real) IN u`` THENL 12837 [REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_UNIQUE THEN 12838 ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN 12839 CONJ_TAC THENL [ASM_MESON_TAC[CONNECTED_COMPONENT_REFL, IN_DEF], ALL_TAC] THEN 12840 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN 12841 ASM_SET_TAC[], 12842 ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY, SUBSET_DEF]]); 12843 12844(* ------------------------------------------------------------------------- *) 12845(* The set of connected components of a set. *) 12846(* ------------------------------------------------------------------------- *) 12847 12848val components = new_definition ("components", 12849 ``components s = {connected_component s x | x | x:real IN s}``); 12850 12851val IN_COMPONENTS = store_thm ("IN_COMPONENTS", 12852 ``!u:real->bool s. s IN components u 12853 <=> ?x. x IN u /\ (s = connected_component u x)``, 12854 REPEAT GEN_TAC THEN REWRITE_TAC[components] THEN EQ_TAC 12855 THENL [SET_TAC[], STRIP_TAC THEN ASM_SIMP_TAC std_ss [] THEN 12856 UNDISCH_TAC ``x:real IN u`` THEN SET_TAC[]]); 12857 12858val BIGUNION_COMPONENTS = store_thm 12859 ("BIGUNION_COMPONENTS", 12860 ``!u:real->bool. u = BIGUNION (components u)``, 12861 REWRITE_TAC [EXTENSION] 12862 >> REPEAT GEN_TAC >> EQ_TAC 12863 >| [ (* goal 1 (of 2) *) 12864 DISCH_TAC >> REWRITE_TAC [IN_BIGUNION] \\ 12865 EXISTS_TAC ``connected_component (u:real->bool) x`` \\ 12866 CONJ_TAC >| 12867 [ REWRITE_TAC [CONNECTED_COMPONENT_SET] \\ 12868 SUBGOAL_THEN ``?s:real->bool. connected s /\ s SUBSET u /\ x IN s`` MP_TAC >| 12869 [ EXISTS_TAC ``{x:real}`` \\ 12870 ASM_REWRITE_TAC [CONNECTED_SING] \\ 12871 POP_ASSUM MP_TAC >> SET_TAC [], 12872 SET_TAC [] ], 12873 REWRITE_TAC [components] >> ASM_SET_TAC [] ], 12874 (* goal 2 of 2 *) 12875 REWRITE_TAC [IN_BIGUNION] \\ 12876 STRIP_TAC \\ 12877 MATCH_MP_TAC (SET_RULE ``!x:real s u. x IN s /\ s SUBSET u ==> x IN u``) \\ 12878 EXISTS_TAC ``s :real -> bool`` >> ASM_REWRITE_TAC [] \\ 12879 `?(y :real). ((s :real -> bool) = connected_component u y)` 12880 by METIS_TAC [IN_COMPONENTS] \\ 12881 ASM_REWRITE_TAC [CONNECTED_COMPONENT_SUBSET] ]); 12882 12883val PAIRWISE_DISJOINT_COMPONENTS = store_thm ("PAIRWISE_DISJOINT_COMPONENTS", 12884 ``!u:real->bool. pairwise DISJOINT (components u)``, 12885 GEN_TAC THEN REWRITE_TAC[pairwise, DISJOINT_DEF] THEN 12886 MAP_EVERY X_GEN_TAC [``s:real->bool``, ``t:real->bool``] THEN STRIP_TAC THEN 12887 ASSERT_TAC ``(?a. s:real->bool = connected_component u a) /\ 12888 ?b. t:real->bool = connected_component u b`` 12889 THENL [ASM_MESON_TAC[IN_COMPONENTS], 12890 ASM_MESON_TAC[CONNECTED_COMPONENT_NONOVERLAP]]); 12891 12892val IN_COMPONENTS_NONEMPTY = store_thm ("IN_COMPONENTS_NONEMPTY", 12893 ``!s c. c IN components s ==> ~(c = {})``, 12894 REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN 12895 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY]); 12896 12897val IN_COMPONENTS_SUBSET = store_thm ("IN_COMPONENTS_SUBSET", 12898 ``!s c. c IN components s ==> c SUBSET s``, 12899 REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN 12900 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]); 12901 12902val IN_COMPONENTS_CONNECTED = store_thm ("IN_COMPONENTS_CONNECTED", 12903 ``!s c. c IN components s ==> connected c``, 12904 REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN 12905 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT]); 12906 12907val IN_COMPONENTS_MAXIMAL = store_thm ("IN_COMPONENTS_MAXIMAL", 12908 ``!s c:real->bool. 12909 c IN components s <=> 12910 ~(c = {}) /\ c SUBSET s /\ connected c /\ 12911 !c'. ~(c' = {}) /\ c SUBSET c' /\ c' SUBSET s /\ connected c' 12912 ==> (c' = c)``, 12913 REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN EQ_TAC THENL 12914 [DISCH_THEN(X_CHOOSE_THEN ``x:real`` STRIP_ASSUME_TAC) THEN 12915 ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY, CONNECTED_COMPONENT_SUBSET, 12916 CONNECTED_CONNECTED_COMPONENT] THEN 12917 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 12918 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN 12919 ASM_MESON_TAC[CONNECTED_COMPONENT_REFL, IN_DEF, SUBSET_DEF], 12920 STRIP_TAC THEN 12921 UNDISCH_TAC ``(c:real->bool) <> {}`` THEN DISCH_TAC THEN 12922 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 12923 STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN CONJ_TAC THENL 12924 [ALL_TAC, ASM_SET_TAC[]] THEN 12925 MATCH_MP_TAC(GSYM CONNECTED_COMPONENT_UNIQUE) THEN 12926 ASM_REWRITE_TAC[] THEN X_GEN_TAC ``c':real->bool`` THEN STRIP_TAC THEN 12927 REWRITE_TAC[SET_RULE ``c' SUBSET c <=> (c' UNION c = c)``] THEN 12928 FIRST_X_ASSUM MATCH_MP_TAC THEN 12929 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 12930 MATCH_MP_TAC CONNECTED_UNION THEN ASM_SET_TAC[]]); 12931 12932val JOINABLE_COMPONENTS_EQ = store_thm ("JOINABLE_COMPONENTS_EQ", 12933 ``!s t c1 c2. 12934 connected t /\ t SUBSET s /\ 12935 c1 IN components s /\ c2 IN components s /\ 12936 ~(c1 INTER t = {}) /\ ~(c2 INTER t = {}) 12937 ==> (c1 = c2)``, 12938 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, components, FORALL_IN_GSPEC] THEN 12939 MESON_TAC[JOINABLE_CONNECTED_COMPONENT_EQ]); 12940 12941val CLOSED_IN_COMPONENT = store_thm ("CLOSED_IN_COMPONENT", 12942 ``!s c:real->bool. 12943 c IN components s ==> closed_in (subtopology euclidean s) c``, 12944 SIMP_TAC std_ss [components, FORALL_IN_GSPEC, CLOSED_IN_CONNECTED_COMPONENT]); 12945 12946val CLOSED_COMPONENTS = store_thm ("CLOSED_COMPONENTS", 12947 ``!s c. closed s /\ c IN components s ==> closed c``, 12948 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, components, FORALL_IN_GSPEC] THEN 12949 SIMP_TAC std_ss [CLOSED_CONNECTED_COMPONENT]); 12950 12951val COMPACT_COMPONENTS = store_thm ("COMPACT_COMPONENTS", 12952 ``!s c:real->bool. compact s /\ c IN components s ==> compact c``, 12953 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN 12954 MESON_TAC[CLOSED_COMPONENTS, IN_COMPONENTS_SUBSET, BOUNDED_SUBSET]); 12955 12956val CONTINUOUS_ON_COMPONENTS_GEN = store_thm ("CONTINUOUS_ON_COMPONENTS_GEN", 12957 ``!f:real->real s. 12958 (!c. c IN components s 12959 ==> open_in (subtopology euclidean s) c /\ f continuous_on c) 12960 ==> f continuous_on s``, 12961 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN 12962 DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN 12963 SUBGOAL_THEN 12964 ``{x | x IN s /\ (f:real->real) x IN t} = 12965 BIGUNION {{x | x IN c /\ f x IN t} | c IN components s}`` 12966 SUBST1_TAC THENL 12967 [GEN_REWR_TAC LAND_CONV [METIS [BIGUNION_COMPONENTS] ``{x | x IN s /\ f x IN t} = 12968 {x | x IN BIGUNION (components s) /\ f x IN t}``] THEN 12969 SIMP_TAC std_ss [BIGUNION_GSPEC, IN_BIGUNION] THEN SET_TAC[], 12970 MATCH_MP_TAC OPEN_IN_BIGUNION THEN SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 12971 METIS_TAC[OPEN_IN_TRANS]]); 12972 12973val CONTINUOUS_ON_COMPONENTS_FINITE = store_thm ("CONTINUOUS_ON_COMPONENTS_FINITE", 12974 ``!f:real->real s. 12975 FINITE(components s) /\ 12976 (!c. c IN components s ==> f continuous_on c) 12977 ==> f continuous_on s``, 12978 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN 12979 DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN 12980 SUBGOAL_THEN 12981 ``{x | x IN s /\ (f:real->real) x IN t} = 12982 BIGUNION {{x | x IN c /\ f x IN t} | c IN components s}`` 12983 SUBST1_TAC THENL 12984 [GEN_REWR_TAC LAND_CONV [METIS [BIGUNION_COMPONENTS] ``{x | x IN s /\ f x IN t} = 12985 {x | x IN BIGUNION (components s) /\ f x IN t}``] THEN 12986 SIMP_TAC std_ss [BIGUNION_GSPEC, IN_BIGUNION] THEN SET_TAC[], 12987 MATCH_MP_TAC CLOSED_IN_BIGUNION THEN 12988 ASM_SIMP_TAC std_ss [GSYM IMAGE_DEF, IMAGE_FINITE, FORALL_IN_IMAGE] THEN 12989 METIS_TAC[CLOSED_IN_TRANS, CLOSED_IN_COMPONENT]]); 12990 12991val COMPONENTS_NONOVERLAP = store_thm ("COMPONENTS_NONOVERLAP", 12992 ``!s c c'. c IN components s /\ c' IN components s 12993 ==> ((c INTER c' = {}) <=> ~(c = c'))``, 12994 SIMP_TAC std_ss [components, GSPECIFICATION] THEN REPEAT STRIP_TAC THEN 12995 ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_NONOVERLAP]); 12996 12997val COMPONENTS_EQ = store_thm ("COMPONENTS_EQ", 12998 ``!s c c'. c IN components s /\ c' IN components s 12999 ==> ((c = c') <=> ~(c INTER c' = {}))``, 13000 MESON_TAC[COMPONENTS_NONOVERLAP]); 13001 13002val COMPONENTS_EQ_EMPTY = store_thm ("COMPONENTS_EQ_EMPTY", 13003 ``!s. (components s = {}) <=> (s = {})``, 13004 GEN_TAC THEN REWRITE_TAC[EXTENSION] THEN 13005 SIMP_TAC std_ss [components, connected_component, GSPECIFICATION] THEN 13006 SET_TAC[]); 13007 13008val COMPONENTS_EMPTY = store_thm ("COMPONENTS_EMPTY", 13009 ``components {} = {}``, 13010 REWRITE_TAC[COMPONENTS_EQ_EMPTY]); 13011 13012val CONNECTED_EQ_CONNECTED_COMPONENTS_EQ = store_thm ("CONNECTED_EQ_CONNECTED_COMPONENTS_EQ", 13013 ``!s. connected s <=> 13014 !c c'. c IN components s /\ c' IN components s ==> (c = c')``, 13015 SIMP_TAC std_ss [components, GSPECIFICATION] THEN 13016 MESON_TAC[CONNECTED_EQ_CONNECTED_COMPONENT_EQ]); 13017 13018val COMPONENTS_EQ_SING_N_EXISTS = store_thm ("COMPONENTS_EQ_SING_N_EXISTS", 13019 ``(!s:real->bool. (components s = {s}) <=> connected s /\ ~(s = {})) /\ 13020 (!s:real->bool. (?a. (components s = {a})) <=> connected s /\ ~(s = {}))``, 13021 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN X_GEN_TAC ``s:real->bool`` THEN 13022 MATCH_MP_TAC(TAUT `(p ==> q) /\ (q ==> r) /\ (r ==> p) 13023 ==> (p <=> r) /\ (q <=> r)`) THEN 13024 REPEAT CONJ_TAC THENL 13025 [MESON_TAC[], 13026 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENTS_EQ] THEN 13027 ASM_MESON_TAC[IN_SING, COMPONENTS_EQ_EMPTY, NOT_INSERT_EMPTY], 13028 STRIP_TAC THEN ONCE_REWRITE_TAC[EXTENSION] THEN 13029 REWRITE_TAC[IN_SING] THEN 13030 SIMP_TAC std_ss [components, GSPECIFICATION] THEN 13031 ASM_MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET, MEMBER_NOT_EMPTY]]); 13032 13033val COMPONENTS_EQ_SING = store_thm ("COMPONENTS_EQ_SING", 13034 ``(!s:real->bool. (components s = {s}) <=> connected s /\ ~(s = {}))``, 13035 REWRITE_TAC [COMPONENTS_EQ_SING_N_EXISTS]); 13036 13037val COMPONENTS_EQ_SING_EXISTS = store_thm ("COMPONENTS_EQ_SING_EXISTS", 13038 `` (!s:real->bool. (?a. (components s = {a})) <=> connected s /\ ~(s = {}))``, 13039 REWRITE_TAC [COMPONENTS_EQ_SING_N_EXISTS]); 13040 13041val COMPONENTS_UNIV = store_thm ("COMPONENTS_UNIV", 13042 ``components univ(:real) = {univ(:real)}``, 13043 REWRITE_TAC[COMPONENTS_EQ_SING, CONNECTED_UNIV, UNIV_NOT_EMPTY]); 13044 13045val CONNECTED_EQ_COMPONENTS_SUBSET_SING = store_thm ("CONNECTED_EQ_COMPONENTS_SUBSET_SING", 13046 ``!s:real->bool. connected s <=> components s SUBSET {s}``, 13047 GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 13048 ASM_REWRITE_TAC[COMPONENTS_EMPTY, CONNECTED_EMPTY, EMPTY_SUBSET] THEN 13049 REWRITE_TAC[SET_RULE ``s SUBSET {a} <=> (s = {}) \/ (s = {a})``] THEN 13050 ASM_REWRITE_TAC[COMPONENTS_EQ_EMPTY, COMPONENTS_EQ_SING]); 13051 13052val CONNECTED_EQ_COMPONENTS_SUBSET_SING_EXISTS = store_thm ("CONNECTED_EQ_COMPONENTS_SUBSET_SING_EXISTS", 13053 ``!s:real->bool. connected s <=> ?a. components s SUBSET {a}``, 13054 GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 13055 ASM_REWRITE_TAC[COMPONENTS_EMPTY, CONNECTED_EMPTY, EMPTY_SUBSET] THEN 13056 REWRITE_TAC[SET_RULE ``s SUBSET {a} <=> (s = {}) \/ (s = {a})``] THEN 13057 ASM_REWRITE_TAC[COMPONENTS_EQ_EMPTY, COMPONENTS_EQ_SING_EXISTS]); 13058 13059val IN_COMPONENTS_SELF = store_thm ("IN_COMPONENTS_SELF", 13060 ``!s:real->bool. s IN components s <=> connected s /\ ~(s = {})``, 13061 GEN_TAC THEN EQ_TAC THENL 13062 [MESON_TAC[IN_COMPONENTS_NONEMPTY, IN_COMPONENTS_CONNECTED], 13063 SIMP_TAC std_ss [GSYM COMPONENTS_EQ_SING, IN_SING]]); 13064 13065val COMPONENTS_MAXIMAL = store_thm ("COMPONENTS_MAXIMAL", 13066 ``!s t c:real->bool. 13067 c IN components s /\ connected t /\ t SUBSET s /\ ~(c INTER t = {}) 13068 ==> t SUBSET c``, 13069 SIMP_TAC std_ss [CONJ_EQ_IMP, components, FORALL_IN_GSPEC] THEN 13070 REPEAT STRIP_TAC THEN 13071 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 13072 SIMP_TAC std_ss [IN_INTER, LEFT_IMP_EXISTS_THM] THEN 13073 X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 13074 FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP CONNECTED_COMPONENT_EQ) THEN 13075 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]); 13076 13077val COMPONENTS_UNIQUE = store_thm ("COMPONENTS_UNIQUE", 13078 ``!s:real->bool k. 13079 (BIGUNION k = s) /\ 13080 (!c. c IN k 13081 ==> connected c /\ ~(c = {}) /\ 13082 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> (c' = c)) 13083 ==> (components s = k)``, 13084 REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN 13085 X_GEN_TAC ``c:real->bool`` THEN REWRITE_TAC[IN_COMPONENTS] THEN 13086 EQ_TAC THENL 13087 [DISCH_THEN(X_CHOOSE_THEN ``x:real`` 13088 (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN 13089 UNDISCH_TAC `` !c. c IN k ==> 13090 connected c /\ c <> {} /\ 13091 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> (c' = c)`` THEN DISCH_TAC THEN 13092 FIRST_ASSUM(MP_TAC o SPEC ``x:real`` o REWRITE_RULE [EXTENSION]) THEN 13093 REWRITE_TAC[IN_BIGUNION] THEN ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 13094 X_GEN_TAC ``c:real->bool`` THEN STRIP_TAC THEN 13095 SUBGOAL_THEN ``connected_component s (x:real) = c`` 13096 (fn th => ASM_REWRITE_TAC[th]) THEN 13097 MATCH_MP_TAC CONNECTED_COMPONENT_UNIQUE THEN 13098 FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN 13099 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 13100 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 13101 X_GEN_TAC ``c':real->bool`` THEN STRIP_TAC THEN 13102 REWRITE_TAC[SET_RULE ``c' SUBSET c <=> (c' UNION c = c)``] THEN 13103 FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL 13104 [MATCH_MP_TAC CONNECTED_UNION, ASM_SET_TAC[]] THEN 13105 ASM_SET_TAC[], 13106 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN 13107 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN 13108 UNDISCH_TAC ``c <> {}:real->bool`` THEN DISCH_TAC THEN 13109 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 13110 STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN 13111 CONJ_TAC THENL [ASM_SET_TAC[], CONV_TAC SYM_CONV] THEN 13112 FIRST_X_ASSUM MATCH_MP_TAC THEN 13113 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT, CONNECTED_COMPONENT_SUBSET] THEN 13114 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN 13115 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]]); 13116 13117val COMPONENTS_UNIQUE_EQ = store_thm ("COMPONENTS_UNIQUE_EQ", 13118 ``!s:real->bool k. 13119 (components s = k) <=> 13120 (BIGUNION k = s) /\ 13121 (!c. c IN k 13122 ==> connected c /\ ~(c = {}) /\ 13123 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> (c' = c))``, 13124 REPEAT GEN_TAC THEN EQ_TAC THENL 13125 [DISCH_THEN(SUBST1_TAC o SYM), REWRITE_TAC[COMPONENTS_UNIQUE]] THEN 13126 REWRITE_TAC[GSYM BIGUNION_COMPONENTS] THEN 13127 X_GEN_TAC ``c:real->bool`` THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL 13128 [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED], 13129 ASM_MESON_TAC[IN_COMPONENTS_NONEMPTY], 13130 RULE_ASSUM_TAC(REWRITE_RULE[IN_COMPONENTS_MAXIMAL]) THEN 13131 ASM_MESON_TAC[SUBSET_EMPTY]]); 13132 13133val EXISTS_COMPONENT_SUPERSET = store_thm ("EXISTS_COMPONENT_SUPERSET", 13134 ``!s t:real->bool. 13135 t SUBSET s /\ ~(s = {}) /\ connected t 13136 ==> ?c. c IN components s /\ t SUBSET c``, 13137 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``t:real->bool = {}`` THENL 13138 [ASM_REWRITE_TAC[EMPTY_SUBSET] THEN 13139 ASM_MESON_TAC[COMPONENTS_EQ_EMPTY, MEMBER_NOT_EMPTY], 13140 FIRST_X_ASSUM(X_CHOOSE_TAC ``a:real`` o 13141 REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 13142 EXISTS_TAC ``connected_component s (a:real)`` THEN 13143 REWRITE_TAC[IN_COMPONENTS] THEN CONJ_TAC THENL 13144 [ASM_SET_TAC[], ASM_MESON_TAC[CONNECTED_COMPONENT_MAXIMAL]]]); 13145 13146val COMPONENTS_INTERMEDIATE_SUBSET = store_thm ("COMPONENTS_INTERMEDIATE_SUBSET", 13147 ``!s t u:real->bool. 13148 s IN components u /\ s SUBSET t /\ t SUBSET u 13149 ==> s IN components t``, 13150 REPEAT GEN_TAC THEN SIMP_TAC std_ss [IN_COMPONENTS, GSYM LEFT_EXISTS_AND_THM] THEN 13151 MESON_TAC[CONNECTED_COMPONENT_INTERMEDIATE_SUBSET, SUBSET_DEF, 13152 CONNECTED_COMPONENT_REFL, IN_DEF, CONNECTED_COMPONENT_SUBSET]); 13153 13154val IN_COMPONENTS_BIGUNION_COMPLEMENT = store_thm ("IN_COMPONENTS_BIGUNION_COMPLEMENT", 13155 ``!s c:real->bool. 13156 c IN components s 13157 ==> (s DIFF c = BIGUNION(components s DELETE c))``, 13158 SIMP_TAC std_ss [components, FORALL_IN_GSPEC, 13159 COMPLEMENT_CONNECTED_COMPONENT_BIGUNION]); 13160 13161val CONNECTED_SUBSET_CLOPEN = store_thm ("CONNECTED_SUBSET_CLOPEN", 13162 ``!u s c:real->bool. 13163 closed_in (subtopology euclidean u) s /\ 13164 open_in (subtopology euclidean u) s /\ 13165 connected c /\ c SUBSET u /\ ~(c INTER s = {}) 13166 ==> c SUBSET s``, 13167 REPEAT STRIP_TAC THEN 13168 UNDISCH_TAC ``connected c`` THEN DISCH_TAC THEN 13169 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [CONNECTED_CLOSED_IN]) THEN 13170 SIMP_TAC std_ss [NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o 13171 SPECL [``c INTER s:real->bool``, ``c DIFF s:real->bool``]) THEN 13172 KNOW_TAC ``~((((closed_in (subtopology euclidean (c :real -> bool)) 13173 (c INTER (s :real -> bool)) /\ 13174 closed_in (subtopology euclidean c) (c DIFF s)) /\ 13175 (c SUBSET c INTER s UNION (c DIFF s))) /\ 13176 (c INTER s INTER (c DIFF s) = ({} :real -> bool))) /\ 13177 ~(c SUBSET s)) ==> c SUBSET s`` THENL 13178 [ALL_TAC, METIS_TAC [CONJ_ASSOC, SET_RULE ``(c DIFF s = {}) <=> c SUBSET s``]] THEN 13179 MATCH_MP_TAC(TAUT `p ==> ~(p /\ ~q) ==> q`) THEN 13180 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 13181 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 13182 CONJ_TAC THENL 13183 [UNDISCH_TAC ``closed_in (subtopology euclidean u) s`` THEN DISCH_TAC THEN 13184 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [CLOSED_IN_CLOSED]), 13185 UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN DISCH_TAC THEN 13186 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN])] THEN 13187 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 13188 REWRITE_TAC[OPEN_IN_OPEN, CLOSED_IN_CLOSED] THENL 13189 [EXISTS_TAC ``t:real->bool``, EXISTS_TAC ``univ(:real) DIFF t``] THEN 13190 ASM_REWRITE_TAC[GSYM OPEN_CLOSED] THEN ASM_SET_TAC[]); 13191 13192val CLOPEN_BIGUNION_COMPONENTS = store_thm ("CLOPEN_BIGUNION_COMPONENTS", 13193 ``!u s:real->bool. 13194 closed_in (subtopology euclidean u) s /\ 13195 open_in (subtopology euclidean u) s 13196 ==> ?k. k SUBSET components u /\ (s = BIGUNION k)``, 13197 REPEAT STRIP_TAC THEN 13198 EXISTS_TAC ``{c:real->bool | c IN components u /\ ~(c INTER s = {})}`` THEN 13199 SIMP_TAC std_ss [SUBSET_RESTRICT] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 13200 CONJ_TAC THENL 13201 [MP_TAC(ISPEC ``u:real->bool`` BIGUNION_COMPONENTS) THEN 13202 FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN SET_TAC[], 13203 SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_GSPEC] THEN 13204 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_SUBSET_CLOPEN THEN 13205 EXISTS_TAC ``u:real->bool`` THEN 13206 ASM_MESON_TAC[IN_COMPONENTS_CONNECTED, IN_COMPONENTS_SUBSET]]); 13207 13208val CLOPEN_IN_COMPONENTS = store_thm ("CLOPEN_IN_COMPONENTS", 13209 ``!u s:real->bool. 13210 closed_in (subtopology euclidean u) s /\ 13211 open_in (subtopology euclidean u) s /\ 13212 connected s /\ ~(s = {}) 13213 ==> s IN components u``, 13214 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[CONJ_ASSOC] THEN 13215 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 13216 FIRST_ASSUM(MP_TAC o MATCH_MP CLOPEN_BIGUNION_COMPONENTS) THEN 13217 DISCH_THEN(X_CHOOSE_THEN ``k:(real->bool)->bool`` STRIP_ASSUME_TAC) THEN 13218 ASM_CASES_TAC ``k:(real->bool)->bool = {}`` THEN 13219 ASM_REWRITE_TAC[BIGUNION_EMPTY] THEN 13220 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 13221 DISCH_THEN(X_CHOOSE_TAC ``c:real->bool``) THEN 13222 ASM_CASES_TAC ``k = {c:real->bool}`` THENL 13223 [METIS_TAC[BIGUNION_SING, GSYM SING_SUBSET], ALL_TAC] THEN 13224 MATCH_MP_TAC(TAUT `~p ==> p /\ q ==> r`) THEN 13225 SUBGOAL_THEN ``?c':real->bool. c' IN k /\ ~(c = c')`` STRIP_ASSUME_TAC THENL 13226 [ASM_MESON_TAC[SET_RULE 13227 ``a IN s /\ ~(s = {a}) ==> ?b. b IN s /\ ~(b = a)``], 13228 REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENTS_EQ] THEN 13229 DISCH_THEN(MP_TAC o SPECL [``c:real->bool``, ``c':real->bool``]) THEN 13230 ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THEN 13231 MATCH_MP_TAC COMPONENTS_INTERMEDIATE_SUBSET THEN 13232 EXISTS_TAC ``u:real->bool`` THEN 13233 MP_TAC(ISPEC ``u:real->bool`` BIGUNION_COMPONENTS) THEN ASM_SET_TAC[]]); 13234 13235(* ------------------------------------------------------------------------- *) 13236(* Continuity implies uniform continuity on a compact domain. *) 13237(* ------------------------------------------------------------------------- *) 13238 13239val COMPACT_UNIFORMLY_EQUICONTINUOUS = store_thm ("COMPACT_UNIFORMLY_EQUICONTINUOUS", 13240 ``!(fs:(real->real)->bool) s. 13241 (!x e. x IN s /\ &0 < e 13242 ==> ?d. &0 < d /\ 13243 (!f x'. f IN fs /\ x' IN s /\ dist (x',x) < d 13244 ==> dist (f x',f x) < e)) /\ 13245 compact s 13246 ==> !e. &0 < e 13247 ==> ?d. &0 < d /\ 13248 !f x x'. f IN fs /\ x IN s /\ x' IN s /\ dist (x',x) < d 13249 ==> dist(f x',f x) < e``, 13250 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 13251 DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 13252 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 13253 X_GEN_TAC ``d:real->real->real`` THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN 13254 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN 13255 DISCH_THEN(MP_TAC o SPEC 13256 ``{ ball(x:real,d x (e / &2:real)) | x IN s}``) THEN 13257 SIMP_TAC std_ss [FORALL_IN_GSPEC, OPEN_BALL, BIGUNION_GSPEC, SUBSET_DEF, GSPECIFICATION] THEN 13258 KNOW_TAC ``(!(x :real). 13259 x IN (s :real -> bool) ==> 13260 ?(x' :real). 13261 x' IN s /\ 13262 x IN 13263 ball 13264 (x', 13265 (d :real -> real -> real) x' 13266 ((e :real) / (2 :real))))`` THENL 13267 [ASM_MESON_TAC[CENTRE_IN_BALL, REAL_HALF], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 13268 DISCH_THEN (X_CHOOSE_TAC ``k:real``) THEN EXISTS_TAC ``k:real`` THEN 13269 POP_ASSUM MP_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 13270 MAP_EVERY X_GEN_TAC [``f:real->real``, ``u:real``, ``v:real``] THEN 13271 STRIP_TAC THEN FIRST_X_ASSUM(fn th => MP_TAC(SPEC ``v:real`` th) THEN 13272 ASM_REWRITE_TAC[] THEN DISCH_THEN(CHOOSE_THEN MP_TAC)) THEN 13273 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 13274 DISCH_THEN(fn th => 13275 MP_TAC(SPEC ``u:real`` th) THEN MP_TAC(SPEC ``v:real`` th)) THEN 13276 ASM_SIMP_TAC std_ss [DIST_REFL] THEN POP_ASSUM MP_TAC THEN 13277 DISCH_THEN (X_CHOOSE_TAC ``w:real``) THEN ASM_REWRITE_TAC [] THEN 13278 ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN ASM_REWRITE_TAC[IN_BALL] THEN 13279 ONCE_REWRITE_TAC[DIST_SYM] THEN REPEAT STRIP_TAC THEN 13280 FIRST_X_ASSUM(MP_TAC o SPECL [``w:real``, ``e / &2:real``]) THEN 13281 ASM_REWRITE_TAC[REAL_HALF] THEN 13282 DISCH_THEN(MP_TAC o SPEC ``f:real->real`` o CONJUNCT2) THEN 13283 DISCH_THEN(fn th => MP_TAC(SPEC ``u:real`` th) THEN 13284 MP_TAC(SPEC ``v:real`` th)) THEN 13285 ASM_REWRITE_TAC[] THEN GEN_REWR_TAC (LAND_CONV o LAND_CONV) [DIST_SYM] THEN 13286 REWRITE_TAC [dist] THEN GEN_REWR_TAC (RAND_CONV o RAND_CONV o RAND_CONV) [GSYM REAL_HALF] THEN 13287 REAL_ARITH_TAC); 13288 13289val COMPACT_UNIFORMLY_CONTINUOUS = store_thm ("COMPACT_UNIFORMLY_CONTINUOUS", 13290 ``!f:real->real s. 13291 f continuous_on s /\ compact s ==> f uniformly_continuous_on s``, 13292 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on, uniformly_continuous_on] THEN 13293 STRIP_TAC THEN 13294 MP_TAC(ISPECL [``{f:real->real}``, ``s:real->bool``] 13295 COMPACT_UNIFORMLY_EQUICONTINUOUS) THEN 13296 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM, CONJ_EQ_IMP, IN_SING, UNWIND_FORALL_THM2] THEN 13297 ASM_MESON_TAC[]); 13298 13299(* ------------------------------------------------------------------------- *) 13300(* A uniformly convergent limit of continuous functions is continuous. *) 13301(* ------------------------------------------------------------------------- *) 13302 13303val ABS_TRIANGLE_LE = store_thm ("ABS_TRIANGLE_LE", 13304 ``!x y. abs(x) + abs(y) <= e ==> abs(x + y) <= e:real``, 13305 METIS_TAC[REAL_LE_TRANS, ABS_TRIANGLE]); 13306 13307val CONTINUOUS_UNIFORM_LIMIT = store_thm ("CONTINUOUS_UNIFORM_LIMIT", 13308 ``!net f:'a->real->real g s. 13309 ~(trivial_limit net) /\ 13310 eventually (\n. (f n) continuous_on s) net /\ 13311 (!e. &0 < e 13312 ==> eventually (\n. !x. x IN s ==> abs(f n x - g x) < e) net) 13313 ==> g continuous_on s``, 13314 REWRITE_TAC[continuous_on] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN 13315 X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN 13316 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 13317 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &3:real``) THEN 13318 ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT] THEN 13319 UNDISCH_TAC ``eventually 13320 (\n. !x. x IN s ==> 13321 !e. 0 < e ==> 13322 ?d. 0 < d /\ 13323 !x'. x' IN s /\ dist (x',x) < d ==> 13324 dist (f n x',f n x) < e) net`` THEN DISCH_TAC THEN 13325 FIRST_X_ASSUM(fn th => MP_TAC th THEN REWRITE_TAC[AND_IMP_INTRO] THEN 13326 GEN_REWR_TAC LAND_CONV [GSYM EVENTUALLY_AND]) THEN 13327 DISCH_THEN(MP_TAC o MATCH_MP EVENTUALLY_HAPPENS) THEN 13328 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC ``a:'a`` THEN 13329 DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC ``x:real``) ASSUME_TAC) THEN 13330 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``e / &3:real``) THEN 13331 ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT] THEN 13332 DISCH_THEN (X_CHOOSE_TAC ``d:real``) THEN EXISTS_TAC ``d:real`` THEN 13333 POP_ASSUM MP_TAC THEN 13334 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN 13335 DISCH_TAC THEN X_GEN_TAC ``y:real`` THEN POP_ASSUM (MP_TAC o Q.SPEC `y:real`) THEN 13336 DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN 13337 FIRST_X_ASSUM(fn th => 13338 MP_TAC(SPEC ``x:real`` th) THEN MP_TAC(SPEC ``y:real`` th)) THEN 13339 ASM_REWRITE_TAC[] THEN SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN 13340 MATCH_MP_TAC(REAL_ARITH ``w <= x + y + z 13341 ==> x * &3 < e ==> y * &3 < e ==> z * &3 < e ==> w < e:real``) THEN 13342 REWRITE_TAC[dist] THEN 13343 SUBST1_TAC(REAL_ARITH 13344 ``(g:real->real) y - g x = 13345 -(f (a:'a) y - g y) + (f a x - g x) + (f a y - f a x)``) THEN 13346 MATCH_MP_TAC ABS_TRIANGLE_LE THEN SIMP_TAC std_ss [ABS_NEG, REAL_LE_LADD] THEN 13347 MATCH_MP_TAC REAL_LE_ADD2 THEN SIMP_TAC std_ss [REAL_LE_REFL] THEN 13348 MATCH_MP_TAC ABS_TRIANGLE_LE THEN REWRITE_TAC[ABS_NEG, REAL_LE_REFL]); 13349 13350(* ------------------------------------------------------------------------- *) 13351(* Topological stuff lifted from and dropped to R *) 13352(* ------------------------------------------------------------------------- *) 13353 13354val OPEN = store_thm ("OPEN", 13355 ``!s. open s <=> 13356 !x. x IN s ==> ?e. &0 < e /\ !x'. abs(x' - x) < e ==> x' IN s``, 13357 REWRITE_TAC[open_def, dist]); 13358 13359val CLOSED = store_thm ("LIMPT_APPROACHABLE", 13360 ``!s. closed s <=> 13361 !x. (!e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ abs(x' - x) < e) 13362 ==> x IN s``, 13363 SIMP_TAC std_ss [open_def, closed_def, dist, IN_DIFF, IN_UNIV] THEN 13364 SET_TAC []); 13365 13366val CONTINUOUS_AT_RANGE = store_thm ("CONTINUOUS_AT_RANGE", 13367 ``!f x. f continuous (at x) <=> 13368 !e. &0 < e 13369 ==> ?d. &0 < d /\ 13370 (!x'. abs(x' - x) < d 13371 ==> abs(f x' - f x) < e)``, 13372 REWRITE_TAC[continuous_at, o_THM, dist] THEN REWRITE_TAC[dist]); 13373 13374val CONTINUOUS_ON_RANGE = store_thm ("CONTINUOUS_ON_RANGE", 13375 ``!f s. f continuous_on s <=> 13376 !x. x IN s 13377 ==> !e. &0 < e 13378 ==> ?d. &0 < d /\ 13379 (!x'. x' IN s /\ abs(x' - x) < d 13380 ==> abs(f x' - f x) < e)``, 13381 REWRITE_TAC[continuous_on, o_THM, dist] THEN REWRITE_TAC[dist]); 13382 13383val CONTINUOUS_ABS_COMPOSE = store_thm ("CONTINUOUS_ABS_COMPOSE", 13384 ``!net f:'a->real. 13385 f continuous net 13386 ==> (\x. abs(f x)) continuous net``, 13387 REPEAT GEN_TAC THEN REWRITE_TAC[continuous, tendsto] THEN 13388 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN 13389 MATCH_MP_TAC MONO_IMP THEN 13390 REWRITE_TAC[] THEN 13391 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] EVENTUALLY_MONO) THEN 13392 SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 13393 13394val CONTINUOUS_ON_ABS_COMPOSE = store_thm ("CONTINUOUS_ON_ABS_COMPOSE", 13395 ``!f:real->real s. 13396 f continuous_on s 13397 ==> (\x. abs(f x)) continuous_on s``, 13398 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_ABS_COMPOSE]); 13399 13400val CONTINUOUS_AT_ABS = store_thm ("CONTINUOUS_AT_ABS", 13401 ``!x. abs continuous (at x)``, 13402 REWRITE_TAC[CONTINUOUS_AT_RANGE] THEN 13403 METIS_TAC [ABS_SUB_ABS, REAL_LET_TRANS]); 13404 13405val CONTINUOUS_AT_DIST = store_thm ("CONTINUOUS_AT_DIST", 13406 ``!a:real x. (\x. dist(a,x)) continuous (at x)``, 13407 REWRITE_TAC[CONTINUOUS_AT_RANGE, dist] THEN 13408 METIS_TAC[REAL_ARITH ``abs(abs(a:real - x) - abs(a - y)) <= abs(x - y)``, 13409 REAL_LET_TRANS]); 13410 13411val CONTINUOUS_ON_DIST = store_thm ("CONTINUOUS_ON_DIST", 13412 ``!a s. (\x. dist(a,x)) continuous_on s``, 13413 REWRITE_TAC[CONTINUOUS_ON_RANGE, dist] THEN 13414 METIS_TAC [REAL_ARITH ``abs(abs(a:real - x) - abs(a - y)) <= abs(x - y)``, 13415 REAL_LET_TRANS]); 13416 13417(* ------------------------------------------------------------------------- *) 13418(* Hence some handy theorems on distance, diameter etc. of/from a set. *) 13419(* ------------------------------------------------------------------------- *) 13420 13421val COMPACT_ATTAINS_SUP = store_thm ("COMPACT_ATTAINS_SUP", 13422 ``!s. compact s /\ ~(s = {}) 13423 ==> ?x. x IN s /\ !y. y IN s ==> y <= x``, 13424 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN 13425 MP_TAC(SPEC ``s:real->bool`` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN 13426 STRIP_TAC THEN EXISTS_TAC ``sup (s:real->bool)`` THEN ASM_SIMP_TAC std_ss [] THEN 13427 METIS_TAC [CLOSED, REAL_ARITH ``s <= s - e <=> ~(&0 < e:real)``, 13428 REAL_ARITH ``x <= s /\ ~(x <= s - e) ==> abs(x - s) < e:real``]); 13429 13430val COMPACT_ATTAINS_INF = store_thm ("COMPACT_ATTAINS_INF", 13431 ``!s. compact s /\ ~(s = {}) 13432 ==> ?x. x IN s /\ !y. y IN s ==> x <= y``, 13433 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN 13434 MP_TAC(SPEC ``s:real->bool`` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN 13435 STRIP_TAC THEN EXISTS_TAC ``inf (s:real->bool)`` THEN ASM_REWRITE_TAC[] THEN 13436 METIS_TAC[ CLOSED, REAL_ARITH ``s + e <= s <=> ~(&0 < e:real)``, 13437 REAL_ARITH ``s <= x /\ ~(s + e <= x) ==> abs(x - s) < e:real``]); 13438 13439val CONTINUOUS_ATTAINS_SUP = store_thm ("CONTINUOUS_ATTAINS_SUP", 13440 ``!f:real->real s. 13441 compact s /\ ~(s = {}) /\ (f) continuous_on s 13442 ==> ?x. x IN s /\ !y. y IN s ==> f(y) <= f(x)``, 13443 REPEAT STRIP_TAC THEN 13444 MP_TAC(SPEC ``IMAGE (f:real->real) s`` COMPACT_ATTAINS_SUP) THEN 13445 ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, COMPACT_CONTINUOUS_IMAGE, IMAGE_EQ_EMPTY] THEN 13446 MESON_TAC[IN_IMAGE]); 13447 13448val CONTINUOUS_ATTAINS_INF = store_thm ("CONTINUOUS_ATTAINS_INF", 13449 ``!f:real->real s. 13450 compact s /\ ~(s = {}) /\ (f) continuous_on s 13451 ==> ?x. x IN s /\ !y. y IN s ==> f(x) <= f(y)``, 13452 REPEAT STRIP_TAC THEN 13453 MP_TAC(SPEC ``IMAGE (f:real->real) s`` COMPACT_ATTAINS_INF) THEN 13454 ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, COMPACT_CONTINUOUS_IMAGE, IMAGE_EQ_EMPTY] THEN 13455 MESON_TAC[IN_IMAGE]); 13456 13457val DISTANCE_ATTAINS_SUP = store_thm ("DISTANCE_ATTAINS_SUP", 13458 ``!s a. compact s /\ ~(s = {}) 13459 ==> ?x. x IN s /\ !y. y IN s ==> dist(a,y) <= dist(a,x)``, 13460 REPEAT STRIP_TAC THEN 13461 ONCE_REWRITE_TAC [METIS [] ``dist (a,x) = (\x. dist (a,x)) x:real``] THEN 13462 MATCH_MP_TAC CONTINUOUS_ATTAINS_SUP THEN 13463 ASM_REWRITE_TAC[CONTINUOUS_ON_RANGE] THEN REWRITE_TAC[dist] THEN 13464 ASM_MESON_TAC[REAL_LET_TRANS, ABS_SUB_ABS, ABS_NEG, 13465 REAL_ARITH ``(a - x) - (a - y) = -(x - y):real``]); 13466 13467(* ------------------------------------------------------------------------- *) 13468(* For *minimal* distance, we only need closure, not compactness. *) 13469(* ------------------------------------------------------------------------- *) 13470 13471val DISTANCE_ATTAINS_INF = store_thm ("DISTANCE_ATTAINS_INF", 13472 ``!s a:real. 13473 closed s /\ ~(s = {}) 13474 ==> ?x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)``, 13475 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 13476 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN 13477 DISCH_THEN(X_CHOOSE_TAC ``b:real``) THEN 13478 MP_TAC(ISPECL [``\x:real. dist(a,x)``, ``cball(a:real,dist(b,a)) INTER s``] 13479 CONTINUOUS_ATTAINS_INF) THEN 13480 KNOW_TAC ``compact 13481 (cball ((a :real),(dist ((b :real),a) :real)) INTER 13482 (s :real -> bool)) /\ 13483 cball (a,(dist (b,a) :real)) INTER s <> ({} :real -> bool) /\ 13484 (\(x :real). (dist (a,x) :real)) continuous_on 13485 cball (a,(dist (b,a) :real)) INTER s`` THENL 13486 [ASM_SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_INTER, BOUNDED_INTER, 13487 BOUNDED_CBALL, CLOSED_CBALL, GSYM MEMBER_NOT_EMPTY] THEN 13488 SIMP_TAC std_ss [dist, CONTINUOUS_ON_RANGE, IN_INTER, IN_CBALL] THEN 13489 METIS_TAC[REAL_LET_TRANS, ABS_SUB_ABS, ABS_NEG, REAL_LE_REFL, 13490 ABS_SUB, REAL_ARITH ``(a - x) - (a - y) = -(x - y:real):real``], 13491 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 13492 DISCH_THEN (X_CHOOSE_TAC ``x:real``) THEN EXISTS_TAC ``x:real`` THEN 13493 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [IN_INTER, IN_CBALL] THEN 13494 METIS_TAC[DIST_SYM, REAL_LE_TOTAL, REAL_LE_TRANS]]); 13495 13496(* ------------------------------------------------------------------------- *) 13497(* We can now extend limit compositions to consider the scalar multiplier. *) 13498(* ------------------------------------------------------------------------- *) 13499 13500val LIM_MUL = store_thm ("LIM_MUL", 13501 ``!net:('a)net f l:real c d. 13502 (c --> d) net /\ (f --> l) net 13503 ==> ((\x. c(x) * f(x)) --> (d * l)) net``, 13504 REPEAT STRIP_TAC THEN 13505 MP_TAC(ISPECL [``net:('a)net``, ``\x y:real. x * y``, ``c:'a->real``, 13506 ``f:'a->real``, ``d:real``, ``l:real``] LIM_BILINEAR) THEN 13507 BETA_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_THEN MATCH_MP_TAC THEN 13508 REWRITE_TAC[bilinear, linear] THEN BETA_TAC THEN 13509 REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 13510 13511val LIM_VMUL = store_thm ("LIM_VMUL", 13512 ``!net:('a)net c d v:real. 13513 (c --> d) net ==> ((\x. c(x) * v) --> (d * v)) net``, 13514 REPEAT STRIP_TAC THEN 13515 KNOW_TAC ``(((\(x :'a). (c :'a -> real) x * (v :real)) --> 13516 ((d :real) * v)) (net :'a net)) = 13517 (((\(x :'a). (c :'a -> real) x * (\x. v :real) x) --> 13518 ((d :real) * v)) (net :'a net))`` THENL 13519 [SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 13520 MATCH_MP_TAC LIM_MUL THEN ASM_REWRITE_TAC[LIM_CONST]); 13521 13522val CONTINUOUS_VMUL = store_thm ("CONTINUOUS_VMUL", 13523 ``!net c v. c continuous net ==> (\x. c(x) * v) continuous net``, 13524 SIMP_TAC std_ss [continuous, LIM_VMUL, o_THM]); 13525 13526val CONTINUOUS_MUL = store_thm ("CONTINUOUS_MUL", 13527 ``!net f c. c continuous net /\ f continuous net 13528 ==> (\x. c(x) * f(x)) continuous net``, 13529 SIMP_TAC std_ss [continuous, LIM_MUL, o_THM]); 13530 13531val CONTINUOUS_ON_VMUL = store_thm ("CONTINUOUS_ON_VMUL", 13532 ``!s c v. c continuous_on s ==> (\x. c(x) * v) continuous_on s``, 13533 REWRITE_TAC [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 13534 SIMP_TAC std_ss [CONTINUOUS_VMUL]); 13535 13536val CONTINUOUS_ON_MUL = store_thm ("CONTINUOUS_ON_MUL", 13537 ``!s c f. c continuous_on s /\ f continuous_on s 13538 ==> (\x. c(x) * f(x)) continuous_on s``, 13539 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 13540 SIMP_TAC std_ss [CONTINUOUS_MUL]); 13541 13542val CONTINUOUS_POW = store_thm ("CONTINUOUS_POW", 13543 ``!net f:'a->real n. 13544 (\x. f x) continuous net 13545 ==> (\x. f x pow n) continuous net``, 13546 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN 13547 INDUCT_TAC THEN ASM_SIMP_TAC std_ss [pow, CONTINUOUS_CONST] THEN 13548 KNOW_TAC ``((\x:'a. f x * f x pow n) continuous net) = 13549 ((\x:'a. f x * (\x. f x pow n) x) continuous net)`` THENL 13550 [SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 13551 MATCH_MP_TAC CONTINUOUS_MUL THEN METIS_TAC [o_DEF, ETA_AX]); 13552 13553val CONTINUOUS_ON_POW = store_thm ("CONTINUOUS_ON_POW", 13554 ``!f:real->real s n. 13555 (\x. f x) continuous_on s 13556 ==> (\x. f x pow n) continuous_on s``, 13557 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN 13558 DISCH_TAC THEN INDUCT_TAC THEN 13559 ASM_SIMP_TAC std_ss[pow, CONTINUOUS_ON_CONST] THEN 13560 KNOW_TAC ``((\x. (f:real->real) x * f x pow n) continuous_on s:real->bool) = 13561 ((\x. f x * (\x. f x pow n) x) continuous_on s)`` THENL 13562 [SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 13563 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN METIS_TAC [o_DEF, ETA_AX]); 13564 13565val CONTINUOUS_PRODUCT = store_thm ("CONTINUOUS_PRODUCT", 13566 ``!net:('a)net f (t:'b->bool). 13567 FINITE t /\ 13568 (!i. i IN t ==> (\x. (f x i)) continuous net) 13569 ==> (\x. (product t (f x))) continuous net``, 13570 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[CONJ_EQ_IMP] THEN 13571 ONCE_REWRITE_TAC [METIS [] 13572 ``!t. ((!i. i IN t ==> (\x. f x i) continuous net) ==> 13573 (\x. product t (f x)) continuous net) = 13574 (\t. (!i. i IN t ==> (\x. f x i) continuous net) ==> 13575 (\x. product t (f x)) continuous net) t``] THEN 13576 MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN SIMP_TAC std_ss [PRODUCT_CLAUSES] THEN 13577 SIMP_TAC std_ss [CONTINUOUS_CONST, FORALL_IN_INSERT] THEN 13578 REPEAT STRIP_TAC THEN 13579 ONCE_REWRITE_TAC [METIS [] ``(\x. f x e * product s (f x)) = 13580 (\x. (\x. f x e) x * (\x. product s (f x)) x)``] THEN 13581 MATCH_MP_TAC CONTINUOUS_MUL THEN ASM_SIMP_TAC std_ss [o_DEF]); 13582 13583val CONTINUOUS_ON_PRODUCT = store_thm ("CONTINUOUS_ON_PRODUCT", 13584 ``!f:real->'a->real s t. 13585 FINITE t /\ 13586 (!i. i IN t ==> (\x. (f x i)) continuous_on s) 13587 ==> (\x. (product t (f x))) continuous_on s``, 13588 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_PRODUCT]); 13589 13590(* ------------------------------------------------------------------------- *) 13591(* And so we have continuity of inverse. *) 13592(* ------------------------------------------------------------------------- *) 13593 13594val LIM_INV = store_thm ("LIM_INV", 13595 ``!net:('a)net f l. 13596 (f --> l) net /\ ~(l = &0) 13597 ==> ((inv o f) --> (inv l)) net``, 13598 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN 13599 ASM_CASES_TAC ``trivial_limit(net:('a)net)`` THEN ASM_REWRITE_TAC[] THEN 13600 REWRITE_TAC[o_THM, dist] THEN STRIP_TAC THEN 13601 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 13602 FIRST_X_ASSUM(MP_TAC o SPEC ``min (abs(l) / &2) ((l pow 2 * e) / &2:real)``) THEN 13603 REWRITE_TAC[REAL_LT_MIN] THEN 13604 KNOW_TAC ``0 < abs l / 2 /\ 0 < l pow 2 * e / 2:real`` THENL 13605 [ASM_SIMP_TAC arith_ss [GSYM ABS_NZ, REAL_LT_DIV, REAL_LT] THEN 13606 MATCH_MP_TAC REAL_LT_DIV THEN SIMP_TAC arith_ss [REAL_LT] THEN 13607 ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN 13608 ASM_SIMP_TAC std_ss [REAL_LT_MUL, GSYM ABS_NZ, REAL_POW_LT], 13609 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 13610 DISCH_THEN (X_CHOOSE_TAC ``a:'a``) THEN EXISTS_TAC ``a:'a`` THEN 13611 POP_ASSUM MP_TAC THEN 13612 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN 13613 DISCH_TAC THEN X_GEN_TAC ``b:'a`` THEN POP_ASSUM (MP_TAC o Q.SPEC `b:'a`) THEN 13614 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN 13615 SIMP_TAC arith_ss [REAL_LT_RDIV_EQ, REAL_LT] THEN STRIP_TAC THEN 13616 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH 13617 ``abs(x - l) * &2 < abs l ==> ~(x = &0:real)``)) THEN 13618 ASM_SIMP_TAC std_ss [REAL_SUB_INV2, ABS_DIV, REAL_LT_LDIV_EQ, 13619 GSYM ABS_NZ, REAL_ENTIRE] THEN 13620 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH 13621 ``abs(x - y) * &2 < b * c ==> c * b <= d * &2 ==> abs(y - x) < d:real``)) THEN 13622 ASM_SIMP_TAC std_ss [GSYM REAL_MUL_ASSOC, REAL_LE_LMUL] THEN 13623 ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN 13624 ASM_SIMP_TAC std_ss [ABS_MUL, POW_2, REAL_MUL_ASSOC, GSYM ABS_NZ, 13625 REAL_LE_RMUL] THEN 13626 ASM_SIMP_TAC std_ss [REAL_ARITH ``abs(x - y) * &2 < abs y ==> abs y <= &2 * abs x:real``]); 13627 13628val CONTINUOUS_INV = store_thm ("CONTINUOUS_INV", 13629 ``!net f. f continuous net /\ ~(f(netlimit net) = &0) 13630 ==> (inv o f) continuous net``, 13631 SIMP_TAC std_ss [continuous, LIM_INV, o_THM]); 13632 13633val CONTINUOUS_AT_WITHIN_INV = store_thm ("CONTINUOUS_AT_WITHIN_INV", 13634 ``!f s a:real. 13635 f continuous (at a within s) /\ ~(f a = &0) 13636 ==> (inv o f) continuous (at a within s)``, 13637 REPEAT GEN_TAC THEN 13638 ASM_CASES_TAC ``trivial_limit (at (a:real) within s)`` THENL 13639 [ASM_REWRITE_TAC[continuous, LIM], 13640 ASM_SIMP_TAC std_ss [NETLIMIT_WITHIN, CONTINUOUS_INV]]); 13641 13642val CONTINUOUS_AT_INV = store_thm ("CONTINUOUS_AT_INV", 13643 ``!f a. f continuous at a /\ ~(f a = &0) 13644 ==> (inv o f) continuous at a``, 13645 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN 13646 REWRITE_TAC[CONTINUOUS_AT_WITHIN_INV]); 13647 13648val CONTINUOUS_ON_INV = store_thm ("CONTINUOUS_ON_INV", 13649 ``!f s. f continuous_on s /\ (!x. x IN s ==> ~(f x = &0)) 13650 ==> (inv o f) continuous_on s``, 13651 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_AT_WITHIN_INV]); 13652 13653(* ------------------------------------------------------------------------- *) 13654(* Hence some useful properties follow quite easily. *) 13655(* ------------------------------------------------------------------------- *) 13656 13657val CONNECTED_SCALING = store_thm ("CONNECTED_SCALING", 13658 ``!s:real->bool c. connected s ==> connected (IMAGE (\x. c * x) s)``, 13659 REPEAT STRIP_TAC THEN 13660 MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 13661 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 13662 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN 13663 REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 13664 13665val CONNECTED_NEGATIONS = store_thm ("CONNECTED_NEGATIONS", 13666 ``!s:real->bool. connected s ==> connected (IMAGE (\x. -x) s)``, 13667 REPEAT STRIP_TAC THEN 13668 MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 13669 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 13670 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN 13671 REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 13672 13673val COMPACT_SCALING = store_thm ("COMPACT_SCALING", 13674 ``!s:real->bool c. compact s ==> compact (IMAGE (\x. c * x) s)``, 13675 REPEAT STRIP_TAC THEN 13676 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 13677 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 13678 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN 13679 REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 13680 13681val COMPACT_NEGATIONS = store_thm ("COMPACT_NEGATIONS", 13682 ``!s:real->bool. compact s ==> compact (IMAGE (\x. -x) s)``, 13683 REPEAT STRIP_TAC THEN 13684 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 13685 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 13686 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN 13687 REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 13688 13689val COMPACT_AFFINITY = store_thm ("COMPACT_AFFINITY", 13690 ``!s a:real c. 13691 compact s ==> compact (IMAGE (\x. a + c * x) s)``, 13692 REPEAT STRIP_TAC THEN 13693 SUBGOAL_THEN ``(\x:real. a + c * x) = (\x. a + x) o (\x. c * x)`` 13694 SUBST1_TAC THENL [REWRITE_TAC[o_DEF], ALL_TAC] THEN 13695 ASM_SIMP_TAC std_ss [IMAGE_COMPOSE, COMPACT_TRANSLATION, COMPACT_SCALING]); 13696 13697(* ------------------------------------------------------------------------- *) 13698(* We can state this in terms of diameter of a set. *) 13699(* ------------------------------------------------------------------------- *) 13700 13701val diameter = new_definition ("diameter", 13702 ``diameter s = 13703 if s = {} then (&0:real) 13704 else sup {abs(x - y) | x IN s /\ y IN s}``); 13705 13706val DIAMETER_BOUNDED = store_thm ("DIAMETER_BOUNDED", 13707 ``!s. bounded s 13708 ==> (!x:real y. x IN s /\ y IN s ==> abs(x - y) <= diameter s) /\ 13709 (!d. &0 <= d /\ d < diameter s 13710 ==> ?x y. x IN s /\ y IN s /\ abs(x - y) > d)``, 13711 GEN_TAC THEN DISCH_TAC THEN 13712 ASM_CASES_TAC ``s:real->bool = {}`` THEN 13713 ASM_REWRITE_TAC[diameter, NOT_IN_EMPTY, REAL_LET_ANTISYM] THENL 13714 [SIMP_TAC std_ss [REAL_NOT_LE, REAL_NOT_LT, REAL_LTE_TOTAL], ALL_TAC] THEN 13715 MP_TAC(SPEC ``{abs(x - y:real) | x IN s /\ y IN s}`` SUP) THEN 13716 ABBREV_TAC ``b = sup {abs(x - y:real) | x IN s /\ y IN s}`` THEN 13717 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 13718 REWRITE_TAC[NOT_IN_EMPTY, real_gt] THEN 13719 KNOW_TAC ``(?(x :real) (p_1 :real) (p_2 :real). 13720 (x = abs (p_1 - p_2)) /\ p_1 IN (s :real -> bool) /\ p_2 IN s) /\ 13721 (?(b :real). 13722 !(x :real). 13723 (?(p_1 :real) (p_2 :real). 13724 (x = abs (p_1 - p_2)) /\ p_1 IN s /\ p_2 IN s) ==> 13725 x <= b)`` THENL 13726 [CONJ_TAC THENL [METIS_TAC[MEMBER_NOT_EMPTY], ALL_TAC], 13727 METIS_TAC[REAL_NOT_LE]] THEN 13728 SIMP_TAC std_ss [REAL_SUB, LEFT_IMP_EXISTS_THM] THEN 13729 UNDISCH_TAC ``bounded s`` THEN DISCH_TAC THEN 13730 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [bounded_def]) THEN 13731 REWRITE_TAC [real_sub] THEN 13732 METIS_TAC [REAL_ARITH ``x <= y + z /\ y <= b /\ z <= b ==> x <= b + b:real``, 13733 ABS_TRIANGLE, ABS_NEG]); 13734 13735val DIAMETER_BOUNDED_BOUND = store_thm ("DIAMETER_BOUNDED_BOUND", 13736 ``!s x y. bounded s /\ x IN s /\ y IN s ==> abs(x - y) <= diameter s``, 13737 MESON_TAC[DIAMETER_BOUNDED]); 13738 13739val DIAMETER_LINEAR_IMAGE = store_thm ("DIAMETER_LINEAR_IMAGE", 13740 ``!f:real->real s. 13741 linear f /\ (!x. abs(f x) = abs x) 13742 ==> (diameter(IMAGE f s) = diameter s)``, 13743 REWRITE_TAC[diameter] THEN 13744 REPEAT STRIP_TAC THEN REWRITE_TAC[diameter, IMAGE_EQ_EMPTY] THEN 13745 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN 13746 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 13747 ONCE_REWRITE_TAC [CONJ_SYM] THEN 13748 SIMP_TAC std_ss [GSYM CONJ_ASSOC, RIGHT_EXISTS_AND_THM, EXISTS_IN_IMAGE] THEN 13749 METIS_TAC[LINEAR_SUB]); 13750 13751val DIAMETER_EMPTY = store_thm ("DIAMETER_EMPTY", 13752 ``diameter {} = &0``, 13753 REWRITE_TAC[diameter]); 13754 13755val DIAMETER_SING = store_thm ("DIAMETER_SING", 13756 ``!a. diameter {a} = &0``, 13757 REWRITE_TAC[diameter, NOT_INSERT_EMPTY, IN_SING] THEN 13758 ONCE_REWRITE_TAC [METIS [] ``abs (x - y:real) = (\x y. abs (x - y:real)) x y``] THEN 13759 KNOW_TAC ``!a:real f x:real y:real. {f x y | (x = a) /\ (y = a)} = {(f a a):real }`` THENL 13760 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, IN_SING], 13761 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 13762 SIMP_TAC std_ss [REAL_SUB_REFL, ABS_0] THEN 13763 MATCH_MP_TAC REAL_SUP_UNIQUE THEN REWRITE_TAC [METIS [SPECIFICATION] ``{0:real} x = x IN {0}``] THEN 13764 SET_TAC [REAL_LE_LT]); 13765 13766val DIAMETER_POS_LE = store_thm ("DIAMETER_POS_LE", 13767 ``!s:real->bool. bounded s ==> &0 <= diameter s``, 13768 REPEAT STRIP_TAC THEN REWRITE_TAC[diameter] THEN 13769 COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN 13770 MP_TAC(SPEC ``{abs(x - y:real) | x IN s /\ y IN s}`` SUP) THEN 13771 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 13772 KNOW_TAC ``{abs (x - y) | x IN (s :real -> bool) /\ y IN s} <> 13773 ({} :real -> bool) /\ (?(b :real). 13774 !(x :real) (y :real). x IN s /\ y IN s ==> abs (x - y) <= b)`` THENL 13775 [CONJ_TAC THENL [FULL_SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, 13776 EXISTS_PROD, NOT_IN_EMPTY] THEN METIS_TAC [MEMBER_NOT_EMPTY], ALL_TAC] THEN 13777 UNDISCH_TAC ``bounded s`` THEN DISCH_TAC THEN 13778 FIRST_X_ASSUM(X_CHOOSE_TAC ``B:real`` o REWRITE_RULE [BOUNDED_POS]) THEN 13779 EXISTS_TAC ``&2 * B:real`` THEN 13780 ASM_SIMP_TAC std_ss [REAL_ARITH 13781 ``abs x <= B /\ abs y <= B ==> abs(x - y) <= &2 * B:real``], 13782 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 13783 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 13784 DISCH_THEN(X_CHOOSE_TAC ``a:real``) THEN 13785 DISCH_THEN(MP_TAC o SPECL [``a:real``, ``a:real``] o CONJUNCT1) THEN 13786 ASM_REWRITE_TAC[REAL_SUB_REFL, ABS_0]]); 13787 13788val DIAMETER_SUBSET = store_thm ("DIAMETER_SUBSET", 13789 ``!s t:real->bool. s SUBSET t /\ bounded t ==> diameter s <= diameter t``, 13790 REPEAT STRIP_TAC THEN 13791 ASM_CASES_TAC ``s:real->bool = {}`` THEN 13792 ASM_SIMP_TAC std_ss [DIAMETER_EMPTY, DIAMETER_POS_LE] THEN 13793 ASM_REWRITE_TAC[diameter] THEN 13794 COND_CASES_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 13795 MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN 13796 REPEAT(CONJ_TAC THENL 13797 [FULL_SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, SUBSET_DEF, 13798 EXISTS_PROD, NOT_IN_EMPTY] THEN METIS_TAC [MEMBER_NOT_EMPTY], ALL_TAC]) THEN 13799 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 13800 UNDISCH_TAC ``bounded t`` THEN DISCH_TAC THEN 13801 FIRST_X_ASSUM(X_CHOOSE_TAC ``B:real`` o REWRITE_RULE [BOUNDED_POS]) THEN 13802 EXISTS_TAC ``&2 * B:real`` THEN 13803 ASM_SIMP_TAC std_ss [REAL_ARITH 13804 ``abs x <= B /\ abs y <= B ==> abs(x - y) <= &2 * B:real``]); 13805 13806val DIAMETER_CLOSURE = store_thm ("DIAMETER_CLOSURE", 13807 ``!s:real->bool. bounded s ==> (diameter(closure s) = diameter s)``, 13808 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN REPEAT STRIP_TAC THEN 13809 ASM_SIMP_TAC std_ss [DIAMETER_SUBSET, BOUNDED_CLOSURE, CLOSURE_SUBSET] THEN 13810 REWRITE_TAC[GSYM REAL_NOT_LT] THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN 13811 DISCH_TAC THEN MP_TAC(ISPEC ``closure s:real->bool`` DIAMETER_BOUNDED) THEN 13812 ABBREV_TAC ``d = diameter(closure s) - diameter(s:real->bool)`` THEN 13813 ASM_SIMP_TAC std_ss [BOUNDED_CLOSURE] THEN 13814 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 13815 POP_ASSUM (MP_TAC o 13816 SPEC ``diameter(closure(s:real->bool)) - d / &2:real``) THEN 13817 SIMP_TAC std_ss [NOT_IMP, GSYM CONJ_ASSOC, NOT_EXISTS_THM] THEN 13818 ONCE_REWRITE_TAC [SET_RULE ``(x:real) NOTIN y = ~(x IN y)``, GSYM DE_MORGAN_THM] THEN 13819 ONCE_REWRITE_TAC [SET_RULE ``(x:real) NOTIN y = ~(x IN y)``, GSYM DE_MORGAN_THM] THEN 13820 FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIAMETER_POS_LE) THEN 13821 CONJ_TAC THENL 13822 [SIMP_TAC std_ss [REAL_SUB_LE, REAL_LE_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 13823 EXPAND_TAC "d" THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 13824 SIMP_TAC std_ss [GSYM REAL_DOUBLE, real_sub] THEN 13825 MATCH_MP_TAC REAL_LE_ADD2 THEN SIMP_TAC std_ss [REAL_LE_REFL] THEN 13826 FULL_SIMP_TAC std_ss [REAL_ARITH ``(a - b = c) = (a = c + b:real)``] THEN 13827 ONCE_REWRITE_TAC [GSYM REAL_SUB_LE] THEN 13828 REWRITE_TAC [REAL_ARITH ``0 < a + b - -c = 0 + 0 < a + (b + c):real``, REAL_LE_LT] THEN 13829 DISJ1_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC [] THEN 13830 ONCE_REWRITE_TAC [REAL_ARITH ``0 = 0 + 0:real``] THEN 13831 MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC [], ALL_TAC] THEN 13832 CONJ_TAC THENL 13833 [ONCE_REWRITE_TAC [REAL_ARITH ``a - b < c = a - c < b:real``] THEN 13834 SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 13835 ASM_REWRITE_TAC [REAL_SUB_REFL, REAL_MUL_LZERO], ALL_TAC] THEN 13836 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN 13837 SIMP_TAC std_ss [CLOSURE_APPROACHABLE, CONJ_ASSOC, GSYM FORALL_AND_THM] THEN 13838 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 13839 UNDISCH_TAC ``!e. ~(0 < e) \/ ?y'. y' IN s /\ dist (y',y) < e:real`` THEN DISCH_TAC THEN 13840 POP_ASSUM (MP_TAC o Q.SPEC `d / 4:real`) THEN 13841 UNDISCH_TAC ``!e. ~(0 < e) \/ ?y. y IN s /\ dist (y,x) < e:real`` THEN DISCH_TAC THEN 13842 POP_ASSUM (MP_TAC o Q.SPEC `d / 4:real`) THEN REWRITE_TAC [AND_IMP_INTRO] THEN 13843 ASM_REWRITE_TAC[METIS [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 4:real``, REAL_MUL_LZERO] 13844 ``&0 < d / &4 <=> &0 < d:real``] THEN 13845 DISCH_THEN(CONJUNCTS_THEN2 13846 (X_CHOOSE_THEN ``u:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) 13847 (X_CHOOSE_THEN ``v:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))) THEN 13848 FIRST_ASSUM(MP_TAC o MATCH_MP DIAMETER_BOUNDED) THEN 13849 DISCH_THEN(MP_TAC o SPECL [``u:real``, ``v:real``] o CONJUNCT1) THEN 13850 ASM_REWRITE_TAC[dist] THEN 13851 RULE_ASSUM_TAC (REWRITE_RULE [real_gt]) THEN 13852 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``a - b < c = a - c < b:real``]) THEN 13853 RULE_ASSUM_TAC (SIMP_RULE std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``]) THEN 13854 UNDISCH_TAC `` (diameter (closure s) - abs (x - y)) * 2 < d:real`` THEN 13855 EXPAND_TAC "d" THEN SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 4:real``] THEN 13856 REAL_ARITH_TAC); 13857 13858val DIAMETER_SUBSET_CBALL_NONEMPTY = store_thm ("DIAMETER_SUBSET_CBALL_NONEMPTY", 13859 ``!s:real->bool. 13860 bounded s /\ ~(s = {}) ==> ?z. z IN s /\ s SUBSET cball(z,diameter s)``, 13861 REPEAT STRIP_TAC THEN 13862 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 13863 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 13864 ASM_REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``b:real`` THEN 13865 DISCH_TAC THEN REWRITE_TAC[IN_CBALL, dist] THEN 13866 ASM_MESON_TAC[DIAMETER_BOUNDED]); 13867 13868val DIAMETER_SUBSET_CBALL = store_thm ("DIAMETER_SUBSET_CBALL", 13869 ``!s:real->bool. bounded s ==> ?z. s SUBSET cball(z,diameter s)``, 13870 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 13871 ASM_MESON_TAC[DIAMETER_SUBSET_CBALL_NONEMPTY, EMPTY_SUBSET]); 13872 13873val DIAMETER_EQ_0 = store_thm ("DIAMETER_EQ_0", 13874 ``!s:real->bool. 13875 bounded s ==> ((diameter s = &0) <=> (s = {}) \/ ?a. (s = {a}))``, 13876 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THEN 13877 ASM_REWRITE_TAC[DIAMETER_EMPTY, DIAMETER_SING] THEN 13878 REWRITE_TAC[SET_RULE 13879 ``(s = {}) \/ (?a. s = {a}) <=> !a b. a IN s /\ b IN s ==> (a = b)``] THEN 13880 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN STRIP_TAC THEN 13881 MP_TAC(ISPECL [``s:real->bool``, ``a:real``, ``b:real``] 13882 DIAMETER_BOUNDED_BOUND) THEN 13883 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC); 13884 13885val DIAMETER_LE = store_thm ("DIAMETER_LE", 13886 ``!s:real->bool d. 13887 (~(s = {}) \/ &0 <= d) /\ 13888 (!x y. x IN s /\ y IN s ==> abs(x - y) <= d) ==> diameter s <= d``, 13889 NTAC 2 GEN_TAC THEN REWRITE_TAC[diameter] THEN 13890 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [] THEN 13891 STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_LE_S THEN 13892 CONJ_TAC THENL [ 13893 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[], 13894 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC []]); 13895 13896val DIAMETER_CBALL = store_thm ("DIAMETER_CBALL", 13897 ``!a:real r. diameter(cball(a,r)) = if r < &0 then &0 else &2 * r``, 13898 REPEAT GEN_TAC THEN COND_CASES_TAC THENL 13899 [ASM_MESON_TAC[CBALL_EQ_EMPTY, DIAMETER_EMPTY], ALL_TAC] THEN 13900 RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT]) THEN 13901 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL 13902 [MATCH_MP_TAC DIAMETER_LE THEN 13903 ASM_SIMP_TAC std_ss [CBALL_EQ_EMPTY, REAL_LE_MUL, REAL_POS, REAL_NOT_LT] THEN 13904 REWRITE_TAC[IN_CBALL, dist] THEN REAL_ARITH_TAC, 13905 MATCH_MP_TAC REAL_LE_TRANS THEN 13906 EXISTS_TAC ``abs((a + r) - (a - r):real)`` THEN 13907 CONJ_TAC THENL 13908 [REWRITE_TAC[REAL_ARITH ``(a + r) - (a - r) = (&2 * r:real)``] THEN 13909 ASM_REAL_ARITH_TAC, 13910 MATCH_MP_TAC DIAMETER_BOUNDED_BOUND THEN 13911 REWRITE_TAC[BOUNDED_CBALL, IN_CBALL, dist] THEN 13912 REWRITE_TAC[REAL_ARITH 13913 ``(abs(a - (a + b)) = abs b) /\ (abs(a - (a - b)) = abs b:real)``] THEN 13914 ASM_REAL_ARITH_TAC]]); 13915 13916val DIAMETER_BALL = store_thm ("DIAMETER_BALL", 13917 ``!a:real r. diameter(ball(a,r)) = if r < &0 then &0 else &2 * r``, 13918 REPEAT GEN_TAC THEN COND_CASES_TAC THENL 13919 [ASM_SIMP_TAC std_ss [BALL_EMPTY, REAL_LT_IMP_LE, DIAMETER_EMPTY], ALL_TAC] THEN 13920 ASM_CASES_TAC ``r = &0:real`` THEN 13921 ASM_SIMP_TAC std_ss [BALL_EMPTY, REAL_LE_REFL, DIAMETER_EMPTY, REAL_MUL_RZERO] THEN 13922 MATCH_MP_TAC EQ_TRANS THEN 13923 EXISTS_TAC ``diameter(cball(a:real,r))`` THEN CONJ_TAC THENL 13924 [SUBGOAL_THEN ``&0 < r:real`` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC, ALL_TAC] THEN 13925 ASM_SIMP_TAC std_ss [GSYM CLOSURE_BALL, DIAMETER_CLOSURE, BOUNDED_BALL], 13926 ASM_SIMP_TAC std_ss [DIAMETER_CBALL]]); 13927 13928val DIAMETER_SUMS = store_thm ("DIAMETER_SUMS", 13929 ``!s t:real->bool. 13930 bounded s /\ bounded t 13931 ==> diameter {x + y | x IN s /\ y IN t} <= diameter s + diameter t``, 13932 REPEAT STRIP_TAC THEN 13933 KNOW_TAC ``!x y:real. {x + y| F} = {}:real->bool`` THENL 13934 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN SET_TAC [], DISCH_TAC] THEN 13935 ASM_CASES_TAC ``s:real->bool = {}`` THEN 13936 ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, DIAMETER_EMPTY, REAL_ADD_LID, DIAMETER_POS_LE] THEN 13937 ASM_CASES_TAC ``t:real->bool = {}`` THEN 13938 ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, DIAMETER_EMPTY, REAL_ADD_RID, DIAMETER_POS_LE] THEN 13939 MATCH_MP_TAC DIAMETER_LE THEN CONJ_TAC THENL 13940 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, NOT_IN_EMPTY] THEN 13941 ASM_SET_TAC [], ALL_TAC] THEN 13942 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM, CONJ_EQ_IMP, FORALL_IN_GSPEC] THEN 13943 REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH 13944 ``abs(x - x') <= s /\ abs(y - y') <= t 13945 ==> abs((x + y) - (x' + y'):real) <= s + t``) THEN 13946 ASM_SIMP_TAC std_ss [DIAMETER_BOUNDED_BOUND]); 13947 13948val LEBESGUE_COVERING_LEMMA = store_thm ("LEBESGUE_COVERING_LEMMA", 13949 ``!s:real->bool c. 13950 compact s /\ ~(c = {}) /\ s SUBSET BIGUNION c /\ (!b. b IN c ==> open b) 13951 ==> ?d. &0 < d /\ 13952 !t. t SUBSET s /\ diameter t <= d 13953 ==> ?b. b IN c /\ t SUBSET b``, 13954 REPEAT STRIP_TAC THEN 13955 FIRST_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN 13956 DISCH_THEN(MP_TAC o SPEC ``c:(real->bool)->bool``) THEN ASM_SIMP_TAC std_ss [] THEN 13957 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC ``e:real`` THEN 13958 STRIP_TAC THEN EXISTS_TAC ``e / &2:real`` THEN ASM_REWRITE_TAC[REAL_HALF] THEN 13959 X_GEN_TAC ``t:real->bool`` THEN STRIP_TAC THEN 13960 ASM_CASES_TAC ``t:real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN 13961 MP_TAC(ISPEC ``t:real->bool`` DIAMETER_SUBSET_CBALL_NONEMPTY) THEN 13962 KNOW_TAC ``(bounded (t :real -> bool) :bool) /\ t <> ({} :real -> bool)`` THENL 13963 [ASM_MESON_TAC[BOUNDED_SUBSET, COMPACT_IMP_BOUNDED], 13964 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 13965 DISCH_THEN(X_CHOOSE_THEN ``x:real`` STRIP_ASSUME_TAC) THEN 13966 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN 13967 KNOW_TAC ``(x :real) IN (s :real -> bool)`` THENL 13968 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 13969 DISCH_THEN (X_CHOOSE_TAC ``b:real->bool``) THEN EXISTS_TAC ``b:real->bool`` THEN 13970 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN 13971 EXISTS_TAC ``cball(x:real,diameter(t:real->bool))`` THEN 13972 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN 13973 EXISTS_TAC ``ball(x:real,e)`` THEN ASM_REWRITE_TAC[] THEN 13974 REWRITE_TAC[SUBSET_DEF, IN_CBALL, IN_BALL] THEN 13975 MAP_EVERY UNDISCH_TAC [``&0 < e:real``, ``diameter(t:real->bool) <= e / &2:real``] THEN 13976 SIMP_TAC std_ss [dist, REAL_LE_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN REAL_ARITH_TAC); 13977 13978(* ------------------------------------------------------------------------- *) 13979(* Related results with closure as the conclusion. *) 13980(* ------------------------------------------------------------------------- *) 13981 13982val CLOSED_SCALING = store_thm ("CLOSED_SCALING", 13983 ``!s:real->bool c. closed s ==> closed (IMAGE (\x. c * x) s)``, 13984 REPEAT GEN_TAC THEN 13985 ASM_CASES_TAC ``s :real->bool = {}`` THEN 13986 ASM_REWRITE_TAC[CLOSED_EMPTY, IMAGE_EMPTY, IMAGE_INSERT] THEN 13987 ASM_CASES_TAC ``c = &0:real`` THENL 13988 [SUBGOAL_THEN ``IMAGE (\x:real. c * x) s = {(0)}`` 13989 (fn th => REWRITE_TAC[th, CLOSED_SING]) THEN 13990 ASM_REWRITE_TAC[EXTENSION, IN_IMAGE, IN_SING, REAL_MUL_LZERO] THEN 13991 ASM_MESON_TAC[MEMBER_NOT_EMPTY], 13992 ALL_TAC] THEN 13993 SIMP_TAC std_ss [CLOSED_SEQUENTIAL_LIMITS, IN_IMAGE, SKOLEM_THM] THEN 13994 STRIP_TAC THEN X_GEN_TAC ``x:num->real`` THEN X_GEN_TAC ``l:real`` THEN 13995 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 13996 DISCH_THEN(X_CHOOSE_THEN ``y:num->real`` MP_TAC) THEN 13997 SIMP_TAC std_ss [FORALL_AND_THM] THEN STRIP_TAC THEN 13998 EXISTS_TAC ``inv(c) * l :real`` THEN 13999 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_MUL_LID] THEN 14000 FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC ``\n:num. inv(c) * x n:real`` THEN 14001 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THENL 14002 [ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID], 14003 ONCE_REWRITE_TAC [METIS [] ``(\n:num. inv c * (c * (y:num->real) n)) = 14004 (\n. inv c:real * (\n. (c * y n)) n)``] THEN 14005 MATCH_MP_TAC LIM_CMUL THEN 14006 FIRST_ASSUM(fn th => REWRITE_TAC[SYM(SPEC_ALL th)]) THEN 14007 ASM_SIMP_TAC std_ss [ETA_AX]]); 14008 14009val CLOSED_NEGATIONS = store_thm ("CLOSED_NEGATIONS", 14010 ``!s:real->bool. closed s ==> closed (IMAGE (\x. -x) s)``, 14011 REPEAT GEN_TAC THEN 14012 SUBGOAL_THEN ``IMAGE (\x. -x) s = IMAGE (\x:real. -(&1) * x) s`` 14013 SUBST1_TAC THEN SIMP_TAC std_ss [CLOSED_SCALING] THEN 14014 REWRITE_TAC[REAL_ARITH ``-(&1) * x = -x:real``] THEN SIMP_TAC std_ss [ETA_AX]); 14015 14016val COMPACT_CLOSED_SUMS = store_thm ("COMPACT_CLOSED_SUMS", 14017 ``!s:real->bool t. 14018 compact s /\ closed t ==> closed {x + y | x IN s /\ y IN t}``, 14019 REPEAT GEN_TAC THEN 14020 SIMP_TAC std_ss [compact, GSPECIFICATION, CLOSED_SEQUENTIAL_LIMITS, EXISTS_PROD] THEN 14021 STRIP_TAC THEN X_GEN_TAC ``f:num->real`` THEN X_GEN_TAC ``l:real`` THEN 14022 SIMP_TAC std_ss [SKOLEM_THM, FORALL_AND_THM] THEN 14023 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 14024 DISCH_THEN(X_CHOOSE_THEN ``a:num->real`` MP_TAC) THEN 14025 DISCH_THEN(X_CHOOSE_THEN ``b:num->real`` STRIP_ASSUME_TAC) THEN 14026 UNDISCH_TAC `` !f:num->real. 14027 (!n. f n IN s) ==> 14028 ?l r. 14029 l IN s /\ (!m n. m < n ==> r m < r n) /\ 14030 (f o r --> l) sequentially`` THEN DISCH_TAC THEN 14031 FIRST_X_ASSUM(MP_TAC o SPEC ``a:num->real``) THEN 14032 ASM_REWRITE_TAC[] THEN 14033 DISCH_THEN(X_CHOOSE_THEN ``la:real`` (X_CHOOSE_THEN ``sub:num->num`` 14034 STRIP_ASSUME_TAC)) THEN 14035 MAP_EVERY EXISTS_TAC [``la:real``, ``l - la:real``] THEN 14036 ASM_REWRITE_TAC[REAL_ARITH ``a + (b - a) = b:real``] THEN 14037 FIRST_X_ASSUM MATCH_MP_TAC THEN 14038 EXISTS_TAC ``\n. (f o (sub:num->num)) n - (a o sub) n:real`` THEN 14039 CONJ_TAC THENL [ASM_SIMP_TAC std_ss [REAL_ADD_SUB, o_THM], ALL_TAC] THEN 14040 MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC std_ss [LIM_SUBSEQUENCE, ETA_AX]); 14041 14042val CLOSED_COMPACT_SUMS = store_thm ("CLOSED_COMPACT_SUMS", 14043 ``!s:real->bool t. 14044 closed s /\ compact t ==> closed {x + y | x IN s /\ y IN t}``, 14045 REPEAT GEN_TAC THEN 14046 SUBGOAL_THEN ``{x + y:real | x IN s /\ y IN t} = {y + x | y IN t /\ x IN s}`` 14047 SUBST1_TAC THEN SIMP_TAC std_ss [COMPACT_CLOSED_SUMS] THEN 14048 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN METIS_TAC [REAL_ADD_SYM]); 14049 14050val CLOSURE_SUMS = store_thm ("CLOSURE_SUMS", 14051 ``!s t:real->bool. 14052 bounded s \/ bounded t 14053 ==> (closure {x + y | x IN s /\ y IN t} = 14054 {x + y | x IN closure s /\ y IN closure t})``, 14055 REWRITE_TAC[TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN 14056 SIMP_TAC std_ss [FORALL_AND_THM] THEN 14057 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SUMS_SYM] THEN 14058 MATCH_MP_TAC(TAUT `(p ==> q) /\ p ==> p /\ q`) THEN 14059 SIMP_TAC std_ss [] THEN 14060 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [EXTENSION, CLOSURE_SEQUENTIAL] THEN 14061 X_GEN_TAC ``z:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN EQ_TAC THENL 14062 [GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [CONJ_SYM] THEN 14063 SIMP_TAC std_ss [GSPECIFICATION, IN_DELETE, SKOLEM_THM, GSYM LEFT_EXISTS_AND_THM] THEN 14064 SIMP_TAC std_ss [FORALL_AND_THM] THEN 14065 ONCE_REWRITE_TAC[TAUT `(p /\ q) /\ r <=> q /\ p /\ r`] THEN 14066 KNOW_TAC ``(?(x' :num -> real) (f :num -> real) (f' :num -> real). 14067 (\x' f f'. ((!(n :num). f n IN (s :real -> bool)) /\ 14068 !(n :num). f' n IN (t :real -> bool)) /\ 14069 (!(n :num). x' n = f n + f' n) /\ 14070 ((x' --> (z :real)) sequentially :bool)) x' f f') ==> 14071?(p_1 :real) (p_2 :real) (x' :num -> real). 14072 (\p_1 p_2 x'. (?(x :num -> real). 14073 (!(n :num). x n IN t) /\ ((x --> p_2) sequentially :bool)) /\ 14074 ((!(n :num). x' n IN s) /\ ((x' --> p_1) sequentially :bool)) /\ 14075 (z = p_1 + p_2)) p_1 p_2 x'`` THENL 14076 [ALL_TAC, METIS_TAC []] THEN 14077 ONCE_REWRITE_TAC[MESON[] ``(?f x y. P f x y) <=> (?x y f. P f x y)``] THEN 14078 SIMP_TAC std_ss [GSYM FUN_EQ_THM] THEN 14079 SIMP_TAC std_ss [ETA_AX, UNWIND_THM2] THEN 14080 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 14081 MAP_EVERY X_GEN_TAC [``a:num->real``, ``b:num->real``] THEN 14082 STRIP_TAC THEN 14083 MP_TAC(ISPEC ``closure s:real->bool`` compact) THEN 14084 ASM_SIMP_TAC std_ss [COMPACT_CLOSURE] THEN 14085 DISCH_THEN(MP_TAC o SPEC ``a:num->real``) THEN 14086 ASM_SIMP_TAC std_ss [SIMP_RULE std_ss [SUBSET_DEF] CLOSURE_SUBSET, LEFT_IMP_EXISTS_THM] THEN 14087 MAP_EVERY X_GEN_TAC [``u:real``, ``r:num->num``] THEN STRIP_TAC THEN 14088 EXISTS_TAC ``z - u:real`` THEN 14089 EXISTS_TAC ``(a:num->real) o (r:num->num)`` THEN EXISTS_TAC ``u:real`` THEN 14090 ASM_SIMP_TAC std_ss [o_THM] THEN 14091 CONJ_TAC THENL [ALL_TAC, REAL_ARITH_TAC] THEN 14092 EXISTS_TAC ``(\n. ((\n. a n + b n) o (r:num->num)) n - (a o r) n) 14093 :num->real`` THEN 14094 CONJ_TAC THENL 14095 [ASM_SIMP_TAC real_ss [o_DEF, REAL_ARITH ``(a + b) - a:real = b``], 14096 MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC std_ss [ETA_AX] THEN 14097 MATCH_MP_TAC LIM_SUBSEQUENCE THEN ASM_REWRITE_TAC[]], 14098 SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM] THEN 14099 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, GSYM LEFT_EXISTS_AND_THM, 14100 GSYM RIGHT_EXISTS_AND_THM] THEN 14101 MAP_EVERY X_GEN_TAC 14102 [``x:real``, ``y:real``, ``a:num->real``, ``b:num->real``] THEN 14103 STRIP_TAC THEN EXISTS_TAC ``(\n. a n + b n):num->real`` THEN 14104 ASM_SIMP_TAC std_ss [LIM_ADD] THEN ASM_MESON_TAC[]]); 14105 14106val COMPACT_CLOSED_DIFFERENCES = store_thm ("COMPACT_CLOSED_DIFFERENCES", 14107 ``!s:real->bool t. 14108 compact s /\ closed t ==> closed {x - y | x IN s /\ y IN t}``, 14109 REPEAT STRIP_TAC THEN 14110 SUBGOAL_THEN ``{x - y | x:real IN s /\ y IN t} = 14111 {x + y | x IN s /\ y IN (IMAGE (\x. -x) t)}`` 14112 (fn th => ASM_SIMP_TAC std_ss [th, COMPACT_CLOSED_SUMS, CLOSED_NEGATIONS]) THEN 14113 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, IN_IMAGE] THEN 14114 ONCE_REWRITE_TAC[REAL_ARITH ``(x:real = -y) <=> (y = -x:real)``] THEN 14115 SIMP_TAC std_ss [real_sub, GSYM CONJ_ASSOC, UNWIND_THM2] THEN 14116 METIS_TAC[REAL_NEG_NEG]); 14117 14118val CLOSED_COMPACT_DIFFERENCES = store_thm ("CLOSED_COMPACT_DIFFERENCES", 14119 ``!s:real->bool t. 14120 closed s /\ compact t ==> closed {x - y | x IN s /\ y IN t}``, 14121 REPEAT STRIP_TAC THEN 14122 SUBGOAL_THEN ``{x - y | x:real IN s /\ y IN t} = 14123 {x + y | x IN s /\ y IN (IMAGE (\x. -x) t)}`` 14124 (fn th => ASM_SIMP_TAC std_ss [th, CLOSED_COMPACT_SUMS, COMPACT_NEGATIONS]) THEN 14125 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, IN_IMAGE] THEN 14126 ONCE_REWRITE_TAC[REAL_ARITH ``(x:real = -y) <=> (y = -x)``] THEN 14127 SIMP_TAC std_ss [real_sub, GSYM CONJ_ASSOC, UNWIND_THM2] THEN 14128 METIS_TAC[REAL_NEG_NEG]); 14129 14130val TRANSLATION_DIFF = store_thm ("TRANSLATION_DIFF", 14131 ``!s t:real->bool. 14132 IMAGE (\x. a + x) (s DIFF t) = 14133 (IMAGE (\x. a + x) s) DIFF (IMAGE (\x. a + x) t)``, 14134 SIMP_TAC std_ss [EXTENSION, IN_DIFF, IN_IMAGE] THEN 14135 ONCE_REWRITE_TAC[REAL_ARITH ``(x:real = a + y) <=> (y = x - a)``] THEN 14136 SIMP_TAC std_ss [UNWIND_THM2]); 14137 14138(* ------------------------------------------------------------------------- *) 14139(* Separation between points and sets. *) 14140(* ------------------------------------------------------------------------- *) 14141 14142val SEPARATE_POINT_CLOSED = store_thm ("SEPARATE_POINT_CLOSED", 14143 ``!s a:real. 14144 closed s /\ ~(a IN s) 14145 ==> ?d. &0 < d /\ !x. x IN s ==> d <= dist(a,x)``, 14146 REPEAT STRIP_TAC THEN 14147 ASM_CASES_TAC ``s:real->bool = {}`` THENL 14148 [EXISTS_TAC ``&1:real`` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY, REAL_LT_01], 14149 ALL_TAC] THEN 14150 MP_TAC(ISPECL [``s:real->bool``, ``a:real``] DISTANCE_ATTAINS_INF) THEN 14151 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC ``b:real`` THEN 14152 STRIP_TAC THEN EXISTS_TAC ``dist(a:real,b)`` THEN 14153 METIS_TAC[DIST_POS_LT]); 14154 14155val SEPARATE_COMPACT_CLOSED = store_thm ("SEPARATE_COMPACT_CLOSED", 14156 ``!s t:real->bool. 14157 compact s /\ closed t /\ (s INTER t = {}) 14158 ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)``, 14159 REPEAT STRIP_TAC THEN 14160 MP_TAC(ISPECL [``{x - y:real | x IN s /\ y IN t}``, ``0:real``] 14161 SEPARATE_POINT_CLOSED) THEN 14162 ASM_SIMP_TAC std_ss [COMPACT_CLOSED_DIFFERENCES, GSPECIFICATION, EXISTS_PROD] THEN 14163 REWRITE_TAC[REAL_ARITH ``(0 = x - y) <=> (x = y:real)``] THEN 14164 KNOW_TAC ``(!(p_1 :real) (p_2 :real). 14165 p_1 <> p_2 \/ p_1 NOTIN (s :real -> bool) \/ 14166 p_2 NOTIN (t :real -> bool))`` THENL 14167 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 14168 DISCH_THEN (X_CHOOSE_TAC ``d:real``) THEN EXISTS_TAC ``d:real`` THEN 14169 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 14170 REWRITE_TAC [dist] THEN 14171 METIS_TAC[REAL_ARITH ``abs(0 - (x - y)) = abs(x - y:real)``]); 14172 14173val SEPARATE_CLOSED_COMPACT = store_thm ("SEPARATE_CLOSED_COMPACT", 14174 ``!s t:real->bool. 14175 closed s /\ compact t /\ (s INTER t = {}) 14176 ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)``, 14177 ONCE_REWRITE_TAC[DIST_SYM, INTER_COMM] THEN 14178 MESON_TAC[SEPARATE_COMPACT_CLOSED]); 14179 14180(* ------------------------------------------------------------------------- *) 14181(* Representing sets as the union of a chain of compact sets. *) 14182(* ------------------------------------------------------------------------- *) 14183 14184val CLOSED_UNION_COMPACT_SUBSETS = store_thm ("CLOSED_UNION_COMPACT_SUBSETS", 14185 ``!s. closed s 14186 ==> ?f:num->real->bool. 14187 (!n. compact(f n)) /\ 14188 (!n. (f n) SUBSET s) /\ 14189 (!n. (f n) SUBSET f(n + 1)) /\ 14190 (BIGUNION {f n | n IN univ(:num)} = s) /\ 14191 (!k. compact k /\ k SUBSET s 14192 ==> ?N. !n. n >= N ==> k SUBSET (f n))``, 14193 REPEAT STRIP_TAC THEN 14194 EXISTS_TAC ``\n. s INTER cball(0:real,&n)`` THEN 14195 ASM_SIMP_TAC std_ss [INTER_SUBSET, COMPACT_CBALL, CLOSED_INTER_COMPACT] THEN 14196 REPEAT CONJ_TAC THENL 14197 [GEN_TAC THEN MATCH_MP_TAC(SET_RULE 14198 ``t SUBSET u ==> s INTER t SUBSET s INTER u``) THEN 14199 REWRITE_TAC[SUBSET_BALLS, DIST_REFL, GSYM REAL_OF_NUM_ADD] THEN 14200 REAL_ARITH_TAC, 14201 SIMP_TAC std_ss [EXTENSION, BIGUNION_GSPEC, GSPECIFICATION, IN_UNIV, IN_INTER] THEN 14202 X_GEN_TAC ``x:real`` THEN REWRITE_TAC[IN_CBALL_0] THEN 14203 MESON_TAC[SIMP_REAL_ARCH], 14204 X_GEN_TAC ``k:real->bool`` THEN SIMP_TAC std_ss [SUBSET_INTER] THEN 14205 REPEAT STRIP_TAC THEN 14206 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN DISCH_THEN 14207 (MP_TAC o SPEC ``0:real`` o MATCH_MP BOUNDED_SUBSET_CBALL) THEN 14208 DISCH_THEN(X_CHOOSE_THEN ``r:real`` STRIP_ASSUME_TAC) THEN 14209 MP_TAC(ISPEC ``r:real`` SIMP_REAL_ARCH) THEN 14210 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 14211 POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM REAL_OF_NUM_GE] THEN 14212 REPEAT STRIP_TAC THEN 14213 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 14214 SUBSET_TRANS)) THEN 14215 REWRITE_TAC[SUBSET_BALLS, DIST_REFL] THEN ASM_REAL_ARITH_TAC]); 14216 14217val OPEN_UNION_COMPACT_SUBSETS = store_thm ("OPEN_UNION_COMPACT_SUBSETS", 14218 ``!s. open s 14219 ==> ?f:num->real->bool. 14220 (!n. compact(f n)) /\ 14221 (!n. (f n) SUBSET s) /\ 14222 (!n. (f n) SUBSET interior(f(n + 1))) /\ 14223 (BIGUNION {f n | n IN univ(:num)} = s) /\ 14224 (!k. compact k /\ k SUBSET s 14225 ==> ?N. !n. n >= N ==> k SUBSET (f n))``, 14226 GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THENL 14227 [DISCH_TAC THEN EXISTS_TAC ``(\n. {}):num->real->bool`` THEN 14228 ASM_SIMP_TAC std_ss [EMPTY_SUBSET, SUBSET_EMPTY, COMPACT_EMPTY] THEN 14229 SIMP_TAC std_ss [EXTENSION, BIGUNION_GSPEC, GSPECIFICATION, NOT_IN_EMPTY], 14230 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 14231 DISCH_THEN(X_CHOOSE_TAC ``a:real``) THEN STRIP_TAC] THEN 14232 KNOW_TAC ``?(f :num -> real -> bool). 14233 (\f. !(n :num). compact (f n)) f /\ 14234 (\f. !(n :num). f n SUBSET (s :real -> bool)) f /\ 14235 (\f. !(n :num). f n SUBSET interior (f (n + (1 :num)))) f /\ 14236 (\f. BIGUNION {f n | n IN univ((:num) :num itself)} = s) f /\ 14237 (\f. !(k :real -> bool). 14238 compact k /\ k SUBSET s ==> 14239 ?(N :num). !(n :num). n >= N ==> k SUBSET f n) f`` THENL 14240 [ALL_TAC, METIS_TAC []] THEN 14241 MATCH_MP_TAC(METIS[] 14242 ``(!f. p1 f /\ p3 f /\ p4 f ==> p5 f) /\ 14243 (?f. p1 f /\ p2 f /\ p3 f /\ (p2 f ==> p4 f)) 14244 ==> ?f. p1 f /\ p2 f /\ p3 f /\ p4 f /\ p5 f``) THEN 14245 CONJ_TAC THENL 14246 [BETA_TAC THEN X_GEN_TAC ``f:num->real->bool`` THEN STRIP_TAC THEN 14247 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN 14248 X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN 14249 UNDISCH_TAC ``compact k`` THEN DISCH_TAC THEN 14250 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [COMPACT_EQ_HEINE_BOREL]) THEN 14251 DISCH_THEN(MP_TAC o SPEC ``{interior(f n):real->bool | n IN univ(:num)}``) THEN 14252 SIMP_TAC std_ss [FORALL_IN_GSPEC, OPEN_INTERIOR] THEN 14253 KNOW_TAC ``(k :real -> bool) SUBSET 14254 BIGUNION {interior ((f :num -> real -> bool) n) | 14255 n IN univ((:num) :num itself)}`` THENL 14256 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 14257 SUBSET_TRANS)) THEN 14258 SIMP_TAC std_ss [SUBSET_DEF, BIGUNION_GSPEC, GSPECIFICATION] THEN ASM_SET_TAC[], 14259 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 14260 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN 14261 ONCE_REWRITE_TAC [METIS [] ``interior (f n) = (\n. interior (f n)) (n:num)``] THEN 14262 SIMP_TAC std_ss [GSYM IMAGE_DEF, EXISTS_FINITE_SUBSET_IMAGE] THEN 14263 REWRITE_TAC[SUBSET_UNIV] THEN 14264 DISCH_THEN(X_CHOOSE_THEN ``i:num->bool`` STRIP_ASSUME_TAC) THEN 14265 FIRST_ASSUM(MP_TAC o SPEC ``\n:num. n`` o 14266 MATCH_MP UPPER_BOUND_FINITE_SET) THEN 14267 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 14268 POP_ASSUM MP_TAC THEN 14269 REWRITE_TAC[GE] THEN DISCH_TAC THEN X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 14270 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 14271 SUBSET_TRANS)) THEN 14272 SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_IMAGE] THEN 14273 X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN MATCH_MP_TAC SUBSET_TRANS THEN 14274 EXISTS_TAC ``(f:num->real->bool) m`` THEN 14275 REWRITE_TAC[INTERIOR_SUBSET] THEN 14276 SUBGOAL_THEN ``!m n. m <= n ==> (f:num->real->bool) m SUBSET f n`` 14277 (fn th => METIS_TAC[th, LESS_EQ_TRANS]) THEN 14278 ONCE_REWRITE_TAC [METIS [] ``f m SUBSET f n = (\m n. f m SUBSET f n) m n``] THEN 14279 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN 14280 METIS_TAC[SUBSET_DEF, ADD1, INTERIOR_SUBSET]], 14281 BETA_TAC THEN EXISTS_TAC ``\n. cball(a,&n) DIFF 14282 {x + e | x IN univ(:real) DIFF s /\ e IN ball(0,inv(&n + &1))}`` THEN 14283 SIMP_TAC std_ss [] THEN REPEAT CONJ_TAC THENL 14284 [X_GEN_TAC ``n:num`` THEN MATCH_MP_TAC COMPACT_DIFF THEN 14285 SIMP_TAC std_ss [COMPACT_CBALL, OPEN_SUMS, OPEN_BALL], 14286 GEN_TAC THEN MATCH_MP_TAC(SET_RULE 14287 ``(UNIV DIFF s) SUBSET t ==> c DIFF t SUBSET s``) THEN 14288 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN 14289 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 14290 MAP_EVERY EXISTS_TAC [``x:real``, ``0:real``] THEN 14291 ASM_SIMP_TAC std_ss [REAL_ADD_RID, CENTRE_IN_BALL, REAL_LT_INV_EQ] THEN 14292 SIMP_TAC std_ss [REAL_LT, REAL_OF_NUM_ADD] THEN ARITH_TAC, 14293 GEN_TAC THEN REWRITE_TAC[INTERIOR_DIFF] THEN MATCH_MP_TAC(SET_RULE 14294 ``s SUBSET s' /\ t' SUBSET t ==> (s DIFF t) SUBSET (s' DIFF t')``) THEN 14295 CONJ_TAC THENL 14296 [REWRITE_TAC[INTERIOR_CBALL, SUBSET_DEF, IN_BALL, IN_CBALL] THEN 14297 SIMP_TAC std_ss [GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC, 14298 MATCH_MP_TAC SUBSET_TRANS THEN 14299 EXISTS_TAC ``{x + e | x IN univ(:real) DIFF s /\ 14300 e IN cball(0,inv(&n + &2))}`` THEN 14301 CONJ_TAC THENL 14302 [MATCH_MP_TAC CLOSURE_MINIMAL THEN 14303 ASM_SIMP_TAC std_ss [CLOSED_COMPACT_SUMS, COMPACT_CBALL, 14304 GSYM OPEN_CLOSED] THEN 14305 KNOW_TAC ``ball (0,inv (&n + 1)) SUBSET ball (0,inv (&n + 1))`` THENL 14306 [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN 14307 SIMP_TAC std_ss [ball, cball, dist, GSYM REAL_OF_NUM_ADD, 14308 REAL_ARITH ``n + 1 + 1:real = n + 2``, 14309 GSPECIFICATION] THEN 14310 METIS_TAC [REAL_LE_LT], ALL_TAC] THEN 14311 SIMP_TAC std_ss [SUBSET_DEF, IN_BALL, IN_CBALL, GSYM REAL_OF_NUM_ADD] THEN 14312 SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD, dist, 14313 REAL_ARITH ``n + 1 + 1:real = n + 2``] THEN 14314 METIS_TAC [REAL_LE_LT], 14315 KNOW_TAC ``cball (0,inv (&n + &2)) SUBSET ball (0,inv (&n + &1))`` THENL 14316 [ALL_TAC, 14317 SIMP_TAC std_ss [cball, ball, dist, SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN 14318 METIS_TAC [REAL_LE_LT]] THEN 14319 REWRITE_TAC[SUBSET_DEF, IN_BALL, IN_CBALL, GSYM REAL_OF_NUM_ADD] THEN 14320 GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH 14321 ``a < b ==> x <= a ==> x < b:real``) THEN 14322 MATCH_MP_TAC REAL_LT_INV2 THEN 14323 SIMP_TAC arith_ss [REAL_LT, REAL_OF_NUM_ADD]]], 14324 DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 14325 ASM_SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_GSPEC] THEN 14326 SIMP_TAC std_ss [SUBSET_DEF, BIGUNION_GSPEC, IN_UNIV, GSPECIFICATION] THEN 14327 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN REWRITE_TAC[IN_DIFF] THEN 14328 SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, IN_BALL_0, EXISTS_PROD] THEN 14329 REWRITE_TAC[REAL_ARITH ``(x:real = y + e) <=> (e = x - y)``] THEN 14330 SIMP_TAC std_ss [TAUT `(p /\ q) /\ r <=> r /\ p /\ q`, UNWIND_THM2] THEN 14331 ONCE_REWRITE_TAC [METIS [DE_MORGAN_THM] 14332 ``(!p_1:real. p_1 IN s \/ ~(abs (x - p_1) < inv (&n + 1))) = 14333 ~(?p_1:real. (~(\p_1. (p_1 IN s)) p_1 /\ 14334 (\p_1. abs (x - p_1) < inv (&n + 1)) p_1))``] THEN 14335 REWRITE_TAC[METIS [] ``~(?x. ~P x /\ Q x) <=> !x. Q x ==> P x``] THEN 14336 UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN BETA_TAC THEN 14337 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_BALL]) THEN 14338 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 14339 ASM_REWRITE_TAC[SUBSET_DEF, IN_BALL, dist] THEN 14340 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 14341 UNDISCH_TAC ``0 < e:real`` THEN DISCH_TAC THEN 14342 FIRST_ASSUM(MP_TAC o ONCE_REWRITE_RULE [REAL_ARCH_INV]) THEN 14343 DISCH_THEN(X_CHOOSE_THEN ``N1:num`` STRIP_ASSUME_TAC) THEN 14344 MP_TAC(ISPEC ``abs(x - a:real)`` SIMP_REAL_ARCH) THEN 14345 DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN EXISTS_TAC ``N1 + N2:num`` THEN 14346 CONJ_TAC THENL 14347 [REWRITE_TAC[IN_CBALL] THEN ONCE_REWRITE_TAC[DIST_SYM, dist] THEN 14348 UNDISCH_TAC ``abs(x - a:real) <= &N2`` THEN 14349 REWRITE_TAC[dist, GSYM REAL_OF_NUM_ADD] THEN 14350 FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ] THEN 14351 DISCH_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN 14352 EXISTS_TAC ``&N2:real`` THEN ASM_REWRITE_TAC [] THEN 14353 SIMP_TAC arith_ss [REAL_OF_NUM_LE, REAL_OF_NUM_ADD], 14354 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 14355 SUBGOAL_THEN ``inv(&(N1 + N2) + &1) <= inv(&N1:real)`` MP_TAC THENL 14356 [MATCH_MP_TAC REAL_LE_INV2 THEN 14357 ASM_SIMP_TAC arith_ss [REAL_LT, LE_1] THEN 14358 REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN 14359 SIMP_TAC arith_ss [REAL_OF_NUM_LE, REAL_OF_NUM_ADD], 14360 METIS_TAC [REAL_LTE_TRANS, REAL_LET_TRANS, REAL_LE_TRANS, REAL_LT_TRANS]]]]]); 14361 14362(* ------------------------------------------------------------------------- *) 14363(* A cute way of denoting open and closed intervals using overloading. *) 14364(* ------------------------------------------------------------------------- *) 14365 14366val OPEN_interval = new_definition ("OPEN_interval", 14367 ``OPEN_interval((a:real),(b:real)) = {x:real | a < x /\ x < b}``); 14368 14369val CLOSED_interval = new_definition ("CLOSED_interval", 14370 ``CLOSED_interval (l:(real#real)list) = 14371 {x:real | FST(HD l) <= x /\ x <= SND(HD l)}``); 14372 14373val _ = overload_on ("interval",``OPEN_interval``); 14374val _ = overload_on ("interval",``CLOSED_interval``); 14375 14376val interval = store_thm ("interval", 14377 ``(interval (a,b) = {x:real | a < x /\ x < b}) /\ 14378 (interval [a,b] = {x:real | a <= x /\ x <= b})``, 14379 REWRITE_TAC [OPEN_interval, CLOSED_interval, HD]); 14380 14381val IN_INTERVAL = store_thm ("IN_INTERVAL", 14382 ``(x IN interval (a,b) = a < x /\ x < b) /\ 14383 (x IN interval [a,b] = a <= x /\ x <= b)``, 14384 SIMP_TAC std_ss [interval, GSPECIFICATION]); 14385 14386val IN_INTERVAL_REFLECT = store_thm ("IN_INTERVAL_REFLECT", 14387 ``(!a b x. (-x) IN interval[-b,-a] <=> x IN interval[a,b]) /\ 14388 (!a b x. (-x) IN interval(-b,-a) <=> x IN interval(a,b))``, 14389 SIMP_TAC std_ss [IN_INTERVAL, REAL_LT_NEG, REAL_LE_NEG] THEN 14390 METIS_TAC[]); 14391 14392val REFLECT_INTERVAL = store_thm ("REFLECT_INTERVAL", 14393 ``(!a b:real. IMAGE (\x. -x) (interval[a,b]) = interval[-b,-a]) /\ 14394 (!a b:real. IMAGE (\x. -x) (interval(a,b)) = interval(-b,-a))``, 14395 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_INTERVAL, 14396 IN_IMAGE] THEN REPEAT STRIP_TAC THEN EQ_TAC THEN 14397 METIS_TAC [REAL_LE_NEG, REAL_LT_NEG, REAL_NEG_NEG]); 14398 14399val INTERVAL_EQ_EMPTY = store_thm ("INTERVAL_EQ_EMPTY", 14400 ``!a b. (b < a <=> (interval [a,b] = {})) /\ 14401 (b <= a <=> (interval (a,b) = {}))``, 14402 REPEAT GEN_TAC THEN CONJ_TAC THENL 14403 [EQ_TAC THENL [RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN EQ_TAC THENL 14404 [SIMP_TAC std_ss [NOT_IN_EMPTY] THEN CCONTR_TAC THEN 14405 FULL_SIMP_TAC std_ss [REAL_NEG_NEG] THEN UNDISCH_TAC (Term `b < a:real`) THEN 14406 FULL_SIMP_TAC std_ss [REAL_NOT_LT] THEN MATCH_MP_TAC REAL_LE_TRANS THEN 14407 EXISTS_TAC ``x:real`` THEN ASM_REWRITE_TAC [], SIMP_TAC std_ss [NOT_IN_EMPTY]], 14408 RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN 14409 CCONTR_TAC THEN UNDISCH_TAC (Term `!x:real. a <= x /\ x <= b <=> x IN {}`) THEN 14410 FULL_SIMP_TAC std_ss [NOT_IN_EMPTY, REAL_NOT_LT] THEN EXISTS_TAC ``a:real`` 14411 THEN FULL_SIMP_TAC std_ss [REAL_LE_LT]], 14412 EQ_TAC THENL [RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN EQ_TAC THENL 14413 [SIMP_TAC std_ss [NOT_IN_EMPTY] THEN CCONTR_TAC THEN 14414 FULL_SIMP_TAC std_ss [REAL_NEG_NEG] THEN UNDISCH_TAC (Term `b <= a:real`) THEN 14415 FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN MATCH_MP_TAC REAL_LT_TRANS THEN 14416 EXISTS_TAC ``x:real`` THEN ASM_REWRITE_TAC [], SIMP_TAC std_ss [NOT_IN_EMPTY]], 14417 RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN 14418 CCONTR_TAC THEN UNDISCH_TAC (Term `!x:real. a < x /\ x < b <=> x IN {}`) THEN 14419 FULL_SIMP_TAC std_ss [NOT_IN_EMPTY, REAL_NOT_LE, REAL_MEAN]]]); 14420 14421val INTERVAL_NE_EMPTY = store_thm ("INTERVAL_NE_EMPTY", 14422 ``(~(interval [a:real,b] = {}) <=> a <= b) /\ 14423 (~(interval (a:real,b) = {}) <=> a < b)``, 14424 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, NOT_IN_EMPTY, IN_INTERVAL] THEN 14425 CONJ_TAC THEN EQ_TAC THENL [SIMP_TAC std_ss [REAL_LE_TRANS], 14426 DISCH_TAC THEN EXISTS_TAC ``a:real`` THEN ASM_SIMP_TAC std_ss [REAL_LE_LT], 14427 SIMP_TAC std_ss [REAL_LT_TRANS], FULL_SIMP_TAC std_ss [REAL_MEAN]]); 14428 14429val SUBSET_INTERVAL_IMP = store_thm ("SUBSET_INTERVAL_IMP", 14430 ``((a <= c /\ d <= b) ==> interval[c,d] SUBSET interval[a:real,b]) /\ 14431 ((a < c /\ d < b) ==> interval[c,d] SUBSET interval(a:real,b)) /\ 14432 ((a <= c /\ d <= b) ==> interval(c,d) SUBSET interval[a:real,b]) /\ 14433 ((a <= c /\ d <= b) ==> interval(c,d) SUBSET interval(a:real,b))``, 14434 REWRITE_TAC[SUBSET_DEF, IN_INTERVAL] THEN REPEAT CONJ_TAC THEN 14435 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM MP_TAC THEN REPEAT STRIP_TAC THEN 14436 METIS_TAC [REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS, REAL_LT_IMP_LE]); 14437 14438val INTERVAL_SING = store_thm ("INTERVAL_SING", 14439 ``(interval[a,a] = {a}) /\ (interval(a,a) = {})``, 14440 REWRITE_TAC[EXTENSION, IN_SING, NOT_IN_EMPTY, IN_INTERVAL] THEN 14441 REWRITE_TAC[REAL_LE_ANTISYM, REAL_LT_ANTISYM] THEN 14442 MESON_TAC[EQ_SYM_EQ]); 14443 14444val SUBSET_INTERVAL = store_thm ("SUBSET_INTERVAL", 14445 ``(interval[c,d] SUBSET interval[a:real,b] <=> 14446 (c <= d) ==> (a <= c /\ d <= b)) /\ 14447 (interval[c,d] SUBSET interval(a:real,b) <=> 14448 (c <= d) ==> (a < c /\ d < b)) /\ 14449 (interval(c,d) SUBSET interval[a:real,b] <=> 14450 (c < d) ==> (a <= c /\ d <= b)) /\ 14451 (interval(c,d) SUBSET interval(a:real,b) <=> 14452 (c < d) ==> (a <= c /\ d <= b))``, 14453 REPEAT STRIP_TAC THEN 14454 (MATCH_MP_TAC(TAUT 14455 `(~q ==> p) /\ (q ==> (p <=> r)) ==> (p <=> q ==> r)`) THEN 14456 CONJ_TAC THENL 14457 [DISCH_TAC THEN MATCH_MP_TAC(SET_RULE ``(s = {}) ==> s SUBSET t``) THEN 14458 ASM_MESON_TAC[INTERVAL_EQ_EMPTY, REAL_NOT_LE], ALL_TAC] THEN 14459 DISCH_TAC THEN EQ_TAC THEN REWRITE_TAC[SUBSET_INTERVAL_IMP] THEN 14460 REWRITE_TAC[SUBSET_DEF, IN_INTERVAL]) THENL 14461 [KNOW_TAC ``((?y. c <= y /\ y <= d) 14462 ==> (!y. c <= y /\ y <= d 14463 ==> a <= y /\ y <= b)) 14464 ==> (a <= c:real /\ d <= b:real)`` THENL 14465 [ALL_TAC, METIS_TAC []] THEN 14466 KNOW_TAC ``(?y:real. c <= y /\ y <= d)`` THENL 14467 [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 14468 STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_TRANS, REAL_LE_REFL], 14469 KNOW_TAC ``((?y. c <= y /\ y <= d) 14470 ==> (!y. c <= y /\ y <= d 14471 ==> a < y /\ y < b)) 14472 ==> (a < c:real /\ d < b:real)`` THENL 14473 [ALL_TAC, METIS_TAC []] THEN 14474 KNOW_TAC ``(?y:real. c <= y /\ y <= d)`` THENL 14475 [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 14476 STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_TRANS, REAL_LE_REFL], 14477 KNOW_TAC ``((?y. c < y /\ y < d) 14478 ==> (!y. c < y /\ y < d 14479 ==> a <= y /\ y <= b)) 14480 ==> (a <= c:real /\ d <= b:real)`` THENL 14481 [ALL_TAC, METIS_TAC []] THEN 14482 KNOW_TAC ``(?y:real. c < y /\ y < d)`` THENL 14483 [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 14484 REPEAT STRIP_TAC THENL 14485 [CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a <= y /\ y <= b`` THEN 14486 FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN 14487 EXISTS_TAC ``((c:real) + min ((a:real)) ((d:real))) / &2:real`` THEN 14488 METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ, 14489 GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2, 14490 REAL_LTE_ADD2, REAL_NOT_LE], 14491 CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a <= y /\ y <= b`` THEN 14492 FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN 14493 EXISTS_TAC ``(max ((b:real)) ((c:real)) + (d:real)) / &2:real`` THEN 14494 METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ, 14495 GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2, 14496 REAL_LTE_ADD2, REAL_NOT_LE]], 14497 KNOW_TAC ``((?y. c < y /\ y < d) 14498 ==> (!y. c < y /\ y < d 14499 ==> a < y /\ y < b)) 14500 ==> (a <= c:real /\ d <= b:real)`` THENL 14501 [ALL_TAC, METIS_TAC []] THEN 14502 KNOW_TAC ``(?y:real. c < y /\ y < d)`` THENL 14503 [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 14504 REPEAT STRIP_TAC THENL 14505 [CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a < y /\ y < b`` THEN 14506 FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN 14507 EXISTS_TAC ``((c:real) + min ((a:real)) ((d:real))) / &2:real`` THEN 14508 METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ, 14509 GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2, 14510 REAL_LTE_ADD2, REAL_NOT_LE, REAL_NOT_LT, REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ, 14511 REAL_LE_LADD, REAL_LE_ADD2, REAL_LE_RADD, REAL_LE_LT], 14512 CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a < y /\ y < b`` THEN 14513 FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN 14514 EXISTS_TAC ``(max ((b:real)) ((c:real)) + (d:real)) / &2:real`` THEN 14515 METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ, 14516 GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2, 14517 REAL_LTE_ADD2, REAL_NOT_LE, REAL_NOT_LT, REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ, 14518 REAL_LE_LADD, REAL_LE_ADD2, REAL_LE_RADD, REAL_LE_LT]]]); 14519 14520val DISJOINT_INTERVAL = store_thm ("DISJOINT_INTERVAL", 14521 ``!a b c d:real. 14522 ((interval[a,b] INTER interval[c,d] = {}) <=> 14523 b < a \/ d < c \/ 14524 b < c \/ d < a) /\ 14525 ((interval[a,b] INTER interval(c,d) = {}) <=> 14526 b < a \/ d <= c \/ 14527 b <= c \/ d <= a) /\ 14528 ((interval(a,b) INTER interval[c,d] = {}) <=> 14529 b <= a \/ d < c \/ 14530 b <= c \/ d <= a) /\ 14531 ((interval(a,b) INTER interval(c,d) = {}) <=> 14532 b <= a \/ d <= c \/ 14533 b <= c \/ d <= a)``, 14534 REWRITE_TAC [EXTENSION, IN_INTER, IN_INTERVAL, NOT_IN_EMPTY] THEN 14535 SIMP_TAC std_ss [GSYM FORALL_AND_THM, NOT_FORALL_THM] THEN 14536 REWRITE_TAC [TAUT `~((p ==> q) /\ (p ==> r)) <=> p /\ (~q \/ ~r)`] THEN 14537 REWRITE_TAC [DE_MORGAN_THM] THEN 14538 REPEAT STRIP_TAC THEN (* 4 subgoals *) 14539 (EQ_TAC THENL 14540 [DISCH_THEN (MP_TAC o SPEC ``(@f. f = (max ((a:real)) ((c:real)) + 14541 min ((b:real)) ((d:real))) / &2):real``) THEN 14542 DISCH_TAC THEN 14543 FULL_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ, 14544 REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ, 14545 REAL_ARITH ``0 < 2:real``] THEN (* 4 subgoals *) 14546 FULL_SIMP_TAC bool_ss [REAL_NOT_LE, min_def, max_def] THEN 14547 POP_ASSUM MP_TAC THEN 14548 REPEAT COND_CASES_TAC THEN ASM_REAL_ARITH_TAC, 14549 14550 DISCH_THEN (fn th => GEN_TAC THEN MP_TAC th) THEN 14551 SIMP_TAC std_ss [] THEN REAL_ARITH_TAC ])); 14552 14553val ENDS_IN_INTERVAL = store_thm ("ENDS_IN_INTERVAL", 14554 ``(!a b. a IN interval[a,b] <=> ~(interval[a,b] = {})) /\ 14555 (!a b. b IN interval[a,b] <=> ~(interval[a,b] = {})) /\ 14556 (!a b. ~(a IN interval(a,b))) /\ 14557 (!a b. ~(b IN interval(a,b)))``, 14558 REWRITE_TAC[IN_INTERVAL, INTERVAL_NE_EMPTY] THEN 14559 REWRITE_TAC[REAL_LE_REFL, REAL_LT_REFL] THEN 14560 MESON_TAC[REAL_LE_REFL]); 14561 14562val ENDS_IN_UNIT_INTERVAL = store_thm ("ENDS_IN_UNIT_INTERVAL", 14563 ``0 IN interval[0,1] /\ 1 IN interval[0,1] /\ 14564 ~(0 IN interval(0,1)) /\ ~(1 IN interval(0,1))``, 14565 REWRITE_TAC[ENDS_IN_INTERVAL, INTERVAL_NE_EMPTY] THEN 14566 REWRITE_TAC[REAL_POS]); 14567 14568val INTER_INTERVAL = store_thm ("INTER_INTERVAL", 14569 ``interval[a,b] INTER interval[c,d] = 14570 interval[(max (a) (c)),(min (b) (d))]``, 14571 REWRITE_TAC[EXTENSION, IN_INTER, IN_INTERVAL] THEN 14572 SIMP_TAC std_ss [REAL_MAX_LE, REAL_LE_MIN] THEN MESON_TAC[]); 14573 14574val INTERVAL_OPEN_SUBSET_CLOSED = store_thm ("INTERVAL_OPEN_SUBSET_CLOSED", 14575 ``!a b. interval(a,b) SUBSET interval[a,b]``, 14576 REWRITE_TAC[SUBSET_DEF, IN_INTERVAL] THEN MESON_TAC[REAL_LT_IMP_LE]); 14577 14578val REAL_LT_MIN = store_thm ("REAL_LT_MIN", 14579 ``!x y z:real. z < min x y <=> z < x /\ z < y``, 14580 METIS_TAC [min_def, REAL_LTE_TRANS, REAL_LT_TRANS, REAL_NOT_LE]); 14581 14582val OPEN_INTERVAL_LEMMA = store_thm ("OPEN_INTERVAL_LEMMA", 14583 ``!a b x. a < x /\ x < b 14584 ==> ?d. (0:real) < d /\ !x'. abs(x' - x) < d ==> a < x' /\ x' < b``, 14585 REPEAT STRIP_TAC THEN 14586 EXISTS_TAC ``min (x - a) (b - x:real)`` THEN REWRITE_TAC[REAL_LT_MIN] THEN 14587 REPEAT (POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC); 14588 14589val OPEN_INTERVAL = store_thm ("OPEN_INTERVAL", 14590 ``!a:real b. open(interval (a,b))``, 14591 REPEAT GEN_TAC THEN 14592 SIMP_TAC std_ss [open_def, interval, GSPECIFICATION, dist, OPEN_INTERVAL_LEMMA]); 14593 14594val CLOSED_INTERVAL = store_thm ("CLOSED_INTERVAL", 14595 ``!a:real b. closed(interval [a,b])``, 14596 REWRITE_TAC[CLOSED_LIMPT, LIMPT_APPROACHABLE, IN_INTERVAL] THEN 14597 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THENL 14598 [FIRST_X_ASSUM(MP_TAC o SPEC ``(a:real) - (x:real)``), 14599 FIRST_X_ASSUM(MP_TAC o SPEC ``(x:real) - (b:real)``)] THEN 14600 ASM_REWRITE_TAC[REAL_SUB_LT] THEN 14601 DISCH_THEN(X_CHOOSE_THEN ``z:real`` MP_TAC) THEN 14602 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 14603 REWRITE_TAC[dist, REAL_NOT_LT] THEN 14604 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``abs((z - x :real))`` THEN 14605 ASM_SIMP_TAC std_ss [REAL_ARITH ``x < a /\ a <= z ==> a - x:real <= abs(z - x)``, 14606 REAL_ARITH ``z <= b /\ b < x ==> x - b:real <= abs(z - x)``, 14607 REAL_LE_REFL]); 14608 14609val INTERIOR_CLOSED_INTERVAL = store_thm ("INTERIOR_CLOSED_INTERVAL", 14610 ``!a:real b. interior(interval [a,b]) = interval (a,b)``, 14611 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 14612 [ALL_TAC, 14613 MATCH_MP_TAC INTERIOR_MAXIMAL THEN 14614 REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED, OPEN_INTERVAL]] THEN 14615 SIMP_TAC std_ss [interior, SUBSET_DEF, IN_INTERVAL, GSPECIFICATION] THEN 14616 X_GEN_TAC ``x:real`` THEN 14617 DISCH_THEN(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN 14618 ASM_SIMP_TAC std_ss [REAL_LT_LE] THEN REPEAT STRIP_TAC THEN 14619 UNDISCH_TAC ``open s`` THEN REWRITE_TAC [open_def] THEN 14620 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 14621 DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THENL 14622 [DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x - (e / 2:real)`), 14623 DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x + (e / 2:real)`)] THEN 14624 ASM_SIMP_TAC std_ss [dist, REAL_ADD_SUB, REAL_ARITH ``x - y - x = -y:real``, 14625 REAL_ARITH ``x + y - x = y:real``] THEN 14626 ASM_SIMP_TAC std_ss [ABS_MUL, ABS_NEG, REAL_MUL_RID] THENL [CONJ_TAC THENL 14627 [METIS_TAC [ABS_REFL, REAL_LT_HALF1, REAL_LT_HALF2, REAL_LE_LT], ALL_TAC], 14628 CONJ_TAC THENL [METIS_TAC [ABS_REFL, REAL_LT_HALF1, REAL_LT_HALF2, REAL_LE_LT], 14629 ALL_TAC]] THEN CCONTR_TAC THEN 14630 UNDISCH_TAC ``!x. x IN s ==> a <= x /\ x <= b:real`` THEN DISCH_TAC THENL 14631 [POP_ASSUM (MP_TAC o Q.SPEC `x - e / 2:real`), 14632 POP_ASSUM (MP_TAC o Q.SPEC `x + e / 2:real`)] THEN FULL_SIMP_TAC std_ss [] THENL 14633 [DISJ1_TAC THEN REWRITE_TAC[REAL_ARITH ``a <= a - b <=> ~(&0 < b:real)``], 14634 DISJ2_TAC THEN REWRITE_TAC[REAL_ARITH ``a + b <= a <=> ~(&0 < b:real)``]] THEN 14635 FULL_SIMP_TAC std_ss [REAL_LT_HALF1]); 14636 14637val INTERIOR_INTERVAL = store_thm ("INTERIOR_INTERVAL", 14638 ``(!a b. interior(interval[a,b]) = interval(a,b)) /\ 14639 (!a b. interior(interval(a,b)) = interval(a,b))``, 14640 SIMP_TAC std_ss [INTERIOR_CLOSED_INTERVAL, INTERIOR_OPEN, OPEN_INTERVAL]); 14641 14642val BOUNDED_CLOSED_INTERVAL = store_thm ("BOUNDED_CLOSED_INTERVAL", 14643 ``!a b:real. bounded (interval [a,b])``, 14644 REPEAT STRIP_TAC THEN REWRITE_TAC[bounded_def, interval] THEN 14645 SIMP_TAC std_ss [GSPECIFICATION] THEN 14646 EXISTS_TAC ``abs(a) + abs(b:real)`` THEN REAL_ARITH_TAC); 14647 14648val BOUNDED_INTERVAL = store_thm ("BOUNDED_INTERVAL", 14649 ``(!a b. bounded (interval [a,b])) /\ (!a b. bounded (interval (a,b)))``, 14650 MESON_TAC[BOUNDED_CLOSED_INTERVAL, BOUNDED_SUBSET, 14651 INTERVAL_OPEN_SUBSET_CLOSED]); 14652 14653val NOT_INTERVAL_UNIV = store_thm ("NOT_INTERVAL_UNIV", 14654 ``(!a b. ~(interval[a,b] = UNIV)) /\ 14655 (!a b. ~(interval(a,b) = UNIV))``, 14656 MESON_TAC[BOUNDED_INTERVAL, NOT_BOUNDED_UNIV]); 14657 14658val COMPACT_INTERVAL = store_thm ("COMPACT_INTERVAL", 14659 ``!a b. compact (interval [a,b])``, 14660 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTERVAL, CLOSED_INTERVAL]); 14661 14662val OPEN_INTERVAL_MIDPOINT = store_thm ("OPEN_INTERVAL_MIDPOINT", 14663 ``!a b:real. 14664 ~(interval(a,b) = {}) ==> (inv(&2) * (a + b)) IN interval(a,b)``, 14665 REWRITE_TAC[INTERVAL_NE_EMPTY, IN_INTERVAL] THEN 14666 ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN ONCE_REWRITE_TAC [GSYM real_div] THEN 14667 KNOW_TAC ``0 < 2:real`` THENL [REAL_ARITH_TAC, ALL_TAC] THEN 14668 REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ] THEN 14669 REWRITE_TAC [REAL_MUL_COMM, GSYM REAL_DOUBLE] THEN 14670 FULL_SIMP_TAC std_ss [REAL_LT_LADD, REAL_LT_RADD]); 14671 14672val OPEN_CLOSED_INTERVAL_CONVEX = store_thm ("OPEN_CLOSED_INTERVAL_CONVEX", 14673 ``!a b x y:real e. 14674 x IN interval(a,b) /\ y IN interval[a,b] /\ &0 < e /\ e <= &1 14675 ==> (e * x + (&1 - e) * y) IN interval(a,b)``, 14676 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT 14677 `(c /\ d ==> a /\ b ==> e) ==> a /\ b /\ c /\ d ==> e`) THEN 14678 STRIP_TAC THEN REWRITE_TAC[IN_INTERVAL] THEN STRIP_TAC THEN 14679 SUBST1_TAC(REAL_ARITH ``(a:real) = e * a + (&1 - e) * a``) THEN 14680 SUBST1_TAC(REAL_ARITH ``(b:real) = e * b + (&1 - e) * b``) THEN 14681 KNOW_TAC ``0:real <= 1 - e`` THENL 14682 [FULL_SIMP_TAC std_ss [REAL_SUB_LE], ALL_TAC] THEN 14683 REWRITE_TAC [REAL_LE_LT] THEN STRIP_TAC THENL 14684 [CONJ_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN 14685 ASM_SIMP_TAC std_ss [REAL_LT_LMUL, REAL_LE_LMUL, REAL_SUB_LE], 14686 POP_ASSUM MP_TAC THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN 14687 DISCH_TAC THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN 14688 ASM_SIMP_TAC std_ss [REAL_LT_LMUL, REAL_LE_LMUL, REAL_SUB_LE, REAL_MUL_LZERO, REAL_LE_REFL]]); 14689 14690val REAL_LE_INV2 = store_thm ("REAL_LE_INV2", 14691 ``!x:real y. &0 < x /\ x <= y ==> inv(y) <= inv(x)``, 14692 REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN 14693 ASM_CASES_TAC ``x:real = y`` THEN ASM_REWRITE_TAC[] THEN 14694 STRIP_TAC THEN DISJ1_TAC THEN MATCH_MP_TAC REAL_LT_INV THEN 14695 ASM_REWRITE_TAC[]); 14696 14697val REAL_INV_LE_1 = store_thm ("REAL_INV_LE_1", 14698 ``!x:real. &1 <= x ==> inv(x) <= &1``, 14699 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_INV1] THEN 14700 MATCH_MP_TAC REAL_LE_INV2 THEN ASM_REWRITE_TAC[REAL_LT_01]); 14701 14702val CLOSURE_OPEN_INTERVAL = store_thm ("CLOSURE_OPEN_INTERVAL", 14703 ``!a b:real. 14704 ~(interval(a,b) = {}) ==> (closure(interval(a,b)) = interval[a,b])``, 14705 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL 14706 [MATCH_MP_TAC CLOSURE_MINIMAL THEN 14707 REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED, CLOSED_INTERVAL], 14708 ALL_TAC] THEN 14709 REWRITE_TAC[SUBSET_DEF, closure, IN_UNION] THEN X_GEN_TAC ``x:real`` THEN 14710 DISCH_TAC THEN MATCH_MP_TAC(TAUT `(~b ==> c) ==> b \/ c`) THEN DISCH_TAC THEN 14711 SIMP_TAC std_ss [GSPECIFICATION, LIMPT_SEQUENTIAL] THEN 14712 ABBREV_TAC ``(c:real) = inv(&2:real) * (a + b)`` THEN 14713 EXISTS_TAC ``\n. (x:real) + inv(&n + &1:real) * (c - x)`` THEN CONJ_TAC THENL 14714 [X_GEN_TAC ``n:num`` THEN REWRITE_TAC[IN_DELETE] THEN BETA_TAC THEN 14715 REWRITE_TAC[REAL_ARITH ``(x + a = x) <=> (a = 0:real)``] THEN 14716 REWRITE_TAC[REAL_ENTIRE, REAL_INV_EQ_0] THEN 14717 SIMP_TAC std_ss [REAL_SUB_0, REAL_OF_NUM_SUC, SUC_NOT, REAL_OF_NUM_EQ, EQ_SYM_EQ] THEN 14718 CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT]] THEN 14719 REWRITE_TAC[REAL_ARITH ``x + a * (y - x) = a * y + (&1 - a) * x:real``] THEN 14720 MATCH_MP_TAC OPEN_CLOSED_INTERVAL_CONVEX THEN 14721 CONJ_TAC THENL [ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT], ALL_TAC] THEN 14722 KNOW_TAC ``&0:real < &n + &1`` THENL [SIMP_TAC std_ss [REAL_OF_NUM_SUC] THEN 14723 ASM_REWRITE_TAC[REAL_LT_INV_EQ, REAL_OF_NUM_SUC, REAL_LT, LESS_0], ALL_TAC] THEN 14724 DISCH_TAC THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ, REAL_OF_NUM_SUC, REAL_LT, LESS_0] THEN 14725 MATCH_MP_TAC REAL_INV_LE_1 THEN REWRITE_TAC [REAL_LE, ONE, LESS_EQ_MONO, 14726 ZERO_LESS_EQ], ALL_TAC] THEN 14727 GEN_REWR_TAC LAND_CONV [REAL_ARITH ``x:real = x + &0 * (c - x)``] THEN 14728 KNOW_TAC ``!n:num x:real. (\n. x + inv (&n + 1) * (c - x)) = 14729 (\n. (\n. x) n + (\n. inv (&n + 1) * (c - x)) n)`` THENL 14730 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 14731 MATCH_MP_TAC LIM_ADD THEN REWRITE_TAC[LIM_CONST] THEN 14732 KNOW_TAC ``!n:num. (\n. inv (&n + 1) * (c - x:real)) = 14733 (\n. (\n. inv (&n + 1)) n * (\n. (c - x)) n)`` THENL 14734 [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN 14735 MATCH_MP_TAC LIM_MUL THEN REWRITE_TAC[LIM_CONST] THEN 14736 REWRITE_TAC[LIM_SEQUENTIALLY, o_THM, REAL_SUB_RZERO] THEN BETA_TAC THEN 14737 X_GEN_TAC ``e:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_ARCH_INV] THEN 14738 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 14739 X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 14740 KNOW_TAC ``&n + 1 <> 0:real`` THENL 14741 [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN 14742 SIMP_TAC arith_ss [REAL_OF_NUM_SUC, REAL_LT, ADD1], ALL_TAC] THEN DISCH_TAC THEN 14743 ASM_SIMP_TAC std_ss [DIST_0, ABS_INV] THEN MATCH_MP_TAC REAL_LET_TRANS THEN 14744 EXISTS_TAC ``inv(&N:real)`` THEN ASM_REWRITE_TAC[] THEN 14745 MATCH_MP_TAC REAL_LE_INV2 THEN FULL_SIMP_TAC std_ss [] THEN 14746 UNDISCH_TAC ``N:num <= n`` THEN UNDISCH_TAC ``N <> 0:num`` THEN 14747 REWRITE_TAC[NOT_ZERO_LT_ZERO, GSYM REAL_OF_NUM_LE, GSYM REAL_LT] THEN 14748 REAL_ARITH_TAC); 14749 14750val CLOSURE_INTERVAL = store_thm ("CLOSURE_INTERVAL", 14751 ``(!a b. closure(interval[a,b]) = interval[a,b]) /\ 14752 (!a b. closure(interval(a,b)) = 14753 if interval(a,b) = {} then {} else interval[a,b])``, 14754 SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_INTERVAL] THEN REPEAT GEN_TAC THEN 14755 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [CLOSURE_OPEN_INTERVAL, CLOSURE_EMPTY]); 14756 14757val BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC = store_thm ("BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC", 14758 ``!s:real->bool. bounded s ==> ?a. s SUBSET interval(-a,a)``, 14759 SIMP_TAC std_ss [BOUNDED_POS, LEFT_IMP_EXISTS_THM] THEN 14760 MAP_EVERY X_GEN_TAC [``s:real->bool``, ``B:real``] THEN STRIP_TAC THEN 14761 EXISTS_TAC ``(B + &1):real`` THEN 14762 REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 14763 SIMP_TAC std_ss [IN_INTERVAL, REAL_BOUNDS_LT] THEN 14764 METIS_TAC[REAL_LE_REFL, REAL_ARITH ``x <= y ==> a <= x ==> a < y + &1:real``]); 14765 14766val BOUNDED_SUBSET_OPEN_INTERVAL = store_thm ("BOUNDED_SUBSET_OPEN_INTERVAL", 14767 ``!s:real->bool. bounded s ==> ?a b. s SUBSET interval(a,b)``, 14768 MESON_TAC[BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC]); 14769 14770val BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC = store_thm ("BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC", 14771 ``!s:real->bool. bounded s ==> ?a. s SUBSET interval[-a,a]``, 14772 GEN_TAC THEN 14773 DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC) THEN 14774 STRIP_TAC THEN EXISTS_TAC ``a:real`` THEN POP_ASSUM MP_TAC THEN 14775 SIMP_TAC std_ss [IN_BALL, IN_INTERVAL, SUBSET_DEF, REAL_LT_IMP_LE]); 14776 14777val BOUNDED_SUBSET_CLOSED_INTERVAL = store_thm ("BOUNDED_SUBSET_CLOSED_INTERVAL", 14778 ``!s:real->bool. bounded s ==> ?a b. s SUBSET interval[a,b]``, 14779 MESON_TAC[BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC]); 14780 14781val FRONTIER_CLOSED_INTERVAL = store_thm ("FRONTIER_CLOSED_INTERVAL", 14782 ``!a b. frontier(interval[a,b]) = interval[a,b] DIFF interval(a,b)``, 14783 SIMP_TAC std_ss [frontier, INTERIOR_CLOSED_INTERVAL, CLOSURE_CLOSED, 14784 CLOSED_INTERVAL]); 14785 14786val FRONTIER_OPEN_INTERVAL = store_thm ("FRONTIER_OPEN_INTERVAL", 14787 ``!a b. frontier(interval(a,b)) = 14788 if interval(a,b) = {} then {} 14789 else interval[a,b] DIFF interval(a,b)``, 14790 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[FRONTIER_EMPTY] THEN 14791 ASM_SIMP_TAC std_ss [frontier, CLOSURE_OPEN_INTERVAL, INTERIOR_OPEN, 14792 OPEN_INTERVAL]); 14793 14794val INTER_INTERVAL_MIXED_EQ_EMPTY = store_thm ("INTER_INTERVAL_MIXED_EQ_EMPTY", 14795 ``!a b c d:real. 14796 ~(interval(c,d) = {}) 14797 ==> ((interval(a,b) INTER interval[c,d] = {}) <=> 14798 (interval(a,b) INTER interval(c,d) = {}))``, 14799 SIMP_TAC std_ss [GSYM CLOSURE_OPEN_INTERVAL, OPEN_INTER_CLOSURE_EQ_EMPTY, 14800 OPEN_INTERVAL]); 14801 14802val INTERVAL_TRANSLATION = store_thm ("INTERVAL_TRANSLATION", 14803 ``(!c a b. interval[c + a,c + b] = IMAGE (\x. c + x) (interval[a,b])) /\ 14804 (!c a b. interval(c + a,c + b) = IMAGE (\x. c + x) (interval(a,b)))``, 14805 REWRITE_TAC[interval] THEN CONJ_TAC THEN 14806 (SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN 14807 REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN 14808 TRY (EXISTS_TAC ``-c + x:real``) THEN ASM_REAL_ARITH_TAC)); 14809 14810val EMPTY_AS_INTERVAL = store_thm ("EMPTY_AS_INTERVAL", 14811 ``{} = interval[1,0]``, 14812 SIMP_TAC std_ss [EXTENSION, NOT_IN_EMPTY, IN_INTERVAL] THEN 14813 REAL_ARITH_TAC); 14814 14815val UNIT_INTERVAL_NONEMPTY = store_thm ("UNIT_INTERVAL_NONEMPTY", 14816 ``~(interval[0:real,1] = {}) /\ 14817 ~(interval(0:real,1) = {})``, 14818 SIMP_TAC std_ss [INTERVAL_NE_EMPTY, REAL_LT_01, REAL_POS]); 14819 14820val IMAGE_STRETCH_INTERVAL = store_thm 14821 ("IMAGE_STRETCH_INTERVAL", 14822 ``!a b:real m. 14823 IMAGE (\x. @f. f = m(1:num) * x) (interval[a,b]) = 14824 if interval[a,b] = {} then {} 14825 else interval[(@f. f = min (m(1:num) * a) (m(1:num) * b)):real, 14826 (@f. f = max (m(1:num) * a) (m(1:num) * b))]``, 14827 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [IMAGE_EMPTY, IMAGE_INSERT] THEN 14828 ASM_SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_INTERVAL, GSYM FORALL_AND_THM, 14829 TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN 14830 X_GEN_TAC ``x:real`` THEN 14831 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [INTERVAL_NE_EMPTY]) THEN 14832 ASM_CASES_TAC ``(m:num->real) (1:num) = &0`` THENL 14833 [ASM_SIMP_TAC std_ss [REAL_MUL_LZERO, REAL_MAX_ACI, REAL_MIN_ACI] THEN 14834 METIS_TAC[REAL_LE_ANTISYM, REAL_LE_REFL], 14835 ALL_TAC] THEN 14836 KNOW_TAC ``!m x y:real. ~(m = 0:real) ==> ((x = m * y) <=> (y = x / m))`` THENL 14837 [REPEAT GEN_TAC THEN DISCH_TAC THEN ASSUME_TAC REAL_LE_TOTAL THEN 14838 GEN_REWR_TAC RAND_CONV [EQ_SYM_EQ] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 14839 POP_ASSUM (MP_TAC o Q.SPECL [`m':real`,`0:real`]) THEN 14840 ASM_SIMP_TAC std_ss [REAL_LE_LT] THEN STRIP_TAC THENL 14841 [ALL_TAC, METIS_TAC [REAL_EQ_LDIV_EQ]] THEN 14842 ONCE_REWRITE_TAC [GSYM REAL_EQ_NEG] THEN REWRITE_TAC [real_div] THEN 14843 REWRITE_TAC [REAL_ARITH ``-(a * b) = a * -b:real``] THEN 14844 ASM_SIMP_TAC std_ss [REAL_NEG_INV, GSYM real_div] THEN POP_ASSUM MP_TAC THEN 14845 GEN_REWR_TAC LAND_CONV [GSYM REAL_LT_NEG] THEN REWRITE_TAC [REAL_NEG_0] THEN 14846 DISCH_TAC THEN REWRITE_TAC [REAL_ARITH ``(-x = y * -m) = (x = -y * -m:real)``] THEN 14847 METIS_TAC [REAL_EQ_LDIV_EQ], DISCH_TAC THEN ASM_SIMP_TAC std_ss []] THEN 14848 SIMP_TAC std_ss [UNWIND_THM2] THEN FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP 14849 (REAL_ARITH ``~(z = &0) ==> &0 < z \/ &0 < -z:real``)) 14850 >- ( ASM_SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ] \\ 14851 DISCH_TAC \\ 14852 `(m 1) * a <= (m 1) * b` by PROVE_TAC [REAL_LE_LMUL] \\ 14853 ASM_SIMP_TAC std_ss [min_def, max_def] \\ 14854 METIS_TAC [REAL_MUL_SYM] ) 14855 >> ONCE_REWRITE_TAC[GSYM REAL_LE_NEG2] 14856 >> ONCE_REWRITE_TAC[REAL_MUL_SYM] 14857 >> KNOW_TAC ``!a b. -(max a b) = min (-a) (-b:real)`` 14858 >- PROVE_TAC [REAL_MAX_MIN, REAL_NEG_NEG] >> DISCH_TAC 14859 >> KNOW_TAC ``!a b. -(min a b) = max (-a) (-b:real)`` 14860 >- PROVE_TAC [REAL_MIN_MAX, REAL_NEG_NEG] >> DISCH_TAC 14861 >> ASM_SIMP_TAC std_ss [real_div, GSYM REAL_MUL_RNEG, REAL_NEG_INV] 14862 >> REWRITE_TAC [GSYM real_div] 14863 >> ASM_SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ] 14864 >> ONCE_REWRITE_TAC [REAL_LE_NEG2] 14865 >> DISCH_TAC 14866 >> `a * -(m 1) <= b * -(m 1)` by PROVE_TAC [REAL_LE_RMUL] 14867 >> ASM_SIMP_TAC std_ss [min_def, max_def] 14868 >> REAL_ARITH_TAC); 14869 14870val INTERVAL_IMAGE_STRETCH_INTERVAL = store_thm ("INTERVAL_IMAGE_STRETCH_INTERVAL", 14871 ``!a b:real m. ?u v:real. 14872 IMAGE (\x. @f. f = m (1:num) * x) (interval[a,b]) = interval[u,v]``, 14873 SIMP_TAC std_ss [IMAGE_STRETCH_INTERVAL] THEN METIS_TAC[EMPTY_AS_INTERVAL]); 14874 14875val CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL = store_thm ("CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL", 14876 ``!a b:real. 14877 ~(interval[a,b] = {}) 14878 ==> (interval[a,b] = IMAGE (\x:real. a + x) 14879 (IMAGE (\x. (@f. f = (b - a) * x)) 14880 (interval[0:real,1])))``, 14881 REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN 14882 ONCE_REWRITE_TAC [METIS [] ``(\x. @f. f = (b - a) * x) = 14883 (\x. @f. f = (\x. (b - a)) (1:num) * x:real)``] THEN 14884 REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN 14885 SIMP_TAC std_ss [REAL_MUL_RZERO, REAL_MUL_RID, UNIT_INTERVAL_NONEMPTY] THEN 14886 REWRITE_TAC[EXTENSION, IN_INTERVAL] THEN 14887 GEN_TAC THEN SIMP_TAC std_ss [IN_IMAGE, IN_INTERVAL, min_def, max_def] THEN 14888 ASM_SIMP_TAC std_ss [REAL_SUB_LE] THEN EQ_TAC THENL 14889 [DISCH_TAC THEN EXISTS_TAC ``x - a:real`` THEN ASM_REAL_ARITH_TAC, ASM_REAL_ARITH_TAC]); 14890 14891val SUMS_INTERVALS = store_thm ("SUMS_INTERVALS", 14892 ``(!a b c d:real. 14893 ~(interval[a,b] = {}) /\ ~(interval[c,d] = {}) 14894 ==> ({x + y | x IN interval[a,b] /\ y IN interval[c,d]} = 14895 interval[a+c,b+d])) /\ 14896 (!a b c d:real. 14897 ~(interval(a,b) = {}) /\ ~(interval(c,d) = {}) 14898 ==> ({x + y | x IN interval(a,b) /\ y IN interval(c,d)} = 14899 interval(a+c,b+d)))``, 14900 CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[INTERVAL_NE_EMPTY] THEN 14901 STRIP_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_INTERVAL, GSPECIFICATION, EXISTS_PROD] THEN 14902 ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c <=> c /\ a /\ b`] THEN 14903 REWRITE_TAC[REAL_ARITH ``(x:real = y + z) <=> (z = x - y)``] THEN 14904 SIMP_TAC std_ss [UNWIND_THM2] THEN (* 2 subgoals *) 14905 ( X_GEN_TAC ``x:real`` THEN EQ_TAC 14906 >- ( DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) >> ASM_REAL_ARITH_TAC ) 14907 >> STRIP_TAC 14908 >> ONCE_REWRITE_TAC [CONJ_SYM] 14909 >> KNOW_TAC 14910 ``(!y. (a <= y /\ y <= b) /\ c <= x - y /\ x - y <= d <=> 14911 ((if a <= x - d then x - d else a) <= y /\ 14912 y <= if b <= x - c then b else x - c:real)) /\ 14913 (!y. (a < y /\ y < b) /\ c < x - y /\ x - y < d <=> 14914 ((if a <= x - d then x - d else a) < y /\ 14915 y < if b <= x - c then b else x - c:real))`` 14916 >- ( CONJ_TAC >> GEN_TAC >> rpt COND_CASES_TAC >> ASM_REAL_ARITH_TAC ) 14917 >> STRIP_TAC >> ASM_REWRITE_TAC [] 14918 >> REWRITE_TAC [GSYM min_def, GSYM max_def, GSYM REAL_LE_BETWEEN, GSYM REAL_LT_BETWEEN] 14919 >> ASM_REWRITE_TAC [min_def, max_def] 14920 >> rpt COND_CASES_TAC (* 4 subgoals *) 14921 >> METIS_TAC [REAL_LE_SUB_LADD, REAL_LE_SUB_RADD, REAL_LE_LADD, REAL_LE_NEG, real_sub, 14922 REAL_LT_SUB_LADD, REAL_LT_SUB_RADD, REAL_LT_LADD, REAL_LT_NEG] )); 14923 14924val OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL = store_thm ("OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL", 14925 ``(!s:real->bool. 14926 open s <=> 14927 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval[a,b] SUBSET s) /\ 14928 (!s:real->bool. 14929 open s <=> 14930 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval(a,b) SUBSET s)``, 14931 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN GEN_TAC THEN 14932 MATCH_MP_TAC(TAUT 14933 `(q ==> r) /\ (r ==> p) /\ (p ==> q) ==> (p <=> q) /\ (p <=> r)`) THEN 14934 REPEAT CONJ_TAC THENL 14935 [MESON_TAC[SUBSET_TRANS, INTERVAL_OPEN_SUBSET_CLOSED], 14936 DISCH_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN 14937 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 14938 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN 14939 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 14940 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN STRIP_TAC THEN 14941 MP_TAC(ISPEC ``interval(a:real,b)`` OPEN_CONTAINS_BALL) THEN 14942 REWRITE_TAC[OPEN_INTERVAL] THEN 14943 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 14944 REPEAT STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN 14945 ASM_MESON_TAC[SUBSET_TRANS, INTERVAL_OPEN_SUBSET_CLOSED], 14946 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 14947 FIRST_ASSUM(MP_TAC o SPEC ``x:real`` o 14948 REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN 14949 ASM_REWRITE_TAC[] THEN 14950 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 14951 EXISTS_TAC ``x - e:real`` THEN 14952 EXISTS_TAC ``x + e:real`` THEN 14953 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE 14954 ``b SUBSET s ==> x IN i /\ j SUBSET b ==> x IN i /\ j SUBSET s``)) THEN 14955 SIMP_TAC std_ss [IN_INTERVAL, IN_CBALL, SUBSET_DEF, REAL_MUL_RID] THEN 14956 REWRITE_TAC[REAL_ARITH ``x - e < x /\ x < x + e <=> &0 < e:real``, 14957 REAL_ARITH ``x - e <= y /\ y <= x + e <=> abs(x - y) <= e:real``] THEN 14958 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT, LE_1] THEN 14959 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN ASM_REWRITE_TAC[dist]]); 14960 14961val OPEN_CONTAINS_INTERVAL = store_thm ("OPEN_CONTAINS_INTERVAL", 14962 ``(!s:real->bool. 14963 open s <=> 14964 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval[a,b] SUBSET s)``, 14965 REWRITE_TAC [OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL]); 14966 14967val OPEN_CONTAINS_OPEN_INTERVAL = store_thm ("OPEN_CONTAINS_OPEN_INTERVAL", 14968 ``(!s:real->bool. 14969 open s <=> 14970 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval(a,b) SUBSET s)``, 14971 METIS_TAC [OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL]); 14972 14973val DIAMETER_INTERVAL = store_thm ("DIAMETER_INTERVAL", 14974 ``(!a b:real. 14975 diameter(interval[a,b]) = 14976 if interval[a,b] = {} then &0 else abs(b - a)) /\ 14977 (!a b:real. 14978 diameter(interval(a,b)) = 14979 if interval(a,b) = {} then &0 else abs(b - a))``, 14980 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN 14981 ASM_CASES_TAC ``interval[a:real,b] = {}`` THENL 14982 [METIS_TAC[INTERVAL_OPEN_SUBSET_CLOSED, SUBSET_EMPTY, DIAMETER_EMPTY], 14983 ASM_REWRITE_TAC[]] THEN 14984 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL 14985 [REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN 14986 ASM_SIMP_TAC std_ss [DIAMETER_BOUNDED_BOUND, 14987 ENDS_IN_INTERVAL, BOUNDED_INTERVAL] THEN 14988 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC 14989 ``diameter(cball(inv(&2) * (a + b):real,abs(b - a) / &2))`` THEN 14990 CONJ_TAC THENL 14991 [MATCH_MP_TAC DIAMETER_SUBSET THEN REWRITE_TAC[BOUNDED_CBALL] THEN 14992 REWRITE_TAC[SUBSET_DEF, IN_INTERVAL, IN_CBALL] THEN 14993 GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[dist] THEN 14994 KNOW_TAC ``x = x * (2 / 2:real)`` THENL 14995 [METIS_TAC [REAL_DIV_REFL, REAL_MUL_RID, REAL_ARITH ``2 <> 0:real``], 14996 DISCH_TAC THEN ONCE_ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 14997 REWRITE_TAC [real_div]] THEN 14998 REWRITE_TAC [REAL_ARITH ``a * (b * inv b) = inv b * (a * b:real)``] THEN 14999 REWRITE_TAC [GSYM REAL_SUB_LDISTRIB, ABS_MUL] THEN 15000 SIMP_TAC std_ss [ABS_INV, REAL_ARITH ``2 <> 0:real``, ABS_N] THEN 15001 GEN_REWR_TAC RAND_CONV [REAL_MUL_SYM] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN 15002 SIMP_TAC std_ss [ABS_POS, REAL_LE_REFL, REAL_INV_1OVER, REAL_HALF_BETWEEN] THEN 15003 ASM_REAL_ARITH_TAC, 15004 REWRITE_TAC[DIAMETER_CBALL] THEN COND_CASES_TAC THEN 15005 REWRITE_TAC [ABS_POS, real_div] THEN 15006 ONCE_REWRITE_TAC [REAL_ARITH ``a * (b * c) = (a * c) * b:real``] THEN 15007 SIMP_TAC std_ss [REAL_MUL_RINV, REAL_ARITH ``2 <> 0:real``] THEN 15008 REAL_ARITH_TAC], 15009 DISCH_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[DIAMETER_EMPTY] THEN 15010 SUBGOAL_THEN ``interval[a:real,b] = closure(interval(a,b))`` 15011 SUBST_ALL_TAC THEN ASM_REWRITE_TAC[CLOSURE_INTERVAL] THEN 15012 ASM_MESON_TAC[DIAMETER_CLOSURE, BOUNDED_INTERVAL]]); 15013 15014val IMAGE_TWIZZLE_INTERVAL = store_thm ("IMAGE_TWIZZLE_INTERVAL", 15015 ``!p a b. IMAGE ((\x. x):real->real) (interval[a,b]) = 15016 interval[a,b]``, 15017 SET_TAC [interval]); 15018 15019val EQ_INTERVAL = store_thm ("EQ_INTERVAL", 15020 ``(!a b c d:real. 15021 (interval[a,b] = interval[c,d]) <=> 15022 ((interval[a,b] = {}) /\ (interval[c,d] = {})) \/ ((a = c) /\ (b = d))) /\ 15023 (!a b c d:real. 15024 (interval[a,b] = interval(c,d)) <=> 15025 (interval[a,b] = {}) /\ (interval(c,d) = {})) /\ 15026 (!a b c d:real. 15027 (interval(a,b) = interval[c,d]) <=> 15028 (interval(a,b) = {}) /\ (interval[c,d] = {})) /\ 15029 (!a b c d:real. 15030 (interval(a,b) = interval(c,d)) <=> 15031 ((interval(a,b) = {}) /\ (interval(c,d) = {})) \/ ((a = c) /\ (b = d)))``, 15032 REPEAT CONJ_TAC THEN REPEAT GEN_TAC THEN 15033 (EQ_TAC THENL [ALL_TAC, STRIP_TAC THEN ASM_REWRITE_TAC[]]) THEN 15034 MATCH_MP_TAC(MESON[] 15035 ``((p = {}) /\ (q = {}) ==> r) /\ (~(p = {}) /\ ~(q = {}) ==> (p = q) ==> r) 15036 ==> (p = q) ==> r``) THEN 15037 SIMP_TAC std_ss [] THENL 15038 [REWRITE_TAC[INTERVAL_NE_EMPTY] THEN 15039 REWRITE_TAC[GSYM SUBSET_ANTISYM] THEN 15040 METIS_TAC [SUBSET_INTERVAL, GSYM REAL_LE_ANTISYM], 15041 STRIP_TAC THEN MATCH_MP_TAC(MESON[CLOPEN] 15042 ``closed s /\ open t /\ ~(s = {}) /\ ~(s = UNIV) ==> ~(s = t)``) THEN 15043 ASM_REWRITE_TAC[CLOSED_INTERVAL, OPEN_INTERVAL, NOT_INTERVAL_UNIV], 15044 STRIP_TAC THEN MATCH_MP_TAC(MESON[CLOPEN] 15045 ``closed s /\ open t /\ ~(s = {}) /\ ~(s = UNIV) ==> ~(t = s)``) THEN 15046 ASM_REWRITE_TAC[CLOSED_INTERVAL, OPEN_INTERVAL, NOT_INTERVAL_UNIV], 15047 REWRITE_TAC[INTERVAL_NE_EMPTY] THEN 15048 REWRITE_TAC[GSYM SUBSET_ANTISYM] THEN 15049 METIS_TAC [SUBSET_INTERVAL, GSYM REAL_LE_ANTISYM]]); 15050 15051val CLOSED_INTERVAL_EQ = store_thm ("CLOSED_INTERVAL_EQ", 15052 ``(!a b:real. closed(interval[a,b])) /\ 15053 (!a b:real. closed(interval(a,b)) <=> (interval(a,b) = {}))``, 15054 REWRITE_TAC[CLOSED_INTERVAL] THEN 15055 REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN 15056 ASM_REWRITE_TAC[CLOSED_EMPTY] THEN 15057 MP_TAC(ISPEC ``interval(a:real,b)`` CLOPEN) THEN 15058 ASM_REWRITE_TAC[OPEN_INTERVAL] THEN 15059 METIS_TAC[BOUNDED_INTERVAL, NOT_BOUNDED_UNIV]); 15060 15061val OPEN_INTERVAL_EQ = store_thm ("OPEN_INTERVAL_EQ", 15062 ``(!a b:real. open(interval[a,b]) <=> (interval[a,b] = {})) /\ 15063 (!a b:real. open(interval(a,b)))``, 15064 REWRITE_TAC[OPEN_INTERVAL] THEN 15065 REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN 15066 ASM_REWRITE_TAC[CLOSED_EMPTY] THEN 15067 MP_TAC(ISPEC ``interval[a:real,b]`` CLOPEN) THEN 15068 ASM_REWRITE_TAC[CLOSED_INTERVAL] THEN 15069 METIS_TAC[BOUNDED_INTERVAL, NOT_BOUNDED_UNIV]); 15070 15071val COMPACT_INTERVAL_EQ = store_thm ("COMPACT_INTERVAL_EQ", 15072 ``(!a b:real. compact(interval[a,b])) /\ 15073 (!a b:real. compact(interval(a,b)) <=> (interval(a,b) = {}))``, 15074 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTERVAL] THEN 15075 REWRITE_TAC[CLOSED_INTERVAL_EQ]); 15076 15077val EQ_BALLS = store_thm ("EQ_BALLS", 15078 ``(!a a':real r r'. 15079 (ball(a,r) = ball(a',r')) <=> (a = a') /\ (r = r') \/ r <= &0 /\ r' <= &0) /\ 15080 (!a a':real r r'. 15081 (ball(a,r) = cball(a',r')) <=> r <= &0 /\ r' < &0) /\ 15082 (!a a':real r r'. 15083 (cball(a,r) = ball(a',r')) <=> r < &0 /\ r' <= &0) /\ 15084 (!a a':real r r'. 15085 (cball(a,r) = cball(a',r')) <=> (a = a') /\ (r = r') \/ r < &0 /\ r' < &0)``, 15086 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT STRIP_TAC THEN 15087 (EQ_TAC THENL 15088 [ALL_TAC, REWRITE_TAC[EXTENSION, IN_BALL, IN_CBALL, dist] THEN REAL_ARITH_TAC]) 15089 THENL 15090 [SIMP_TAC std_ss [SET_EQ_SUBSET, SUBSET_BALLS, dist] THEN REAL_ARITH_TAC, 15091 ONCE_REWRITE_TAC[EQ_SYM_EQ], 15092 ALL_TAC, 15093 REWRITE_TAC[SET_EQ_SUBSET, SUBSET_BALLS, dist] THEN REAL_ARITH_TAC] THEN 15094 DISCH_THEN(MP_TAC o MATCH_MP (METIS [CLOPEN, BOUNDED_BALL, NOT_BOUNDED_UNIV] 15095 ``(s = t) ==> closed s /\ open t /\ bounded t ==> (s = {}) /\ (t = {})``)) THEN 15096 REWRITE_TAC[OPEN_BALL, CLOSED_CBALL, BOUNDED_BALL, 15097 BALL_EQ_EMPTY, CBALL_EQ_EMPTY] THEN 15098 REAL_ARITH_TAC); 15099 15100(* ------------------------------------------------------------------------- *) 15101(* Some special cases for intervals in R^1. *) 15102(* ------------------------------------------------------------------------- *) 15103 15104val INTERVAL_CASES = store_thm ("INTERVAL_CASES", 15105 ``!x:real. x IN interval[a,b] ==> x IN interval(a,b) \/ (x = a) \/ (x = b)``, 15106 REWRITE_TAC[IN_INTERVAL] THEN REAL_ARITH_TAC); 15107 15108val OPEN_CLOSED_INTERVAL = store_thm ("OPEN_CLOSED_INTERVAL", 15109 ``!a b:real. interval(a,b) = interval[a,b] DIFF {a;b}``, 15110 REWRITE_TAC[EXTENSION, IN_INTERVAL, IN_DIFF, IN_INSERT, NOT_IN_EMPTY] THEN 15111 SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 15112 15113val CLOSED_OPEN_INTERVAL = store_thm ("CLOSED_OPEN_INTERVAL", 15114 ``!a b:real. a <= b ==> (interval[a,b] = interval(a,b) UNION {a;b})``, 15115 REWRITE_TAC[EXTENSION, IN_INTERVAL, IN_UNION, IN_INSERT, NOT_IN_EMPTY] THEN 15116 SIMP_TAC std_ss [] THEN REAL_ARITH_TAC); 15117 15118val BALL = store_thm ("BALL", 15119 ``!x:real r. (cball(x,r) = interval[x - r,x + r]) /\ 15120 (ball(x,r) = interval(x - r,x + r))``, 15121 REWRITE_TAC[EXTENSION, IN_BALL, IN_CBALL, IN_INTERVAL] THEN 15122 REWRITE_TAC[dist] THEN REAL_ARITH_TAC); 15123 15124val SPHERE = store_thm ("SPHERE", 15125 ``!a:real r. sphere(a,r) = if r < (&0:real) then {} else {a - r;a + r}``, 15126 REPEAT GEN_TAC THEN REWRITE_TAC[sphere] THEN COND_CASES_TAC THEN 15127 SIMP_TAC std_ss [EXTENSION, IN_INSERT, NOT_IN_EMPTY, GSPECIFICATION, dist] THEN 15128 ASM_REAL_ARITH_TAC); 15129 15130val FINITE_SPHERE = store_thm ("FINITE_SPHERE", 15131 ``!a:real r. FINITE(sphere(a,r))``, 15132 REPEAT GEN_TAC THEN REWRITE_TAC[SPHERE] THEN 15133 METIS_TAC[FINITE_INSERT, FINITE_EMPTY]); 15134 15135val FINITE_INTERVAL = store_thm ("FINITE_INTERVAL", 15136 ``(!a b. FINITE(interval[a,b]) <=> b <= a) /\ 15137 (!a b. FINITE(interval(a,b)) <=> b <= a)``, 15138 REWRITE_TAC[OPEN_CLOSED_INTERVAL] THEN 15139 REWRITE_TAC[SET_RULE ``s DIFF {a;b} = s DELETE a DELETE b``] THEN 15140 REWRITE_TAC[FINITE_DELETE] THEN REPEAT GEN_TAC THEN 15141 SIMP_TAC std_ss [interval, FINITE_IMAGE_INJ_EQ, FINITE_REAL_INTERVAL]); 15142 15143val BALL_INTERVAL = store_thm ("BALL_INTERVAL", 15144 ``!x:real e. ball(x,e) = interval(x - e,x + e)``, 15145 REWRITE_TAC[EXTENSION, IN_BALL, IN_INTERVAL, dist] THEN 15146 REAL_ARITH_TAC); 15147 15148val CBALL_INTERVAL = store_thm ("CBALL_INTERVAL", 15149 ``!x:real e. cball(x,e) = interval[x - e,x + e]``, 15150 REWRITE_TAC[EXTENSION, IN_CBALL, IN_INTERVAL, dist] THEN 15151 REAL_ARITH_TAC); 15152 15153val BALL_INTERVAL_0 = store_thm ("BALL_INTERVAL_0", 15154 ``!e. ball(0:real,e) = interval(-e,e)``, 15155 GEN_TAC THEN REWRITE_TAC[BALL_INTERVAL] THEN AP_TERM_TAC THEN 15156 BINOP_TAC THEN REAL_ARITH_TAC); 15157 15158val CBALL_INTERVAL_0 = store_thm ("CBALL_INTERVAL_0", 15159 ``!e. cball(0:real,e) = interval[-e,e]``, 15160 GEN_TAC THEN REWRITE_TAC[CBALL_INTERVAL] THEN AP_TERM_TAC THEN 15161 AP_THM_TAC THEN AP_TERM_TAC THEN BINOP_TAC THEN REAL_ARITH_TAC); 15162 15163val CLOSED_DIFF_OPEN_INTERVAL = store_thm ("CLOSED_DIFF_OPEN_INTERVAL", 15164 ``!a b:real. 15165 interval[a,b] DIFF interval(a,b) = 15166 if interval[a,b] = {} then {} else {a;b}``, 15167 REWRITE_TAC[EXTENSION, IN_DIFF, GSYM INTERVAL_EQ_EMPTY, IN_INTERVAL] THEN 15168 REPEAT GEN_TAC THEN COND_CASES_TAC THEN 15169 ASM_REWRITE_TAC[NOT_IN_EMPTY, IN_INSERT, NOT_IN_EMPTY] THEN 15170 FULL_SIMP_TAC std_ss [NOT_IN_EMPTY] THEN 15171 ASM_REAL_ARITH_TAC); 15172 15173val INTERVAL = store_thm ("INTERVAL", 15174 ``(!a b:real. interval[a,b] = 15175 if a <= b then cball(midpoint(a,b),dist(a,b) / &2) 15176 else {}) /\ 15177 (!a b:real. interval(a,b) = 15178 if a < b then ball(midpoint(a,b),dist(a,b) / &2) 15179 else {})``, 15180 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN 15181 RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE, REAL_NOT_LT]) THEN 15182 ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN 15183 REWRITE_TAC[BALL, dist] THEN 15184 ASM_SIMP_TAC std_ss [REAL_SUB_LE, REAL_LT_IMP_LE, 15185 REAL_ARITH ``a <= b ==> (abs(a - b) = b - a:real)``] THEN 15186 REWRITE_TAC[METIS [real_div, REAL_MUL_SYM] ``x / &2 = inv(&2:real) * x``] THEN 15187 REWRITE_TAC[midpoint] THEN 15188 TRY AP_TERM_TAC THEN ASM_SIMP_TAC std_ss [PAIR_EQ, CONS_11, GSYM INTERVAL_EQ_EMPTY] THEN 15189 REWRITE_TAC [GSYM REAL_SUB_LDISTRIB, GSYM REAL_ADD_LDISTRIB] THEN 15190 REWRITE_TAC [REAL_ARITH ``a + b - (b - a) = 2 * a:real``] THEN 15191 REWRITE_TAC [REAL_ARITH ``a + b + (b - a) = 2 * b:real``] THEN 15192 SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_ARITH ``2 <> 0:real``, REAL_MUL_LINV] THEN REAL_ARITH_TAC); 15193 15194val SEGMENT = store_thm ("SEGMENT", 15195 ``(!a b. segment[a,b] = 15196 if a <= b then interval[a,b] else interval[b,a]) /\ 15197 (!a b. segment(a,b) = 15198 if a <= b then interval(a,b) else interval(b,a))``, 15199 CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN 15200 COND_CASES_TAC THEN 15201 REWRITE_TAC[IN_DIFF, IN_INSERT, NOT_IN_EMPTY, 15202 EXTENSION, GSYM BETWEEN_IN_SEGMENT, between, IN_INTERVAL] THEN 15203 REWRITE_TAC[dist] THEN ASM_REAL_ARITH_TAC); 15204 15205val OPEN_SEGMENT = store_thm ("OPEN_SEGMENT", 15206 ``!a b:real. open(segment(a,b))``, 15207 REPEAT GEN_TAC THEN REWRITE_TAC[SEGMENT] THEN 15208 COND_CASES_TAC THEN REWRITE_TAC[OPEN_INTERVAL]); 15209 15210val SEGMENT_SCALAR_MULTIPLE = store_thm ("SEGMENT_SCALAR_MULTIPLE", 15211 ``(!a b v:real. segment[a * v,b * v] = 15212 {x * v:real | a <= x /\ x <= b \/ b <= x /\ x <= a}) /\ 15213 (!a b v:real. ~(v = 0) 15214 ==> (segment(a * v,b * v) = 15215 {x * v:real | a < x /\ x < b \/ b < x /\ x < a}))``, 15216 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN REPEAT STRIP_TAC THENL 15217 [REPEAT GEN_TAC THEN 15218 MP_TAC(SPECL [``a * 1:real``, ``b * 1:real``] 15219 (CONJUNCT1 SEGMENT)) THEN 15220 REWRITE_TAC[segment, REAL_MUL_ASSOC, GSYM REAL_ADD_RDISTRIB] THEN 15221 ONCE_REWRITE_TAC [METIS [] ``((1 - u) * a + u * b:real) = 15222 (\u. ((1 - u) * a + u * b)) u``] THEN 15223 ONCE_REWRITE_TAC [METIS [] ``(0 <= u /\ u <= 1:real) = 15224 (\u. 0 <= u /\ u <= 1) u``] THEN 15225 ONCE_REWRITE_TAC [METIS [] 15226 ``{x:real * v | a <= x /\ x <= b \/ b <= x /\ x <= a} = 15227 {(\x. x) x * v | (\x. a <= x /\ x <= b \/ b <= x /\ x <= a) x}``] THEN 15228 REWRITE_TAC [SET_RULE ``{f x * b:real | p (x:real)} = 15229 IMAGE (\a. a * b) {f x | p x}``] THEN 15230 BETA_TAC THEN DISCH_TAC THEN AP_TERM_TAC THEN 15231 FIRST_X_ASSUM(MP_TAC o SIMP_RULE std_ss [REAL_MUL_RID, IMAGE_ID]) THEN 15232 DISCH_THEN SUBST1_TAC THEN COND_CASES_TAC THEN 15233 SIMP_TAC std_ss [EXTENSION, IN_INTERVAL, GSPECIFICATION] THEN ASM_REAL_ARITH_TAC, 15234 ASM_REWRITE_TAC[open_segment] THEN 15235 ONCE_REWRITE_TAC [METIS [] ``{x * v | a <= x /\ x <= b \/ b <= x /\ x <= a:real} = 15236 {(\x. x) x * v | (\x. a <= x /\ x <= b \/ b <= x /\ x <= a) x}``] THEN 15237 ASM_SIMP_TAC std_ss [REAL_EQ_RMUL, SET_RULE 15238 ``(!x y:real. (x * v = y * v) <=> (x = y)) 15239 ==> ({x * v | P x} DIFF {a * v;b * v} = 15240 {x * v | P x /\ ~(x = a) /\ ~(x = b)})``] THEN 15241 ONCE_REWRITE_TAC [SET_RULE 15242 ``{x * v | (a <= x /\ x <= b \/ b <= x /\ x <= a) /\ x <> a /\ x <> b:real} = 15243 {(\x. x * v) x | x IN (\x. (a <= x /\ x <= b \/ b <= x /\ x <= a) /\ x <> a /\ x <> b)}``] THEN 15244 ONCE_REWRITE_TAC [SET_RULE 15245 ``{x * v | a < x /\ x < b \/ b < x /\ x < a:real} = 15246 {(\x. x * v) x | x IN (\x. (a < x /\ x < b \/ b < x /\ x < a))}``] THEN 15247 ONCE_REWRITE_TAC[GSYM IMAGE_DEF] THEN AP_TERM_TAC THEN 15248 ABS_TAC THEN REAL_ARITH_TAC]); 15249 15250(* ------------------------------------------------------------------------- *) 15251(* Intervals in general, including infinite and mixtures of open and closed. *) 15252(* ------------------------------------------------------------------------- *) 15253 15254val is_interval = new_definition ("is_interval", 15255 ``is_interval(s:real->bool) <=> 15256 !a b x. a IN s /\ b IN s 15257 ==> (a <= x /\ x <= b) \/ 15258 (b <= x /\ x <= a) 15259 ==> x IN s``); 15260 15261val IS_INTERVAL_INTERVAL = store_thm ("IS_INTERVAL_INTERVAL", 15262 ``!a:real b. is_interval(interval (a,b)) /\ is_interval(interval [a,b])``, 15263 REWRITE_TAC[is_interval, IN_INTERVAL] THEN 15264 METIS_TAC[REAL_LT_TRANS, REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS]); 15265 15266val IS_INTERVAL_EMPTY = store_thm ("IS_INTERVAL_EMPTY", 15267 ``is_interval {}``, 15268 REWRITE_TAC[is_interval, NOT_IN_EMPTY]); 15269 15270val IS_INTERVAL_UNIV = store_thm ("IS_INTERVAL_UNIV", 15271 ``is_interval(UNIV:real->bool)``, 15272 REWRITE_TAC[is_interval, IN_UNIV]); 15273 15274val IS_INTERVAL_POINTWISE = store_thm ("IS_INTERVAL_POINTWISE", 15275 ``!s:real->bool x. 15276 is_interval s ==> (?a. a IN s /\ (a = x)) 15277 ==> x IN s``, 15278 METIS_TAC [is_interval]); 15279 15280val IS_INTERVAL_COMPACT = store_thm ("IS_INTERVAL_COMPACT", 15281 ``!s:real->bool. is_interval s /\ compact s <=> ?a b. s = interval[a,b]``, 15282 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN 15283 ASM_SIMP_TAC std_ss [IS_INTERVAL_INTERVAL, COMPACT_INTERVAL] THEN 15284 ASM_CASES_TAC ``s:real->bool = {}`` 15285 >- ASM_MESON_TAC[EMPTY_AS_INTERVAL] THEN (* one goal left *) 15286 15287 EXISTS_TAC ``(@f. f = inf { (x:real) | x IN s}):real`` THEN 15288 EXISTS_TAC ``(@f. f = sup { (x:real) | x IN s}):real`` THEN 15289 SIMP_TAC std_ss [EXTENSION, IN_INTERVAL] THEN X_GEN_TAC ``x:real`` THEN 15290 EQ_TAC THENL (* 2 subgoals *) 15291 [ (* goal 1 (of 2) *) 15292 DISCH_TAC THEN 15293 MP_TAC(ISPEC ``{ (x:real) | x IN s}`` INF) THEN 15294 MP_TAC(ISPEC ``{ (x:real) | x IN s}`` SUP) THEN 15295 SIMP_TAC std_ss [METIS [] ``x = (\x. x) x``, GSYM IMAGE_DEF] THEN 15296 ASM_SIMP_TAC std_ss [IMAGE_EQ_EMPTY, FORALL_IN_IMAGE] THEN 15297 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN 15298 REWRITE_TAC[bounded_def] THEN 15299 ASM_MESON_TAC[REAL_LE_TRANS, MEMBER_NOT_EMPTY, 15300 REAL_ARITH ``abs(x) <= B ==> -B <= x /\ x <= B:real``], 15301 (* goal 2 (of 2) *) 15302 DISCH_TAC THEN 15303 SUFF_TAC ``?a:real. a IN s /\ (a = x)`` 15304 >- ( MATCH_MP_TAC IS_INTERVAL_POINTWISE >> ASM_REWRITE_TAC [] ) THEN 15305 SUBGOAL_THEN 15306 ``?a b:real. a IN s /\ b IN s /\ a <= (x:real) /\ x <= b`` 15307 STRIP_ASSUME_TAC THENL (* 2 subgoals *) 15308 [ (* goal 2.1 (of 2) *) 15309 MP_TAC (ISPECL [``\x:real. x``, ``s:real->bool``] 15310 CONTINUOUS_ATTAINS_INF) THEN 15311 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ID, o_DEF] THEN 15312 DISCH_THEN (X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 15313 EXISTS_TAC ``a:real`` THEN 15314 MP_TAC (ISPECL [``\x:real. x``, ``s:real->bool``] 15315 CONTINUOUS_ATTAINS_SUP) THEN 15316 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ID, o_DEF] THEN 15317 DISCH_THEN (X_CHOOSE_THEN ``b:real`` STRIP_ASSUME_TAC) THEN 15318 EXISTS_TAC ``b:real`` THEN 15319 ASM_REWRITE_TAC [] THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THENL (* 2 subgoals *) 15320 [ (* goal 2.1.1 (of 2) *) 15321 EXISTS_TAC ``inf {(x:real) | x IN s}`` THEN ASM_SIMP_TAC std_ss [] THEN 15322 MATCH_MP_TAC REAL_LE_INF THEN 15323 ONCE_REWRITE_TAC [METIS [SPECIFICATION] ``{x | x IN s} x = x IN {x | x IN s}``] THEN 15324 ASM_SET_TAC [], 15325 (* goal 2.1.2 (of 2) *) 15326 EXISTS_TAC ``sup {(x:real) | x IN s}`` THEN ASM_SIMP_TAC std_ss [] THEN 15327 15328 MATCH_MP_TAC REAL_SUP_LE_S THEN 15329 ONCE_REWRITE_TAC [METIS [SPECIFICATION] ``{x | x IN s} x = x IN {x | x IN s}``] THEN 15330 ASM_SET_TAC [] ], 15331 (* goal 2.2 (of 2) *) 15332 EXISTS_TAC ``x:real`` THEN ASM_SIMP_TAC std_ss [] THEN 15333 UNDISCH_TAC ``is_interval s`` THEN DISCH_TAC THEN 15334 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[is_interval, AND_IMP_INTRO]) THEN 15335 MAP_EVERY EXISTS_TAC [``a:real``, ``b:real``] THEN 15336 ASM_SIMP_TAC std_ss []]]); 15337 15338val IS_INTERVAL = store_thm ("IS_INTERVAL", 15339 ``!s:real->bool. 15340 is_interval s <=> 15341 !a b x. a IN s /\ b IN s /\ a <= x /\ x <= b 15342 ==> x IN s``, 15343 REWRITE_TAC[is_interval] THEN MESON_TAC[]); 15344 15345val IS_INTERVAL_CASES = store_thm ("IS_INTERVAL_CASES", 15346 ``!s:real->bool. 15347 is_interval s <=> 15348 (s = {}) \/ 15349 (s = univ(:real)) \/ 15350 (?a. s = {x | a < x}) \/ 15351 (?a. s = {x | a <= x}) \/ 15352 (?b. s = {x | x <= b}) \/ 15353 (?b. s = {x | x < b}) \/ 15354 (?a b. s = {x | a < x /\ x < b}) \/ 15355 (?a b. s = {x | a < x /\ x <= b}) \/ 15356 (?a b. s = {x | a <= x /\ x < b}) \/ 15357 (?a b. s = {x | a <= x /\ x <= b})``, 15358 GEN_TAC THEN REWRITE_TAC[IS_INTERVAL] THEN EQ_TAC THENL 15359 [DISCH_TAC, 15360 STRIP_TAC THEN ASM_SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, NOT_IN_EMPTY] THEN 15361 REAL_ARITH_TAC] THEN 15362 ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[] THEN 15363 MP_TAC(ISPEC ``s:real->bool`` SUP) THEN 15364 MP_TAC(ISPEC ``s:real->bool`` INF) THEN 15365 ASM_SIMP_TAC std_ss [IMAGE_EQ_EMPTY, FORALL_IN_IMAGE] THEN 15366 ASM_CASES_TAC ``?a. !x:real. x IN s ==> a <= x`` THEN 15367 ASM_CASES_TAC ``?b. !x:real. x IN s ==> x <= b`` THEN 15368 ASM_REWRITE_TAC[] THENL 15369 [STRIP_TAC THEN STRIP_TAC THEN 15370 MAP_EVERY ASM_CASES_TAC 15371 [``inf(s) IN s:real->bool``, ``sup(s) IN s:real->bool``] 15372 THENL 15373 [DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN 15374 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC, 15375 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN 15376 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC, 15377 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN 15378 DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC, 15379 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN 15380 DISJ2_TAC THEN DISJ1_TAC] THEN 15381 MAP_EVERY EXISTS_TAC [``inf(s:real->bool)``, ``sup(s:real->bool)``], 15382 STRIP_TAC THEN ASM_CASES_TAC ``inf(s:real->bool) IN s`` THENL 15383 [DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC, 15384 DISJ2_TAC THEN DISJ1_TAC] THEN 15385 EXISTS_TAC ``inf(s:real->bool)``, 15386 STRIP_TAC THEN ASM_CASES_TAC ``sup(s:real->bool) IN s`` THENL 15387 [DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC, 15388 DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN 15389 DISJ1_TAC] THEN 15390 EXISTS_TAC ``sup(s:real->bool)``, 15391 DISJ1_TAC] THEN 15392 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_UNIV] THEN 15393 RULE_ASSUM_TAC(REWRITE_RULE[IN_IMAGE]) THEN 15394 REWRITE_TAC[GSYM REAL_NOT_LE] THEN 15395 ASM_MESON_TAC [REAL_LE_TRANS, REAL_LE_TOTAL, REAL_LE_ANTISYM]); 15396 15397val IS_INTERVAL_INTER = store_thm ("IS_INTERVAL_INTER", 15398 ``!s t:real->bool. 15399 is_interval s /\ is_interval t ==> is_interval(s INTER t)``, 15400 REWRITE_TAC[is_interval, IN_INTER] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN 15401 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``, ``x:real``] THEN 15402 REPEAT STRIP_TAC THENL 15403 [UNDISCH_TAC ``!a b x. 15404 a IN s /\ b IN s ==> 15405 a <= x /\ x <= b \/ b <= x /\ x <= a ==> 15406 x IN s:real->bool`` THEN DISCH_TAC THEN 15407 FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO]), 15408 UNDISCH_TAC ``!a b x. 15409 a IN t /\ b IN t ==> 15410 a <= x /\ x <= b \/ b <= x /\ x <= a ==> 15411 x IN t:real->bool`` THEN DISCH_TAC THEN 15412 FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO]), 15413 UNDISCH_TAC ``!a b x. 15414 a IN s /\ b IN s ==> 15415 a <= x /\ x <= b \/ b <= x /\ x <= a ==> 15416 x IN s:real->bool`` THEN DISCH_TAC THEN 15417 FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO]), 15418 UNDISCH_TAC ``!a b x. 15419 a IN t /\ b IN t ==> 15420 a <= x /\ x <= b \/ b <= x /\ x <= a ==> 15421 x IN t:real->bool`` THEN DISCH_TAC THEN 15422 FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO])] THEN 15423 MAP_EVERY EXISTS_TAC [``a:real``, ``b:real``] THEN ASM_REWRITE_TAC[]); 15424 15425val INTERVAL_SUBSET_IS_INTERVAL = store_thm ("INTERVAL_SUBSET_IS_INTERVAL", 15426 ``!s a b:real. 15427 is_interval s 15428 ==> (interval[a,b] SUBSET s <=> (interval[a,b] = {}) \/ a IN s /\ b IN s)``, 15429 REWRITE_TAC[is_interval] THEN REPEAT STRIP_TAC THEN 15430 ASM_CASES_TAC ``interval[a:real,b] = {}`` THEN 15431 ASM_REWRITE_TAC[EMPTY_SUBSET] THEN 15432 EQ_TAC THENL [ASM_MESON_TAC[ENDS_IN_INTERVAL, SUBSET_DEF], ALL_TAC] THEN 15433 REWRITE_TAC[SUBSET_DEF, IN_INTERVAL] THEN ASM_MESON_TAC[]); 15434 15435val INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD = store_thm 15436 ("INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD", 15437 ``!s x:real. 15438 is_interval s /\ x IN s 15439 ==> ?a b d. &0 < d /\ x IN interval[a,b] /\ 15440 interval[a,b] SUBSET s /\ 15441 ball(x,d) INTER s SUBSET interval[a,b]``, 15442 REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [INTERVAL_SUBSET_IS_INTERVAL] THEN 15443 SUBGOAL_THEN ``?a. (?y. y IN s /\ (y = a)) /\ 15444 (a < x \/ (a = (x:real)) /\ 15445 !y:real. y IN s ==> a <= y)`` 15446 MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT], SIMP_TAC std_ss []] THEN 15447 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 15448 SUBGOAL_THEN 15449 ``?b. (?y. y IN s /\ (y = b)) /\ 15450 (x < b \/ (b = (x:real)) /\ 15451 !y:real. y IN s ==> y <= b)`` 15452 MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT], SIMP_TAC std_ss []] THEN 15453 DISCH_THEN (X_CHOOSE_TAC ``b:real``) THEN EXISTS_TAC ``b:real`` THEN 15454 EXISTS_TAC ``min (if a < x then (x:real) - a else &1) 15455 (if x < b then (b:real) - x else &1)`` THEN 15456 REWRITE_TAC[REAL_LT_MIN, SUBSET_DEF, IN_BALL, IN_INTER] THEN 15457 SIMP_TAC std_ss [REAL_LT_INF_FINITE, IMAGE_EQ_EMPTY, IMAGE_FINITE, 15458 FINITE_NUMSEG, NUMSEG_EMPTY, GSYM NOT_LESS_EQUAL] THEN 15459 SIMP_TAC std_ss [FORALL_IN_IMAGE, IN_INTERVAL] THEN REPEAT CONJ_TAC THENL 15460 [METIS_TAC[REAL_SUB_LT, REAL_LT_01], 15461 METIS_TAC[REAL_SUB_LT, REAL_LT_01], 15462 ASM_MESON_TAC[REAL_LE_LT], 15463 ASM_MESON_TAC[REAL_LE_LT], 15464 METIS_TAC [], ALL_TAC] THEN 15465 X_GEN_TAC ``y:real`` THEN 15466 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 15467 MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN 15468 (COND_CASES_TAC THENL [REWRITE_TAC[dist], ASM_MESON_TAC[]]) THEN 15469 REWRITE_TAC [abs] THEN COND_CASES_TAC THEN DISCH_TAC THENL 15470 [FULL_SIMP_TAC std_ss [REAL_ARITH ``x - y < x - a = a < y:real``, REAL_LE_LT], 15471 FULL_SIMP_TAC std_ss [REAL_NOT_LE, REAL_ARITH ``x - y < 0 = x < y:real``] THEN 15472 METIS_TAC [REAL_LE_TRANS, REAL_LE_LT], 15473 FULL_SIMP_TAC std_ss [REAL_SUB_LE] THEN METIS_TAC [REAL_LE_TRANS, REAL_LE_LT], 15474 FULL_SIMP_TAC std_ss [REAL_NEG_SUB, 15475 REAL_ARITH ``y - x < b - x = y < b:real``, REAL_LE_LT]]); 15476 15477(* TODO: 15478val IS_INTERVAL_SUMS = store_thm ("IS_INTERVAL_SUMS", 15479 ``!s t:real->bool. 15480 is_interval s /\ is_interval t 15481 ==> is_interval {x + y | x IN s /\ y IN t}``, 15482 REPEAT GEN_TAC THEN REWRITE_TAC[is_interval] THEN 15483 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 15484 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 15485 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN 15486 REWRITE_TAC [AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN 15487 MAP_EVERY X_GEN_TAC 15488 [``a:real``, ``a':real``, ``b:real``, ``b':real``, ``y:real``] THEN 15489 DISCH_THEN (CONJUNCTS_THEN2 15490 (MP_TAC o SPECL [``a:real``, ``b:real``]) MP_TAC) THEN 15491 DISCH_THEN (CONJUNCTS_THEN2 15492 (MP_TAC o SPECL [``a':real``, ``b':real``]) ASSUME_TAC) THEN 15493 ASM_SIMP_TAC std_ss [AND_IMP_INTRO, GSPECIFICATION, EXISTS_PROD] THEN 15494 ONCE_REWRITE_TAC[REAL_ARITH ``(z:real = x + y) <=> (y = z - x)``] THEN 15495 SIMP_TAC std_ss [UNWIND_THM2] THEN 15496 ONCE_REWRITE_TAC [METIS [] 15497 ``!a b s. (!x. a <= x /\ x <= b \/ b <= x /\ x <= a ==> x IN s:real->bool) = 15498 (!x. (\x. a <= x /\ x <= b \/ b <= x /\ x <= a) x ==> x IN s)``] THEN 15499 ONCE_REWRITE_TAC [METIS [] ``(y - p_1) = (\x. y - x) (p_1:real)``] THEN 15500 MATCH_MP_TAC (METIS [] 15501 ``(?x. P x /\ Q(f x)) 15502 ==> (!x. Q x ==> x IN t) /\ (!x. P x ==> x IN s) 15503 ==> ?x. x IN s /\ f x IN t``) THEN 15504 POP_ASSUM MP_TAC THEN 15505 DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 15506 DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 15507 DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 15508 DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 15509 SIMP_TAC std_ss [REAL_ARITH 15510 ``c <= y - x /\ y - x <= d <=> y - d <= x /\ x <= y - c:real``] THEN 15511 KNOW_TAC 15512 ``!x. a <= x /\ x <= b \/ b <= x /\ x <= a:real <=> 15513 (if a <= b then a else b) <= x /\ x <= if a <= b then b else a`` 15514 >- ( GEN_TAC >> COND_CASES_TAC >> SIMP_TAC std_ss [] >> ASM_REAL_ARITH_TAC ) THEN 15515 Rewr' THEN 15516 REWRITE_TAC [GSYM min_def, GSYM max_def] THEN 15517 STRIP_TAC >| (* 2 subgoals *) 15518 [ (* goal 1 (of 2) *) 15519 SIMP_TAC std_ss [min_def, max_def] THEN REPEAT COND_CASES_TAC THEN 15520 SIMP_TAC std_ss [] >| (* 2 subgoals *) 15521 [ (* goal 1.1 (of 2) *) 15522 15523 15524 ONCE_REWRITE_TAC [TAUT `(p /\ q) /\ (r /\ s) <=> (p /\ r) \/ (q /\ s)`] THEN 15525 REWRITE_TAC[GSYM REAL_LE_MIN, GSYM REAL_MAX_LE] THEN 15526 REWRITE_TAC[GSYM REAL_LE_BETWEEN] THEN 15527 SIMP_TAC std_ss [min_def, max_def] THEN REPEAT COND_CASES_TAC THEN 15528 FULL_SIMP_TAC std_ss [] THEN ASM_REAL_ARITH_TAC); 15529*) 15530 15531val IS_INTERVAL_SING = store_thm ("IS_INTERVAL_SING", 15532 ``!a:real. is_interval {a}``, 15533 SIMP_TAC std_ss [is_interval, IN_SING, CONJ_EQ_IMP, REAL_LE_ANTISYM]); 15534 15535val IS_INTERVAL_SCALING = store_thm ("IS_INTERVAL_SCALING", 15536 ``!s:real->bool c. is_interval s ==> is_interval(IMAGE (\x. c * x) s)``, 15537 REPEAT GEN_TAC THEN ASM_CASES_TAC ``c = &0:real`` THENL 15538 [ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN 15539 SUBGOAL_THEN ``(IMAGE ((\x. 0):real->real) (s:real->bool) = {}) \/ 15540 (IMAGE ((\x. 0):real->real) s = {0})`` 15541 STRIP_ASSUME_TAC THENL 15542 [SET_TAC[], 15543 ASM_REWRITE_TAC[IS_INTERVAL_EMPTY], 15544 ASM_REWRITE_TAC[IS_INTERVAL_SING]], 15545 SIMP_TAC std_ss [is_interval, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 15546 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN DISCH_TAC THEN 15547 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN 15548 POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_FORALL_THM]) THEN 15549 REWRITE_TAC[AND_IMP_INTRO] THEN 15550 DISCH_TAC THEN MAP_EVERY X_GEN_TAC [``a:real``,``b:real``] THEN 15551 POP_ASSUM (MP_TAC o Q.SPECL [`a:real`,`b:real`]) THEN 15552 DISCH_THEN(fn th => X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 15553 MP_TAC(SPEC ``inv(c) * x:real`` th)) THEN 15554 ASM_SIMP_TAC std_ss [IN_IMAGE] THEN 15555 KNOW_TAC ``a <= inv c * x /\ inv c * x <= b \/ 15556 b <= inv c * x /\ inv c * x <= a:real`` THENL 15557 [FIRST_X_ASSUM(MP_TAC) THEN 15558 DISCH_THEN (CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN 15559 ASM_REWRITE_TAC[] THEN 15560 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN 15561 UNDISCH_TAC ``c <> 0:real`` THEN DISCH_TAC THEN 15562 FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH 15563 ``~(c = &0:real) ==> &0 < c \/ &0 < -c``)) THEN 15564 ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ] THEN 15565 GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_LE_NEG2] THEN 15566 ASM_SIMP_TAC std_ss [GSYM REAL_MUL_RNEG, GSYM REAL_LE_RDIV_EQ, GSYM 15567 REAL_LE_LDIV_EQ] THEN 15568 ASM_SIMP_TAC std_ss [real_div, GSYM REAL_NEG_INV] THEN REAL_ARITH_TAC, 15569 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 15570 DISCH_TAC THEN EXISTS_TAC ``inv c * x:real`` THEN 15571 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_MUL_LID]]]); 15572 15573val IS_INTERVAL_SCALING_EQ = store_thm ("IS_INTERVAL_SCALING_EQ", 15574 ``!s:real->bool c. 15575 is_interval(IMAGE (\x. c * x) s) <=> (c = &0) \/ is_interval s``, 15576 REPEAT GEN_TAC THEN ASM_CASES_TAC ``c = &0:real`` THENL 15577 [ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN 15578 SUBGOAL_THEN ``(IMAGE ((\x. 0):real->real) s = {}) \/ 15579 (IMAGE ((\x. 0):real->real) s = {0})`` 15580 STRIP_ASSUME_TAC THENL 15581 [SET_TAC[], 15582 ASM_REWRITE_TAC[IS_INTERVAL_EMPTY], 15583 ASM_REWRITE_TAC[IS_INTERVAL_SING]], 15584 ASM_REWRITE_TAC[] THEN EQ_TAC THEN REWRITE_TAC[IS_INTERVAL_SCALING] THEN 15585 DISCH_THEN(MP_TAC o SPEC ``inv c:real`` o MATCH_MP IS_INTERVAL_SCALING) THEN 15586 ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, REAL_MUL_ASSOC, o_DEF, REAL_MUL_LINV, 15587 REAL_MUL_LID, IMAGE_ID]]); 15588 15589val lemma0 = prove ((* unused *) 15590 ``!c. &0 < c 15591 ==> !s:real->bool. is_interval(IMAGE (\x. c * x) s) <=> 15592 is_interval s``, 15593 SIMP_TAC std_ss [IS_INTERVAL_SCALING_EQ, REAL_LT_IMP_NE]); 15594 15595val lemma = prove ( 15596 ``~(?a b c:real. a < b /\ b < c /\ 15597 a IN s /\ b IN s /\ c IN s) 15598 ==> FINITE s /\ CARD(s) <= 2``, 15599 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 15600 REWRITE_TAC[TAUT `~(p /\ q) <=> p ==> ~q`] THEN 15601 REWRITE_TAC[ARITH_PROVE ``~(n <= 2) <=> 3 <= n:num``] THEN 15602 DISCH_THEN(MP_TAC o MATCH_MP CHOOSE_SUBSET_STRONG) THEN 15603 REWRITE_TAC [ARITH_PROVE ``3 = SUC 2``, TWO, ONE, HAS_SIZE_CLAUSES] THEN 15604 DISCH_TAC THEN KNOW_TAC ``(?a b c:real. 15605 ((~(b = c) /\ ~(a = c)) /\ ~(a = b)) /\ {a; b; c} SUBSET s)`` THENL 15606 [POP_ASSUM MP_TAC THEN 15607 REWRITE_TAC [ARITH_PROVE ``3 = SUC 2``, TWO, ONE, HAS_SIZE_CLAUSES] THEN 15608 SET_TAC [], POP_ASSUM K_TAC] THEN 15609 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, GSYM CONJ_ASSOC] THEN 15610 REWRITE_TAC[INSERT_SUBSET, EMPTY_SUBSET] THEN 15611 ONCE_REWRITE_TAC [METIS [] 15612 ``(b <> c /\ a <> c /\ a <> b /\ a IN s /\ b IN s /\ c IN s ==> 15613 ?a b c:real. a < b /\ b < c /\ a IN s /\ b IN s /\ c IN s) = 15614 (\a b c. b <> c /\ a <> c /\ a <> b /\ a IN s /\ b IN s /\ c IN s ==> 15615 ?a b c:real. a < b /\ b < c /\ a IN s /\ b IN s /\ c IN s) a b c``] THEN 15616 MATCH_MP_TAC(METIS [REAL_LE_TOTAL] 15617 ``(!m n p:real. P m n p ==> P n p m /\ P n m p) /\ 15618 (!m n p. m <= n /\ n <= p ==> P m n p) 15619 ==> !m n p. P m n p``) THEN 15620 CONJ_TAC THENL [METIS_TAC[], ALL_TAC] THEN 15621 SIMP_TAC std_ss [REAL_LT_LE] THEN METIS_TAC[]); 15622 15623val CARD_FRONTIER_INTERVAL = store_thm ("CARD_FRONTIER_INTERVAL", 15624 ``!s:real->bool. 15625 is_interval s ==> FINITE(frontier s) /\ CARD(frontier s) <= 2``, 15626 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC lemma THEN 15627 SIMP_TAC std_ss [NOT_EXISTS_THM, FRONTIER_CLOSURES, IN_INTER] THEN 15628 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``, ``c:real``] THEN 15629 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 15630 MAP_EVERY UNDISCH_TAC 15631 [``b IN closure (univ(:real) DIFF s)``, 15632 ``(a:real) IN closure s``, ``(c:real) IN closure s``] THEN 15633 SIMP_TAC std_ss [CLOSURE_APPROACHABLE, IN_DIFF, IN_UNIV, dist] THEN 15634 DISCH_THEN(MP_TAC o SPEC ``(c - b) / &2:real``) THEN 15635 ASM_REWRITE_TAC[REAL_HALF, REAL_SUB_LT] THEN 15636 DISCH_THEN(X_CHOOSE_THEN ``v:real`` STRIP_ASSUME_TAC) THEN 15637 DISCH_THEN(MP_TAC o SPEC ``(b - a) / &2:real``) THEN 15638 ASM_REWRITE_TAC[REAL_HALF, REAL_SUB_LT] THEN 15639 DISCH_THEN(X_CHOOSE_THEN ``u:real`` STRIP_ASSUME_TAC) THEN 15640 EXISTS_TAC ``min ((b - a) / &2:real) ((c - b) / &2:real)`` THEN 15641 ASM_REWRITE_TAC[REAL_HALF, REAL_SUB_LT, REAL_LT_MIN] THEN 15642 X_GEN_TAC ``w:real`` THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 15643 UNDISCH_TAC ``is_interval s`` THEN DISCH_TAC THEN 15644 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [IS_INTERVAL]) THEN 15645 DISCH_THEN(MP_TAC o SPECL [``u:real``, ``v:real``, ``w:real``]) THEN 15646 ASM_REWRITE_TAC[] THEN FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 15647 ASM_REAL_ARITH_TAC); 15648 15649(* ------------------------------------------------------------------------- *) 15650(* Limit component bounds. *) 15651(* ------------------------------------------------------------------------- *) 15652 15653val LIM_COMPONENT_UBOUND = store_thm ("LIM_COMPONENT_UBOUND", 15654 ``!net:('a)net f (l:real) b k. 15655 ~(trivial_limit net) /\ (f --> l) net /\ 15656 eventually (\x. f x <= b) net 15657 ==> l <= b``, 15658 REPEAT STRIP_TAC THEN MP_TAC(ISPECL 15659 [``net:('a)net``, ``f:'a->real``, ``{y:real | y <= b}``, ``l:real``] 15660 LIM_IN_CLOSED_SET) THEN 15661 ASM_SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_LE, GSPECIFICATION]); 15662 15663val LIM_COMPONENT_LBOUND = store_thm ("LIM_COMPONENT_LBOUND", 15664 ``!net:('a)net f (l:real) b. 15665 ~(trivial_limit net) /\ (f --> l) net /\ 15666 eventually (\x. b <= (f x)) net 15667 ==> b <= l``, 15668 REPEAT STRIP_TAC THEN MP_TAC(ISPECL 15669 [``net:('a)net``, ``f:'a->real``, ``{y:real | b <= y}``, ``l:real``] 15670 LIM_IN_CLOSED_SET) THEN 15671 ASM_SIMP_TAC std_ss [REWRITE_RULE[real_ge] CLOSED_HALFSPACE_COMPONENT_GE, 15672 GSPECIFICATION]); 15673 15674val LIM_COMPONENT_EQ = store_thm ("LIM_COMPONENT_EQ", 15675 ``!net f:'a->real i l b. 15676 (f --> l) net /\ 15677 ~(trivial_limit net) /\ eventually (\x. f(x) = b) net 15678 ==> (l = b)``, 15679 SIMP_TAC std_ss [GSYM REAL_LE_ANTISYM, EVENTUALLY_AND] THEN 15680 METIS_TAC [LIM_COMPONENT_UBOUND, LIM_COMPONENT_LBOUND]); 15681 15682val LIM_COMPONENT_LE = store_thm ("LIM_COMPONENT_LE", 15683 ``!net:('a)net f:'a->real g:'a->real l m. 15684 ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\ 15685 eventually (\x. (f x) <= (g x)) net 15686 ==> (l <= m)``, 15687 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN 15688 SIMP_TAC std_ss [LIM_COMPONENT_LBOUND] THEN 15689 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 15690 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> b /\ a ==> c ==> d`] THEN 15691 DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN REPEAT STRIP_TAC THEN 15692 MATCH_MP_TAC LIM_COMPONENT_LBOUND THEN EXISTS_TAC ``net:'a net`` THEN 15693 EXISTS_TAC ``(\(x :'a). (g :'a -> real) x - (f :'a -> real) x)`` THEN 15694 METIS_TAC []); 15695 15696val LIM_DROP_LE = store_thm ("LIM_DROP_LE", 15697 ``!net:('a)net f g l m. 15698 ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\ 15699 eventually (\x. f x <= g x) net 15700 ==> l <= m``, 15701 REPEAT STRIP_TAC THEN 15702 MATCH_MP_TAC(ISPEC ``net:('a)net`` LIM_COMPONENT_LE) THEN 15703 MAP_EVERY EXISTS_TAC [``f:'a->real``, ``g:'a->real``] THEN 15704 ASM_REWRITE_TAC[LESS_EQ_REFL]); 15705 15706val LIM_DROP_UBOUND = store_thm ("LIM_DROP_UBOUND", 15707 ``!net f:'a->real l b. 15708 (f --> l) net /\ 15709 ~(trivial_limit net) /\ eventually (\x. f x <= b) net 15710 ==> l <= b``, 15711 REPEAT STRIP_TAC THEN 15712 MATCH_MP_TAC LIM_COMPONENT_UBOUND THEN 15713 REWRITE_TAC[LESS_EQ_REFL] THEN METIS_TAC[]); 15714 15715val LIM_DROP_LBOUND = store_thm ("LIM_DROP_LBOUND", 15716 ``!net f:'a->real l b. 15717 (f --> l) net /\ 15718 ~(trivial_limit net) /\ eventually (\x. b <= f x) net 15719 ==> b <= l``, 15720 REPEAT STRIP_TAC THEN 15721 MATCH_MP_TAC LIM_COMPONENT_LBOUND THEN 15722 REWRITE_TAC[LESS_EQ_REFL] THEN METIS_TAC[]); 15723 15724(* ------------------------------------------------------------------------- *) 15725(* Also extending closed bounds to closures. *) 15726(* ------------------------------------------------------------------------- *) 15727 15728val IMAGE_CLOSURE_SUBSET = store_thm ("IMAGE_CLOSURE_SUBSET", 15729 ``!f (s:real->bool) (t:real->bool). 15730 f continuous_on closure s /\ closed t /\ IMAGE f s SUBSET t 15731 ==> IMAGE f (closure s) SUBSET t``, 15732 REPEAT STRIP_TAC THEN 15733 SUBGOAL_THEN ``closure s SUBSET {x | (f:real->real) x IN t}`` MP_TAC 15734 THENL [MATCH_MP_TAC SUBSET_TRANS, SET_TAC []] THEN 15735 EXISTS_TAC ``{x | x IN closure s /\ (f:real->real) x IN t}`` THEN 15736 CONJ_TAC THENL 15737 [MATCH_MP_TAC CLOSURE_MINIMAL, SET_TAC[]] THEN 15738 ASM_SIMP_TAC std_ss [CONTINUOUS_CLOSED_PREIMAGE, CLOSED_CLOSURE] THEN 15739 MP_TAC (ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[]); 15740 15741val CLOSURE_IMAGE_CLOSURE = store_thm ("CLOSURE_IMAGE_CLOSURE", 15742 ``!f:real->real s. 15743 f continuous_on closure s 15744 ==> (closure(IMAGE f (closure s)) = closure(IMAGE f s))``, 15745 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 15746 SIMP_TAC std_ss [SUBSET_CLOSURE, IMAGE_SUBSET, CLOSURE_SUBSET] THEN 15747 SIMP_TAC std_ss [CLOSURE_MINIMAL_EQ, CLOSED_CLOSURE] THEN 15748 MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN 15749 ASM_REWRITE_TAC[CLOSED_CLOSURE, CLOSURE_SUBSET]); 15750 15751val CLOSURE_IMAGE_BOUNDED = store_thm ("CLOSURE_IMAGE_BOUNDED", 15752 ``!f:real->real s. 15753 f continuous_on closure s /\ bounded s 15754 ==> (closure(IMAGE f s) = IMAGE f (closure s))``, 15755 REPEAT STRIP_TAC THEN 15756 MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC ``closure(IMAGE (f:real->real) (closure s))`` THEN 15757 CONJ_TAC THENL [ASM_MESON_TAC[CLOSURE_IMAGE_CLOSURE], ALL_TAC] THEN 15758 MATCH_MP_TAC CLOSURE_CLOSED THEN MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 15759 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN 15760 ASM_REWRITE_TAC[COMPACT_CLOSURE]); 15761 15762val CONTINUOUS_ON_CLOSURE_ABS_LE = store_thm ("CONTINUOUS_ON_CLOSURE_ABS_LE", 15763 ``!f:real->real s x b. 15764 f continuous_on (closure s) /\ 15765 (!y. y IN s ==> abs(f y) <= b) /\ 15766 x IN (closure s) 15767 ==> abs(f x) <= b``, 15768 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN 15769 SUBGOAL_THEN ``IMAGE (f:real->real) (closure s) SUBSET cball(0,b)`` 15770 MP_TAC THENL 15771 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET, ASM_SET_TAC []] THEN 15772 ASM_REWRITE_TAC [CLOSED_CBALL] THEN ASM_SET_TAC []); 15773 15774val CONTINUOUS_ON_CLOSURE_COMPONENT_LE = store_thm ("CONTINUOUS_ON_CLOSURE_COMPONENT_LE", 15775 ``!f:real->real s x b. 15776 f continuous_on (closure s) /\ 15777 (!y. y IN s ==> (f y) <= b) /\ 15778 x IN (closure s) 15779 ==> (f x) <= b``, 15780 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN 15781 SUBGOAL_THEN ``IMAGE (f:real->real) (closure s) SUBSET {x | x <= b}`` 15782 MP_TAC THENL 15783 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET, ASM_SET_TAC []] THEN 15784 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE] THEN ASM_SET_TAC[]); 15785 15786val CONTINUOUS_ON_CLOSURE_COMPONENT_GE = store_thm ("CONTINUOUS_ON_CLOSURE_COMPONENT_GE", 15787 ``!f:real->real s x b. 15788 f continuous_on (closure s) /\ 15789 (!y. y IN s ==> b <= (f y)) /\ 15790 x IN (closure s) 15791 ==> b <= (f x)``, 15792 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN 15793 SUBGOAL_THEN ``IMAGE (f:real->real) (closure s) SUBSET {x | x >= b}`` 15794 MP_TAC THENL 15795 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET, ASM_SET_TAC [real_ge]] THEN 15796 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_GE] THEN ASM_SET_TAC[real_ge]); 15797 15798val CONTINUOUS_MAP_CLOSURES = store_thm ("CONTINUOUS_MAP_CLOSURES", 15799 ``!f:real->real. 15800 f continuous_on UNIV <=> 15801 !s. IMAGE f (closure s) SUBSET closure(IMAGE f s)``, 15802 GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL 15803 [GEN_TAC THEN MATCH_MP_TAC(MESON[SUBSET_DEF, CLOSURE_SUBSET] 15804 ``(closure s = t) ==> s SUBSET t``) THEN 15805 MATCH_MP_TAC CLOSURE_IMAGE_CLOSURE THEN 15806 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, SUBSET_UNIV], 15807 REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN 15808 REWRITE_TAC[GSYM CLOSED_IN, SUBTOPOLOGY_UNIV, IN_UNIV] THEN 15809 X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN 15810 FIRST_X_ASSUM(MP_TAC o SPEC ``{x | (f:real->real) x IN t}``) THEN 15811 REWRITE_TAC[GSYM CLOSURE_SUBSET_EQ] THEN 15812 SUBGOAL_THEN 15813 ``closure(IMAGE (f:real->real) {x | f x IN t}) SUBSET t`` 15814 MP_TAC THENL 15815 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SET_TAC[], SET_TAC[]]]); 15816 15817(* ------------------------------------------------------------------------- *) 15818(* Limits relative to a union. *) 15819(* ------------------------------------------------------------------------- *) 15820 15821val LIM_WITHIN_UNION = store_thm ("LIM_WITHIN_UNION", 15822 ``(f --> l) (at x within (s UNION t)) <=> 15823 (f --> l) (at x within s) /\ (f --> l) (at x within t)``, 15824 SIMP_TAC std_ss [LIM_WITHIN, IN_UNION, GSYM FORALL_AND_THM] THEN 15825 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN 15826 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN 15827 EQ_TAC THENL [MESON_TAC[], ALL_TAC] THEN DISCH_THEN 15828 (CONJUNCTS_THEN2 (X_CHOOSE_TAC ``d:real``) (X_CHOOSE_TAC ``k:real``)) THEN 15829 EXISTS_TAC ``min d k:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 15830 ASM_MESON_TAC[]); 15831 15832val CONTINUOUS_ON_UNION = store_thm ("CONTINUOUS_ON_UNION", 15833 ``!f s t. closed s /\ closed t /\ f continuous_on s /\ f continuous_on t 15834 ==> f continuous_on (s UNION t)``, 15835 REWRITE_TAC[CONTINUOUS_ON, CLOSED_LIMPT, IN_UNION, LIM_WITHIN_UNION] THEN 15836 MESON_TAC[LIM, TRIVIAL_LIMIT_WITHIN]); 15837 15838val CONTINUOUS_ON_CASES = store_thm ("CONTINUOUS_ON_CASES", 15839 ``!P f g:real->real s t. 15840 closed s /\ closed t /\ f continuous_on s /\ g continuous_on t /\ 15841 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x)) 15842 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)``, 15843 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION THEN 15844 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL 15845 [EXISTS_TAC ``f:real->real``, EXISTS_TAC ``g:real->real``] THEN 15846 METIS_TAC[]); 15847 15848val CONTINUOUS_ON_UNION_LOCAL = store_thm ("CONTINUOUS_ON_UNION_LOCAL", 15849 ``!f:real->real s. 15850 closed_in (subtopology euclidean (s UNION t)) s /\ 15851 closed_in (subtopology euclidean (s UNION t)) t /\ 15852 f continuous_on s /\ f continuous_on t 15853 ==> f continuous_on (s UNION t)``, 15854 REWRITE_TAC[CONTINUOUS_ON, CLOSED_IN_LIMPT, IN_UNION, LIM_WITHIN_UNION] THEN 15855 MESON_TAC[LIM, TRIVIAL_LIMIT_WITHIN]); 15856 15857val CONTINUOUS_ON_CASES_LOCAL = store_thm ("CONTINUOUS_ON_CASES_LOCAL", 15858 ``!P f g:real->real s t. 15859 closed_in (subtopology euclidean (s UNION t)) s /\ 15860 closed_in (subtopology euclidean (s UNION t)) t /\ 15861 f continuous_on s /\ g continuous_on t /\ 15862 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x)) 15863 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)``, 15864 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL THEN 15865 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL 15866 [EXISTS_TAC ``f:real->real``, EXISTS_TAC ``g:real->real``] THEN 15867 METIS_TAC[]); 15868 15869val CONTINUOUS_ON_CASES_LE = store_thm ("CONTINUOUS_ON_CASES_LE", 15870 ``!f g:real->real h s a. 15871 f continuous_on {t | t IN s /\ h t <= a} /\ 15872 g continuous_on {t | t IN s /\ a <= h t} /\ 15873 (h) continuous_on s /\ 15874 (!t. t IN s /\ (h t = a) ==> (f t = g t)) 15875 ==> (\t. if h t <= a then f(t) else g(t)) continuous_on s``, 15876 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC 15877 ``{t | t IN s /\ (h:real->real) t <= a} UNION 15878 {t | t IN s /\ a <= h t}`` THEN 15879 CONJ_TAC THENL 15880 [ALL_TAC, SIMP_TAC std_ss [SUBSET_DEF, IN_UNION, GSPECIFICATION, REAL_LE_TOTAL]] THEN 15881 ONCE_REWRITE_TAC [METIS [] ``h t <= a = (\t:real. h t <= a:real) t``] THEN 15882 MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN ASM_SIMP_TAC std_ss [] THEN 15883 SIMP_TAC std_ss [GSPECIFICATION, GSYM CONJ_ASSOC, REAL_LE_ANTISYM] THEN 15884 REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL 15885 [ALL_TAC, METIS_TAC[]] THEN 15886 CONJ_TAC THENL 15887 [SUBGOAL_THEN 15888 ``{t | t IN s /\ (h:real->real) t <= a} = 15889 {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\ 15890 (h) t IN {x | x <= a}}`` 15891 (fn th => GEN_REWR_TAC RAND_CONV [th]) 15892 THENL 15893 [SIMP_TAC std_ss [o_THM, GSPECIFICATION, EXTENSION, IN_UNION] THEN 15894 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC std_ss [], 15895 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN 15896 ASM_SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_LE, ETA_AX] THEN 15897 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 15898 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[]], 15899 SUBGOAL_THEN 15900 ``{t | t IN s /\ a <= (h:real->real) t} = 15901 {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\ 15902 (h) t IN {x | x >= a}}`` 15903 (fn th => GEN_REWR_TAC RAND_CONV [th]) 15904 THENL 15905 [SIMP_TAC std_ss [o_THM, GSPECIFICATION, EXTENSION, IN_UNION] THEN 15906 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC std_ss [real_ge] THEN 15907 ASM_REAL_ARITH_TAC, 15908 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN 15909 ASM_SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_GE, ETA_AX] THEN 15910 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 15911 CONTINUOUS_ON_SUBSET)) THEN 15912 SET_TAC[]]]); 15913 15914val CONTINUOUS_ON_CASES_1 = store_thm ("CONTINUOUS_ON_CASES_1", 15915 ``!f g:real->real s a. 15916 f continuous_on {t | t IN s /\ t <= a} /\ 15917 g continuous_on {t | t IN s /\ a <= t} /\ 15918 (a IN s ==> (f(a) = g(a))) 15919 ==> (\t. if t <= a then f(t) else g(t)) continuous_on s``, 15920 REPEAT STRIP_TAC THEN 15921 ONCE_REWRITE_TAC [METIS [] ``t <= a = (\t. t) t <= a:real``] THEN 15922 MATCH_MP_TAC CONTINUOUS_ON_CASES_LE THEN 15923 ASM_SIMP_TAC std_ss [o_DEF, CONTINUOUS_ON_ID] THEN 15924 METIS_TAC[]); 15925 15926val EXTENSION_FROM_CLOPEN = store_thm ("EXTENSION_FROM_CLOPEN", 15927 ``!f:real->real s t u. 15928 open_in (subtopology euclidean s) t /\ 15929 closed_in (subtopology euclidean s) t /\ 15930 f continuous_on t /\ IMAGE f t SUBSET u /\ ((u = {}) ==> (s = {})) 15931 ==> ?g. g continuous_on s /\ IMAGE g s SUBSET u /\ 15932 !x. x IN t ==> (g x = f x)``, 15933 REPEAT GEN_TAC THEN ASM_CASES_TAC ``u:real->bool = {}`` THEN 15934 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_EMPTY, IMAGE_EMPTY, IMAGE_INSERT, SUBSET_EMPTY, 15935 IMAGE_EQ_EMPTY, NOT_IN_EMPTY] THEN 15936 STRIP_TAC THEN UNDISCH_TAC ``u <> {}:real->bool`` THEN DISCH_TAC THEN 15937 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 15938 DISCH_THEN(X_CHOOSE_TAC ``a:real``) THEN 15939 EXISTS_TAC ``\x. if x IN t then (f:real->real) x else a`` THEN 15940 SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE] THEN 15941 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 15942 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN 15943 SUBGOAL_THEN ``s:real->bool = t UNION (s DIFF t)`` SUBST1_TAC THENL 15944 [ASM_SET_TAC[], 15945 ONCE_REWRITE_TAC [METIS [] ``(\x. if x IN t then f x else a) = 15946 (\x. if (\x. x IN t) x then f x else (\x. a) x)``] THEN 15947 MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL] THEN 15948 ASM_SIMP_TAC std_ss [SET_RULE ``t SUBSET s ==> (t UNION (s DIFF t) = s)``] THEN 15949 REWRITE_TAC[CONTINUOUS_ON_CONST, IN_DIFF] THEN 15950 CONJ_TAC THENL [MATCH_MP_TAC CLOSED_IN_DIFF, MESON_TAC[]] THEN 15951 ASM_REWRITE_TAC[CLOSED_IN_REFL]); 15952 15953(* ------------------------------------------------------------------------- *) 15954(* Some more convenient intermediate-value theorem formulations. *) 15955(* ------------------------------------------------------------------------- *) 15956 15957val CONNECTED_IVT_HYPERPLANE = store_thm ("CONNECTED_IVT_HYPERPLANE", 15958 ``!s x y:real a b. 15959 connected s /\ 15960 x IN s /\ y IN s /\ a * x <= b /\ b <= a * y 15961 ==> ?z. z IN s /\ (a * z = b)``, 15962 REPEAT STRIP_TAC THEN 15963 UNDISCH_TAC ``connected s`` THEN DISCH_TAC THEN 15964 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [connected]) THEN 15965 SIMP_TAC std_ss [NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o SPECL 15966 [``{x:real | a * x < b}``, ``{x:real | a * x > b}``]) THEN 15967 SIMP_TAC std_ss [OPEN_HALFSPACE_LT, OPEN_HALFSPACE_GT] THEN 15968 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN SIMP_TAC std_ss [] THEN STRIP_TAC THEN 15969 SIMP_TAC real_ss [EXTENSION, GSPECIFICATION, IN_INTER, NOT_IN_EMPTY, SUBSET_DEF, 15970 IN_UNION, REAL_LT_LE, real_gt] THEN 15971 METIS_TAC[REAL_LE_TOTAL, REAL_LE_ANTISYM]); 15972 15973val CONNECTED_IVT_COMPONENT = store_thm ("CONNECTED_IVT_COMPONENT", 15974 ``!s x y:real a. 15975 connected s /\ x IN s /\ y IN s /\ x <= a /\ a <= y 15976 ==> ?z. z IN s /\ (z = a)``, 15977 REPEAT STRIP_TAC THEN MP_TAC(ISPECL 15978 [``s:real->bool``, ``x:real``, ``y:real``, ``1:real``, 15979 ``a:real``] CONNECTED_IVT_HYPERPLANE) THEN 15980 ASM_SIMP_TAC std_ss [REAL_MUL_LID]); 15981 15982(* ------------------------------------------------------------------------- *) 15983(* Rather trivial observation that we can map any connected set on segment. *) 15984(* ------------------------------------------------------------------------- *) 15985 15986val MAPPING_CONNECTED_ONTO_SEGMENT = store_thm ("MAPPING_CONNECTED_ONTO_SEGMENT", 15987 ``!s:real->bool a b:real. 15988 connected s /\ ~(?a. s SUBSET {a}) 15989 ==> ?f. f continuous_on s /\ (IMAGE f s = segment[a,b])``, 15990 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE 15991 ``~(?a. s SUBSET {a}) ==> ?a b. a IN s /\ b IN s /\ ~(a = b)``)) THEN 15992 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 15993 MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN STRIP_TAC THEN EXISTS_TAC 15994 ``\x:real. a + dist(u,x) / (dist(u,x) + dist(v,x)) * (b - a:real)`` THEN 15995 CONJ_TAC THEN SIMP_TAC std_ss [] THENL 15996 [ONCE_REWRITE_TAC [METIS [] 15997 ``(\x. a + dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) = 15998 (\x. (\x. a) x + (\x. dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) x)``] THEN 15999 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN 16000 ONCE_REWRITE_TAC [METIS [] 16001 ``(\x. dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) = 16002 (\x. (\x. dist (u,x) / (dist (u,x) + dist (v,x))) x * (\x. (b - a)) x)``] THEN 16003 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN SIMP_TAC std_ss [o_DEF, CONTINUOUS_ON_CONST], 16004 16005 REWRITE_TAC[segment, REAL_ARITH 16006 ``(&1 - u) * a + u * b:real = a + u * (b - a)``] THEN 16007 ONCE_REWRITE_TAC [METIS [] 16008 ``(\x. a + dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) = 16009 (\x. a + (\x. dist (u,x) / (dist (u,x) + dist (v,x))) x * (b - a))``] THEN 16010 ONCE_REWRITE_TAC [METIS [] ``(0 <= u /\ u <= 1:real) = (\u. 0 <= u /\ u <= 1) u``] THEN 16011 MATCH_MP_TAC(SET_RULE 16012 ``(IMAGE f s = {x | P x}) 16013 ==> (IMAGE (\x. a + f x * b) s = {a + u * b:real | P u})``) THEN 16014 SIMP_TAC std_ss [GSYM SUBSET_ANTISYM_EQ, SUBSET_DEF, FORALL_IN_IMAGE] THEN 16015 ASM_SIMP_TAC real_ss [dist, GSPECIFICATION, REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ, 16016 REAL_ARITH ``~(u:real = v) ==> &0 < abs(u - x) + abs(v - x)``] THEN 16017 CONJ_TAC THENL [REAL_ARITH_TAC, REWRITE_TAC[IN_IMAGE]] THEN 16018 X_GEN_TAC ``t:real`` THEN STRIP_TAC THEN 16019 MP_TAC(ISPECL 16020 [``IMAGE (\x:real. dist(u,x) / (dist(u,x) + dist(v,x))) s``, 16021 ``0:real``, ``1:real``, ``t:real``] 16022 CONNECTED_IVT_COMPONENT) THEN 16023 ASM_SIMP_TAC arith_ss [] THEN 16024 SIMP_TAC std_ss [EXISTS_IN_IMAGE] THEN 16025 KNOW_TAC ``connected 16026 (IMAGE 16027 (\(x :real). 16028 (dist ((u :real),x) :real) / 16029 ((dist (u,x) :real) + (dist ((v :real),x) :real))) 16030 (s :real -> bool)) /\ 16031 (0 :real) IN 16032 IMAGE 16033 (\(x :real). 16034 (dist (u,x) :real) / ((dist (u,x) :real) + (dist (v,x) :real))) 16035 s /\ 16036 (1 :real) IN 16037 IMAGE 16038 (\(x :real). 16039 (dist (u,x) :real) / ((dist (u,x) :real) + (dist (v,x) :real))) 16040 s`` THENL 16041 [REWRITE_TAC[IN_IMAGE], DISCH_TAC THEN ASM_REWRITE_TAC [IN_IMAGE] THEN 16042 BETA_TAC THEN MESON_TAC[dist]] THEN 16043 REPEAT CONJ_TAC THENL 16044 [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[], 16045 EXISTS_TAC ``u:real`` THEN ASM_REWRITE_TAC[DIST_REFL, real_div, dist] THEN 16046 BETA_TAC THEN REAL_ARITH_TAC, 16047 EXISTS_TAC ``v:real`` THEN ASM_REWRITE_TAC[DIST_REFL] THEN 16048 ASM_SIMP_TAC std_ss [REAL_DIV_REFL, DIST_EQ_0, REAL_ADD_RID] THEN 16049 RULE_ASSUM_TAC (ONCE_REWRITE_RULE 16050 [REAL_ARITH ``(u <> v) = (abs (u - v) <> 0:real)``]) THEN 16051 ASM_SIMP_TAC real_ss [REAL_DIV_REFL]]] THEN 16052 REWRITE_TAC[real_div] THENL 16053 [ONCE_REWRITE_TAC [METIS [] ``(\x. dist (u,x) * inv (dist (u,x) + dist (v,x))) = 16054 (\x. (\x. dist (u,x)) x * (\x. inv (dist (u,x) + dist (v,x))) x)``] THEN 16055 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN 16056 REWRITE_TAC[CONTINUOUS_ON_DIST] THEN 16057 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (dist (u,x) + dist (v,x))) = 16058 (\x. inv ((\x. (dist (u,x) + dist (v,x))) x))``] THEN 16059 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN 16060 ASM_SIMP_TAC std_ss [dist, REAL_ARITH 16061 ``~(u:real = v) ==> ~(abs(u - x) + abs(v - x) = &0)``] THEN 16062 ONCE_REWRITE_TAC [METIS [] ``(\x:real. abs (u - x) + abs (v - x)) = 16063 (\x. (\x. abs (u - x)) x + (\x. abs (v - x)) x)``] THEN 16064 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN 16065 SIMP_TAC std_ss [GSYM dist, REWRITE_RULE[o_DEF] CONTINUOUS_ON_DIST], 16066 ONCE_REWRITE_TAC [METIS [] ``(\x. dist (u,x) * inv (dist (u,x) + dist (v,x))) = 16067 (\x. (\x. dist (u,x)) x * (\x. inv (dist (u,x) + dist (v,x))) x)``] THEN 16068 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN 16069 REWRITE_TAC[CONTINUOUS_ON_DIST] THEN 16070 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (dist (u,x) + dist (v,x))) = 16071 (\x. inv ((\x. (dist (u,x) + dist (v,x))) x))``] THEN 16072 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN 16073 ASM_SIMP_TAC std_ss [dist, REAL_ARITH 16074 ``~(u:real = v) ==> ~(abs(u - x) + abs(v - x) = &0)``] THEN 16075 ONCE_REWRITE_TAC [METIS [] ``(\x:real. abs (u - x) + abs (v - x)) = 16076 (\x. (\x. abs (u - x)) x + (\x. abs (v - x)) x)``] THEN 16077 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN 16078 SIMP_TAC std_ss [GSYM dist, REWRITE_RULE[o_DEF] CONTINUOUS_ON_DIST], 16079 ALL_TAC] THEN 16080 FULL_SIMP_TAC std_ss [GSYM dist, DIST_REFL, REAL_ADD_RID] THEN 16081 REWRITE_TAC [GSYM real_div] THEN METIS_TAC [REAL_DIV_REFL]); 16082 16083(* ------------------------------------------------------------------------- *) 16084(* Also more convenient formulations of monotone convergence. *) 16085(* ------------------------------------------------------------------------- *) 16086 16087val BOUNDED_INCREASING_CONVERGENT = store_thm ("BOUNDED_INCREASING_CONVERGENT", 16088 ``!s:num->real. 16089 bounded {s n | n IN univ(:num)} /\ (!n. (s n) <= (s(SUC n))) 16090 ==> ?l. (s --> l) sequentially``, 16091 GEN_TAC THEN 16092 SIMP_TAC std_ss [bounded_def, GSPECIFICATION, LIM_SEQUENTIALLY, dist, 16093 IN_UNIV] THEN 16094 DISCH_TAC THEN MATCH_MP_TAC CONVERGENT_BOUNDED_MONOTONE THEN 16095 SIMP_TAC std_ss [LEFT_EXISTS_AND_THM] THEN 16096 CONJ_TAC THENL [METIS_TAC[], ALL_TAC] THEN DISJ1_TAC THEN 16097 ONCE_REWRITE_TAC [METIS [] ``!m n. ((s:num->real) m <= s n) = (\m n. s m <= s n) m n``] THEN 16098 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN 16099 METIS_TAC [REAL_LE_TRANS, REAL_LE_REFL]); 16100 16101val BOUNDED_DECREASING_CONVERGENT = store_thm ("BOUNDED_DECREASING_CONVERGENT", 16102 ``!s:num->real. 16103 bounded {s n | n IN univ(:num)} /\ (!n. (s(SUC n)) <= (s(n))) 16104 ==> ?l. (s --> l) sequentially``, 16105 GEN_TAC THEN SIMP_TAC std_ss [bounded_def, FORALL_IN_GSPEC] THEN 16106 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 16107 MP_TAC(ISPEC ``\n. -((s:num->real) n)`` BOUNDED_INCREASING_CONVERGENT) THEN 16108 ASM_SIMP_TAC std_ss [bounded_def, FORALL_IN_GSPEC, ABS_NEG, REAL_LE_NEG2] THEN 16109 GEN_REWR_TAC (LAND_CONV o BINDER_CONV) [GSYM LIM_NEG_EQ] THEN 16110 SIMP_TAC std_ss [REAL_NEG_NEG, ETA_AX] THEN METIS_TAC[]); 16111 16112(* ------------------------------------------------------------------------- *) 16113(* Basic homeomorphism definitions. *) 16114(* ------------------------------------------------------------------------- *) 16115 16116val homeomorphism = new_definition ("homeomorphism", 16117 ``homeomorphism (s,t) (f,g) <=> 16118 (!x. x IN s ==> (g(f(x)) = x)) /\ (IMAGE f s = t) /\ f continuous_on s /\ 16119 (!y. y IN t ==> (f(g(y)) = y)) /\ (IMAGE g t = s) /\ g continuous_on t``); 16120 16121val _ = set_fixity "homeomorphic" (Infix(NONASSOC, 450)); 16122 16123val homeomorphic = new_definition ("homeomorphic", 16124 ``s homeomorphic t <=> ?f g. homeomorphism (s,t) (f,g)``); 16125 16126val HOMEOMORPHISM = store_thm ("HOMEOMORPHISM", 16127 ``!s:real->bool t:real->bool f g. 16128 homeomorphism (s,t) (f,g) <=> 16129 f continuous_on s /\ IMAGE f s SUBSET t /\ 16130 g continuous_on t /\ IMAGE g t SUBSET s /\ 16131 (!x. x IN s ==> (g (f x) = x)) /\ 16132 (!y. y IN t ==> (f (g y) = y))``, 16133 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN 16134 EQ_TAC THEN SIMP_TAC std_ss [] THEN SET_TAC[]); 16135 16136val HOMEOMORPHISM_OF_SUBSETS = store_thm ("HOMEOMORPHISM_OF_SUBSETS", 16137 ``!f g s t s' t'. 16138 homeomorphism (s,t) (f,g) /\ s' SUBSET s /\ t' SUBSET t /\ (IMAGE f s' = t') 16139 ==> homeomorphism (s',t') (f,g)``, 16140 REWRITE_TAC[homeomorphism] THEN 16141 REPEAT STRIP_TAC THEN 16142 TRY(MATCH_MP_TAC CONTINUOUS_ON_SUBSET) THEN ASM_SET_TAC[]); 16143 16144val HOMEOMORPHISM_ID = store_thm ("HOMEOMORPHISM_ID", 16145 ``!s:real->bool. homeomorphism (s,s) ((\x. x),(\x. x))``, 16146 SIMP_TAC std_ss [homeomorphism, IMAGE_ID, CONTINUOUS_ON_ID]); 16147 16148val HOMEOMORPHIC_REFL = store_thm ("HOMEOMORPHIC_REFL", 16149 ``!s:real->bool. s homeomorphic s``, 16150 REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_ID]); 16151 16152val HOMEOMORPHISM_SYM = store_thm ("HOMEOMORPHISM_SYM", 16153 ``!f:real->real g s t. 16154 homeomorphism (s,t) (f,g) <=> homeomorphism (t,s) (g,f)``, 16155 REWRITE_TAC[homeomorphism] THEN MESON_TAC[]); 16156 16157val HOMEOMORPHIC_SYM = store_thm ("HOMEOMORPHIC_SYM", 16158 ``!s t. s homeomorphic t <=> t homeomorphic s``, 16159 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic, homeomorphism] THEN 16160 ONCE_REWRITE_TAC [METIS [] 16161 ``((!x. x IN t ==> (g (f x) = x)) /\ (IMAGE f t = s) /\ 16162 f continuous_on t /\ (!y. y IN s ==> (f (g y) = y)) /\ 16163 (IMAGE g s = t) /\ g continuous_on s) = 16164 (\f g. (!x. x IN t ==> (g (f x) = x)) /\ (IMAGE f t = s) /\ 16165 f continuous_on t /\ (!y. y IN s ==> (f (g y) = y)) /\ 16166 (IMAGE g s = t) /\ g continuous_on s) f g``] THEN 16167 GEN_REWR_TAC RAND_CONV [SWAP_EXISTS_THM] THEN 16168 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN SIMP_TAC std_ss [] THEN 16169 TAUT_TAC); 16170 16171val HOMEOMORPHISM_COMPOSE = store_thm ("HOMEOMORPHISM_COMPOSE", 16172 ``!f:real->real g h:real->real k s t u. 16173 homeomorphism (s,t) (f,g) /\ homeomorphism (t,u) (h,k) 16174 ==> homeomorphism (s,u) (h o f,g o k)``, 16175 SIMP_TAC std_ss [homeomorphism, CONTINUOUS_ON_COMPOSE, IMAGE_COMPOSE, o_THM] THEN 16176 SET_TAC[]); 16177 16178val HOMEOMORPHIC_TRANS = store_thm ("HOMEOMORPHIC_TRANS", 16179 ``!s:real->bool t:real->bool u:real->bool. 16180 s homeomorphic t /\ t homeomorphic u ==> s homeomorphic u``, 16181 REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_COMPOSE]); 16182 16183val HOMEOMORPHIC_IMP_CARD_EQ = store_thm ("HOMEOMORPHIC_IMP_CARD_EQ", 16184 ``!s:real->bool t:real->bool. s homeomorphic t ==> s =_c t``, 16185 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic, homeomorphism, eq_c] THEN 16186 STRIP_TAC THEN EXISTS_TAC ``f:real->real`` THEN ASM_SET_TAC []); 16187 16188val HOMEOMORPHIC_FINITENESS = store_thm ("HOMEOMORPHIC_FINITENESS", 16189 ``!s:real->bool t:real->bool. 16190 s homeomorphic t ==> (FINITE s <=> FINITE t)``, 16191 REPEAT GEN_TAC THEN 16192 DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN 16193 DISCH_THEN(ACCEPT_TAC o MATCH_MP CARD_FINITE_CONG)); 16194 16195val HOMEOMORPHIC_EMPTY = store_thm ("HOMEOMORPHIC_EMPTY", 16196 ``(!s. (s:real->bool) homeomorphic ({}:real->bool) <=> (s = {})) /\ 16197 (!s. ({}:real->bool) homeomorphic (s:real->bool) <=> (s = {}))``, 16198 REWRITE_TAC[homeomorphic, homeomorphism, IMAGE_EMPTY, IMAGE_INSERT, IMAGE_EQ_EMPTY] THEN 16199 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 16200 ASM_SIMP_TAC std_ss [continuous_on, NOT_IN_EMPTY]); 16201 16202val HOMEOMORPHIC_MINIMAL = store_thm ("HOMEOMORPHIC_MINIMAL", 16203 ``!s t. s homeomorphic t <=> 16204 ?f g. (!x. x IN s ==> f(x) IN t /\ (g(f(x)) = x)) /\ 16205 (!y. y IN t ==> g(y) IN s /\ (f(g(y)) = y)) /\ 16206 f continuous_on s /\ g continuous_on t``, 16207 REWRITE_TAC[homeomorphic, homeomorphism, EXTENSION, IN_IMAGE] THEN 16208 REPEAT GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN MESON_TAC[]); 16209 16210val HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF = store_thm ("HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF", 16211 ``!f:real->real s. 16212 linear f /\ (!x y. (f x = f y) ==> (x = y)) 16213 ==> (IMAGE f s) homeomorphic s``, 16214 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 16215 FIRST_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_LEFT_INVERSE]) THEN 16216 STRIP_TAC THEN EXISTS_TAC ``g:real->real`` THEN 16217 EXISTS_TAC ``f:real->real`` THEN 16218 ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON, FORALL_IN_IMAGE, FUN_IN_IMAGE] THEN 16219 ASM_SIMP_TAC std_ss [continuous_on, CONJ_EQ_IMP, FORALL_IN_IMAGE] THEN 16220 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 16221 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 16222 MP_TAC(ISPEC ``f:real->real`` LINEAR_INJECTIVE_BOUNDED_BELOW_POS) THEN 16223 ASM_REWRITE_TAC[] THEN 16224 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 16225 EXISTS_TAC ``e * B:real`` THEN ASM_SIMP_TAC real_ss [REAL_LT_MUL] THEN 16226 X_GEN_TAC ``y:real`` THEN ASM_SIMP_TAC std_ss [dist, GSYM LINEAR_SUB] THEN 16227 DISCH_TAC THEN ASM_SIMP_TAC real_ss [GSYM REAL_LT_LDIV_EQ] THEN 16228 MATCH_MP_TAC(REAL_ARITH ``a <= b ==> b < x ==> a < x:real``) THEN 16229 ASM_SIMP_TAC real_ss [REAL_LE_RDIV_EQ]); 16230 16231val HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ = store_thm ("HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ", 16232 ``!f:real->real s t. 16233 linear f /\ (!x y. (f x = f y) ==> (x = y)) 16234 ==> ((IMAGE f s) homeomorphic t <=> s homeomorphic t)``, 16235 REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o SPEC ``s:real->bool`` o 16236 MATCH_MP HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF) THEN 16237 EQ_TAC THENL 16238 [FIRST_X_ASSUM(MP_TAC o ONCE_REWRITE_RULE [HOMEOMORPHIC_SYM]), 16239 POP_ASSUM MP_TAC] THEN 16240 METIS_TAC[AND_IMP_INTRO, HOMEOMORPHIC_TRANS]); 16241 16242val HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ = store_thm ("HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ", 16243 ``!f:real->real s t. 16244 linear f /\ (!x y. (f x = f y) ==> (x = y)) 16245 ==> (s homeomorphic (IMAGE f t) <=> s homeomorphic t)``, 16246 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN 16247 REWRITE_TAC[HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ]); 16248 16249val HOMEOMORPHIC_TRANSLATION_SELF = store_thm ("HOMEOMORPHIC_TRANSLATION_SELF", 16250 ``!a:real s. (IMAGE (\x. a + x) s) homeomorphic s``, 16251 REPEAT GEN_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 16252 EXISTS_TAC ``\x:real. x - a`` THEN 16253 EXISTS_TAC ``\x:real. a + x`` THEN 16254 SIMP_TAC std_ss [FORALL_IN_IMAGE, CONTINUOUS_ON_SUB, CONTINUOUS_ON_ID, 16255 CONTINUOUS_ON_CONST, CONTINUOUS_ON_ADD, REAL_ADD_SUB] THEN 16256 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]); 16257 16258val HOMEOMORPHIC_TRANSLATION_LEFT_EQ = store_thm ("HOMEOMORPHIC_TRANSLATION_LEFT_EQ", 16259 ``!a:real s t. 16260 (IMAGE (\x. a + x) s) homeomorphic t <=> s homeomorphic t``, 16261 METIS_TAC[HOMEOMORPHIC_TRANSLATION_SELF, 16262 HOMEOMORPHIC_SYM, HOMEOMORPHIC_TRANS]); 16263 16264val HOMEOMORPHIC_TRANSLATION_RIGHT_EQ = store_thm ("HOMEOMORPHIC_TRANSLATION_RIGHT_EQ", 16265 ``!a:real s t. 16266 s homeomorphic (IMAGE (\x. a + x) t) <=> s homeomorphic t``, 16267 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN 16268 REWRITE_TAC[HOMEOMORPHIC_TRANSLATION_LEFT_EQ]); 16269 16270val HOMEOMORPHISM_IMP_QUOTIENT_MAP = store_thm ("HOMEOMORPHISM_IMP_QUOTIENT_MAP", 16271 ``!f:real->real g s t. 16272 homeomorphism (s,t) (f,g) 16273 ==> !u. u SUBSET t 16274 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=> 16275 open_in (subtopology euclidean t) u)``, 16276 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN 16277 STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN 16278 EXISTS_TAC ``g:real->real`` THEN ASM_REWRITE_TAC[SUBSET_REFL]); 16279 16280val HOMEOMORPHIC_SCALING_LEFT = store_thm ("HOMEOMORPHIC_SCALING_LEFT", 16281 ``!c. &0 < c 16282 ==> (!s t. (IMAGE (\x. c * x) s) homeomorphic t <=> s homeomorphic t)``, 16283 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN 16284 MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ THEN 16285 ASM_SIMP_TAC std_ss [REAL_EQ_LMUL, REAL_LT_IMP_NE, LINEAR_SCALING]); 16286 16287val HOMEOMORPHIC_SCALING_RIGHT = store_thm ("HOMEOMORPHIC_SCALING_RIGHT", 16288 ``!c. &0 < c 16289 ==> (!s t. s homeomorphic (IMAGE (\x. c * x) t) <=> s homeomorphic t)``, 16290 SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN 16291 MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ THEN 16292 ASM_SIMP_TAC std_ss [REAL_EQ_LMUL, REAL_LT_IMP_NE, LINEAR_SCALING]); 16293 16294val HOMEOMORPHIC_FINITE = store_thm ("HOMEOMORPHIC_FINITE", 16295 ``!s:real->bool t:real->bool. 16296 FINITE s /\ FINITE t ==> (s homeomorphic t <=> (CARD s = CARD t))``, 16297 REPEAT STRIP_TAC THEN EQ_TAC THENL 16298 [DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN 16299 ASM_SIMP_TAC std_ss [CARD_EQ_CARD], 16300 STRIP_TAC THEN REWRITE_TAC[homeomorphic, HOMEOMORPHISM] THEN 16301 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] 16302 CARD_EQ_BIJECTIONS) THEN 16303 ASM_REWRITE_TAC[] THEN 16304 DISCH_THEN (X_CHOOSE_TAC ``f:real->real``) THEN POP_ASSUM MP_TAC THEN 16305 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN 16306 MAP_EVERY EXISTS_TAC [``f:real->real``,``g:real->real``] THEN 16307 POP_ASSUM MP_TAC THEN 16308 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_FINITE] THEN ASM_SET_TAC[]]); 16309 16310val HOMEOMORPHIC_FINITE_STRONG = store_thm ("HOMEOMORPHIC_FINITE_STRONG", 16311 ``!s:real->bool t:real->bool. 16312 FINITE s \/ FINITE t 16313 ==> (s homeomorphic t <=> FINITE s /\ FINITE t /\ (CARD s = CARD t))``, 16314 REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN 16315 SIMP_TAC std_ss [HOMEOMORPHIC_FINITE] THEN DISCH_TAC THEN 16316 FIRST_ASSUM(MP_TAC o MATCH_MP CARD_FINITE_CONG o MATCH_MP 16317 HOMEOMORPHIC_IMP_CARD_EQ) THEN 16318 FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN 16319 ASM_MESON_TAC[HOMEOMORPHIC_FINITE]); 16320 16321val HOMEOMORPHIC_SING = store_thm ("HOMEOMORPHIC_SING", 16322 ``!a:real b:real. {a} homeomorphic {b}``, 16323 SIMP_TAC std_ss [HOMEOMORPHIC_FINITE, FINITE_SING, CARD_SING]); 16324 16325val LIFT_TO_QUOTIENT_SPACE_UNIQUE = store_thm ("LIFT_TO_QUOTIENT_SPACE_UNIQUE", 16326 ``!f:real->real g:real->real s t u. 16327 (IMAGE f s = t) /\ 16328 (IMAGE g s = u) /\ 16329 (!v. v SUBSET t 16330 ==> (open_in (subtopology euclidean s) 16331 {x | x IN s /\ f x IN v} <=> 16332 open_in (subtopology euclidean t) v)) /\ 16333 (!v. v SUBSET u 16334 ==> (open_in (subtopology euclidean s) 16335 {x | x IN s /\ g x IN v} <=> 16336 open_in (subtopology euclidean u) v)) /\ 16337 (!x y. x IN s /\ y IN s ==> ((f x = f y) <=> (g x = g y))) 16338 ==> t homeomorphic u``, 16339 REPEAT STRIP_TAC THEN 16340 MP_TAC(ISPECL 16341 [``f:real->real``, ``g:real->real``, ``s:real->bool``, 16342 ``t:real->bool``, ``u:real->bool``] LIFT_TO_QUOTIENT_SPACE) THEN 16343 MP_TAC(ISPECL 16344 [``g:real->real``, ``f:real->real``, ``s:real->bool``, 16345 ``u:real->bool``, ``t:real->bool``] LIFT_TO_QUOTIENT_SPACE) THEN 16346 ASM_REWRITE_TAC[] THEN 16347 MP_TAC(ISPECL [``f:real->real``, ``s:real->bool``, ``t:real->bool``] 16348 CONTINUOUS_ON_OPEN_GEN) THEN 16349 ASM_SIMP_TAC std_ss [SUBSET_REFL] THEN DISCH_THEN SUBST1_TAC THEN 16350 KNOW_TAC ``(!(u :real -> bool). 16351 open_in (subtopology euclidean (t :real -> bool)) u ==> 16352 open_in (subtopology euclidean (s :real -> bool)) 16353 {x | x IN s /\ (f :real -> real) x IN u})`` THENL 16354 [METIS_TAC[OPEN_IN_IMP_SUBSET], 16355 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 16356 DISCH_THEN(X_CHOOSE_THEN ``h:real->real`` STRIP_ASSUME_TAC)] THEN 16357 MP_TAC(ISPECL [``g:real->real``, ``s:real->bool``, ``u:real->bool``] 16358 CONTINUOUS_ON_OPEN_GEN) THEN 16359 ASM_SIMP_TAC std_ss [SUBSET_REFL] THEN DISCH_THEN SUBST1_TAC THEN 16360 KNOW_TAC ``(!(u' :real -> bool). 16361 open_in (subtopology euclidean (u :real -> bool)) u' ==> 16362 open_in (subtopology euclidean (s :real -> bool)) 16363 {x | x IN s /\ (g :real -> real) x IN u'}) /\ 16364 (!(x :real) (y :real). 16365 x IN s /\ y IN s /\ ((f :real -> real) x = f y) ==> (g x = g y))`` THENL 16366 [METIS_TAC[OPEN_IN_IMP_SUBSET], 16367 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 16368 DISCH_THEN(X_CHOOSE_THEN ``k:real->real`` STRIP_ASSUME_TAC)] THEN 16369 REWRITE_TAC[homeomorphic, homeomorphism] THEN 16370 MAP_EVERY EXISTS_TAC 16371 [``k:real->real``, ``h:real->real``] THEN 16372 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]); 16373 16374(* ------------------------------------------------------------------------- *) 16375(* Inverse function property for open/closed maps. *) 16376(* ------------------------------------------------------------------------- *) 16377 16378val CONTINUOUS_ON_INVERSE_OPEN_MAP = store_thm ("CONTINUOUS_ON_INVERSE_OPEN_MAP", 16379 ``!f:real->real g s t. 16380 f continuous_on s /\ (IMAGE f s = t) /\ (!x. x IN s ==> (g(f x) = x)) /\ 16381 (!u. open_in (subtopology euclidean s) u 16382 ==> open_in (subtopology euclidean t) (IMAGE f u)) 16383 ==> g continuous_on t``, 16384 REPEAT STRIP_TAC THEN 16385 MP_TAC(ISPECL [``g:real->real``, ``t:real->bool``, ``s:real->bool``] 16386 CONTINUOUS_ON_OPEN_GEN) THEN 16387 KNOW_TAC ``IMAGE (g :real -> real) (t :real -> bool) SUBSET (s :real -> bool)`` THENL 16388 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 16389 DISCH_THEN SUBST1_TAC] THEN 16390 X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 16391 FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN ASM_REWRITE_TAC[] THEN 16392 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 16393 FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [open_in]) THEN 16394 ASM_SET_TAC[]); 16395 16396val CONTINUOUS_ON_INVERSE_CLOSED_MAP = store_thm ("CONTINUOUS_ON_INVERSE_CLOSED_MAP", 16397 ``!f:real->real g s t. 16398 f continuous_on s /\ (IMAGE f s = t) /\ (!x. x IN s ==> (g(f x) = x)) /\ 16399 (!u. closed_in (subtopology euclidean s) u 16400 ==> closed_in (subtopology euclidean t) (IMAGE f u)) 16401 ==> g continuous_on t``, 16402 REPEAT STRIP_TAC THEN 16403 MP_TAC(ISPECL [``g:real->real``, ``t:real->bool``, ``s:real->bool``] 16404 CONTINUOUS_ON_CLOSED_GEN) THEN 16405 KNOW_TAC ``IMAGE (g :real -> real) (t :real -> bool) SUBSET (s :real -> bool)`` THENL 16406 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 16407 DISCH_THEN SUBST1_TAC] THEN 16408 X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 16409 FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN ASM_REWRITE_TAC[] THEN 16410 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 16411 FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [closed_in]) THEN 16412 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM_SET_TAC[]); 16413 16414val HOMEOMORPHISM_INJECTIVE_OPEN_MAP = store_thm ("HOMEOMORPHISM_INJECTIVE_OPEN_MAP", 16415 ``!f:real->real s t. 16416 f continuous_on s /\ (IMAGE f s = t) /\ 16417 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) /\ 16418 (!u. open_in (subtopology euclidean s) u 16419 ==> open_in (subtopology euclidean t) (IMAGE f u)) 16420 ==> ?g. homeomorphism (s,t) (f,g)``, 16421 REPEAT STRIP_TAC THEN 16422 UNDISCH_TAC ``!(x :real) (y :real). 16423 x IN (s :real -> bool) /\ y IN s /\ 16424 ((f :real -> real) x = f y) ==> 16425 (x = y)`` THEN DISCH_TAC THEN 16426 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_ON_LEFT_INVERSE]) THEN 16427 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN 16428 ASM_SIMP_TAC std_ss [homeomorphism] THEN 16429 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 16430 MATCH_MP_TAC CONTINUOUS_ON_INVERSE_OPEN_MAP THEN ASM_MESON_TAC[]); 16431 16432val HOMEOMORPHISM_INJECTIVE_CLOSED_MAP = store_thm ("HOMEOMORPHISM_INJECTIVE_CLOSED_MAP", 16433 ``!f:real->real s t. 16434 f continuous_on s /\ (IMAGE f s = t) /\ 16435 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) /\ 16436 (!u. closed_in (subtopology euclidean s) u 16437 ==> closed_in (subtopology euclidean t) (IMAGE f u)) 16438 ==> ?g. homeomorphism (s,t) (f,g)``, 16439 REPEAT STRIP_TAC THEN 16440 UNDISCH_TAC ``!(x :real) (y :real). 16441 x IN (s :real -> bool) /\ y IN s /\ 16442 ((f :real -> real) x = f y) ==> 16443 (x = y)`` THEN DISCH_TAC THEN 16444 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_ON_LEFT_INVERSE]) THEN 16445 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN 16446 ASM_SIMP_TAC std_ss [homeomorphism] THEN 16447 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 16448 MATCH_MP_TAC CONTINUOUS_ON_INVERSE_CLOSED_MAP THEN ASM_MESON_TAC[]); 16449 16450val HOMEOMORPHISM_IMP_OPEN_MAP = store_thm ("HOMEOMORPHISM_IMP_OPEN_MAP", 16451 ``!f:real->real g s t u. 16452 homeomorphism (s,t) (f,g) /\ open_in (subtopology euclidean s) u 16453 ==> open_in (subtopology euclidean t) (IMAGE f u)``, 16454 REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN 16455 SUBGOAL_THEN ``IMAGE (f:real->real) u = 16456 {y | y IN t /\ g(y) IN u}`` 16457 SUBST1_TAC THENL 16458 [FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [open_in]) THEN 16459 ASM_SET_TAC[], 16460 MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]]); 16461 16462val HOMEOMORPHISM_IMP_CLOSED_MAP = store_thm ("HOMEOMORPHISM_IMP_CLOSED_MAP", 16463 ``!f:real->real g s t u. 16464 homeomorphism (s,t) (f,g) /\ closed_in (subtopology euclidean s) u 16465 ==> closed_in (subtopology euclidean t) (IMAGE f u)``, 16466 REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN 16467 SUBGOAL_THEN ``IMAGE (f:real->real) u = 16468 {y | y IN t /\ g(y) IN u}`` 16469 SUBST1_TAC THENL 16470 [FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [closed_in]) THEN 16471 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM_SET_TAC[], 16472 MATCH_MP_TAC CONTINUOUS_ON_IMP_CLOSED_IN THEN ASM_REWRITE_TAC[]]); 16473 16474val HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ = store_thm ("HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ", 16475 ``!f:real->real s t. 16476 f continuous_on s /\ (IMAGE f s = t) /\ 16477 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 16478 ==> ((?g. homeomorphism (s,t) (f,g)) <=> 16479 !u. open_in (subtopology euclidean s) u 16480 ==> open_in (subtopology euclidean t) (IMAGE f u))``, 16481 REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 16482 [MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN ASM_MESON_TAC[], 16483 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN 16484 ASM_REWRITE_TAC[]]); 16485 16486val HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ = store_thm ("HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ", 16487 ``!f:real->real s t. 16488 f continuous_on s /\ (IMAGE f s = t) /\ 16489 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 16490 ==> ((?g. homeomorphism (s,t) (f,g)) <=> 16491 !u. closed_in (subtopology euclidean s) u 16492 ==> closed_in (subtopology euclidean t) (IMAGE f u))``, 16493 REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 16494 [MATCH_MP_TAC HOMEOMORPHISM_IMP_CLOSED_MAP THEN ASM_MESON_TAC[], 16495 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP THEN 16496 ASM_REWRITE_TAC[]]); 16497 16498val INJECTIVE_MAP_OPEN_IFF_CLOSED = store_thm ("INJECTIVE_MAP_OPEN_IFF_CLOSED", 16499 ``!f:real->real s t. 16500 f continuous_on s /\ (IMAGE f s = t) /\ 16501 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 16502 ==> ((!u. open_in (subtopology euclidean s) u 16503 ==> open_in (subtopology euclidean t) (IMAGE f u)) <=> 16504 (!u. closed_in (subtopology euclidean s) u 16505 ==> closed_in (subtopology euclidean t) (IMAGE f u)))``, 16506 REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN 16507 EXISTS_TAC ``?g:real->real. homeomorphism (s,t) (f,g)`` THEN 16508 CONJ_TAC THENL 16509 [CONV_TAC SYM_CONV THEN MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ, 16510 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ] THEN 16511 ASM_REWRITE_TAC[]); 16512 16513(* ------------------------------------------------------------------------- *) 16514(* Relatively weak hypotheses if the domain of the function is compact. *) 16515(* ------------------------------------------------------------------------- *) 16516 16517val CONTINUOUS_IMP_CLOSED_MAP = store_thm ("CONTINUOUS_IMP_CLOSED_MAP", 16518 ``!f:real->real s t. 16519 f continuous_on s /\ (IMAGE f s = t) /\ compact s 16520 ==> !u. closed_in (subtopology euclidean s) u 16521 ==> closed_in (subtopology euclidean t) (IMAGE f u)``, 16522 SIMP_TAC std_ss [CLOSED_IN_CLOSED_EQ, COMPACT_IMP_CLOSED] THEN 16523 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_SUBSET THEN 16524 ASM_SIMP_TAC std_ss [IMAGE_SUBSET] THEN 16525 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 16526 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 16527 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_IN_CLOSED_TRANS, 16528 BOUNDED_SUBSET, CONTINUOUS_ON_SUBSET]); 16529 16530val CONTINUOUS_IMP_QUOTIENT_MAP = store_thm ("CONTINUOUS_IMP_QUOTIENT_MAP", 16531 ``!f:real->real s t. 16532 f continuous_on s /\ (IMAGE f s = t) /\ compact s 16533 ==> !u. u SUBSET t 16534 ==> (open_in (subtopology euclidean s) 16535 {x | x IN s /\ f x IN u} <=> 16536 open_in (subtopology euclidean t) u)``, 16537 REPEAT GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN 16538 MATCH_MP_TAC CLOSED_MAP_IMP_QUOTIENT_MAP THEN 16539 ASM_REWRITE_TAC[] THEN 16540 MATCH_MP_TAC CONTINUOUS_IMP_CLOSED_MAP THEN 16541 ASM_REWRITE_TAC[]); 16542 16543val CONTINUOUS_ON_INVERSE = store_thm ("CONTINUOUS_ON_INVERSE", 16544 ``!f:real->real g s. 16545 f continuous_on s /\ compact s /\ (!x. x IN s ==> (g(f(x)) = x)) 16546 ==> g continuous_on (IMAGE f s)``, 16547 REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN 16548 SUBGOAL_THEN ``IMAGE g (IMAGE (f:real->real) s) = s`` SUBST1_TAC THENL 16549 [REWRITE_TAC[EXTENSION, IN_IMAGE] THEN ASM_MESON_TAC[], ALL_TAC] THEN 16550 X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN 16551 REWRITE_TAC[CLOSED_IN_CLOSED] THEN 16552 EXISTS_TAC ``IMAGE (f:real->real) t`` THEN CONJ_TAC THENL 16553 [MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 16554 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN 16555 FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN 16556 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 16557 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_IN_CLOSED_TRANS, 16558 BOUNDED_SUBSET, CONTINUOUS_ON_SUBSET], 16559 SIMP_TAC std_ss [EXTENSION, IN_INTER, GSPECIFICATION, IN_IMAGE] THEN 16560 ASM_MESON_TAC[CLOSED_IN_SUBSET, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, SUBSET_DEF]]); 16561 16562val HOMEOMORPHISM_COMPACT = store_thm ("HOMEOMORPHISM_COMPACT", 16563 ``!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\ 16564 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 16565 ==> ?g. homeomorphism(s,t) (f,g)``, 16566 REWRITE_TAC[INJECTIVE_ON_LEFT_INVERSE] THEN REPEAT GEN_TAC THEN 16567 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 16568 DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN 16569 ASM_SIMP_TAC std_ss [EXTENSION, homeomorphism] THEN 16570 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN 16571 ASM_MESON_TAC[CONTINUOUS_ON_INVERSE, IN_IMAGE]); 16572 16573val HOMEOMORPHIC_COMPACT = store_thm ("HOMEOMORPHIC_COMPACT", 16574 ``!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\ 16575 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) 16576 ==> s homeomorphic t``, 16577 REWRITE_TAC[homeomorphic] THEN METIS_TAC[HOMEOMORPHISM_COMPACT]); 16578 16579(* ------------------------------------------------------------------------- *) 16580(* Lemmas about composition of homeomorphisms. *) 16581(* ------------------------------------------------------------------------- *) 16582 16583val HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE = store_thm ("HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE", 16584 ``!f:real->real g:real->real s t u. 16585 f continuous_on s /\ (IMAGE f s = t) /\ 16586 g continuous_on t /\ IMAGE g t SUBSET u /\ 16587 (?h. homeomorphism (s,u) (g o f,h)) 16588 ==> (?f'. homeomorphism (s,t) (f,f')) /\ 16589 (?g'. homeomorphism (t,u) (g,g'))``, 16590 REPEAT GEN_TAC THEN STRIP_TAC THEN 16591 RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism, o_THM]) THEN 16592 MATCH_MP_TAC(TAUT `q /\ (q ==> p) ==> p /\ q`) THEN CONJ_TAC THENL 16593 [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN 16594 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 16595 MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_SURJECTIVE THEN 16596 MAP_EVERY EXISTS_TAC [``f:real->real``, ``s:real->bool``] THEN 16597 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN 16598 MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN 16599 MAP_EVERY EXISTS_TAC [``h:real->real``, ``s:real->bool``] THEN 16600 ASM_SIMP_TAC std_ss [homeomorphism, o_THM], 16601 REWRITE_TAC[homeomorphism, o_THM] THEN 16602 DISCH_THEN(X_CHOOSE_THEN ``g':real->real`` STRIP_ASSUME_TAC) THEN 16603 EXISTS_TAC ``((h:real->real) o (g:real->real))`` THEN 16604 ASM_SIMP_TAC std_ss [o_THM, IMAGE_COMPOSE] THEN 16605 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 16606 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN 16607 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]); 16608 16609val HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE = store_thm ("HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE", 16610 ``!f:real->real g:real->real s t u. 16611 f continuous_on s /\ IMAGE f s SUBSET t /\ 16612 g continuous_on t /\ IMAGE g t SUBSET u /\ 16613 (!x y. x IN t /\ y IN t /\ (g x = g y) ==> (x = y)) /\ 16614 (?h. homeomorphism (s,u) (g o f,h)) 16615 ==> (?f'. homeomorphism (s,t) (f,f')) /\ 16616 (?g'. homeomorphism (t,u) (g,g'))``, 16617 REPEAT GEN_TAC THEN STRIP_TAC THEN 16618 RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism, o_THM]) THEN 16619 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL 16620 [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN 16621 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 16622 MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_INJECTIVE THEN 16623 MAP_EVERY EXISTS_TAC [``g:real->real``, ``u:real->bool``] THEN 16624 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN 16625 MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN 16626 MAP_EVERY EXISTS_TAC [``h:real->real``, ``s:real->bool``] THEN 16627 ASM_REWRITE_TAC[homeomorphism, o_THM], 16628 REWRITE_TAC[homeomorphism, o_THM] THEN 16629 DISCH_THEN(X_CHOOSE_THEN ``f':real->real`` STRIP_ASSUME_TAC) THEN 16630 EXISTS_TAC ``(f:real->real) o (h:real->real)`` THEN 16631 ASM_SIMP_TAC std_ss [o_THM, IMAGE_COMPOSE] THEN 16632 REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN 16633 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN 16634 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]); 16635 16636(* ------------------------------------------------------------------------- *) 16637(* Preservation of topological properties. *) 16638(* ------------------------------------------------------------------------- *) 16639 16640val HOMEOMORPHIC_COMPACTNESS = store_thm ("HOMEOMORPHIC_COMPACTNESS", 16641 ``!s t. s homeomorphic t ==> (compact s <=> compact t)``, 16642 REWRITE_TAC[homeomorphic, homeomorphism] THEN 16643 MESON_TAC[COMPACT_CONTINUOUS_IMAGE]); 16644 16645val HOMEOMORPHIC_CONNECTEDNESS = store_thm ("HOMEOMORPHIC_CONNECTEDNESS", 16646 ``!s t. s homeomorphic t ==> (connected s <=> connected t)``, 16647 REWRITE_TAC[homeomorphic, homeomorphism] THEN 16648 MESON_TAC[CONNECTED_CONTINUOUS_IMAGE]); 16649 16650(* ------------------------------------------------------------------------- *) 16651(* Results on translation, scaling etc. *) 16652(* ------------------------------------------------------------------------- *) 16653 16654val HOMEOMORPHIC_SCALING = store_thm ("HOMEOMORPHIC_SCALING", 16655 ``!s:real->bool c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. c * x) s)``, 16656 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 16657 MAP_EVERY EXISTS_TAC [``\x:real. c * x``, ``\x:real. inv(c) * x``] THEN 16658 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CMUL, CONTINUOUS_ON_ID, FORALL_IN_IMAGE] THEN 16659 ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_RINV] THEN 16660 SIMP_TAC std_ss [REAL_MUL_LID, IN_IMAGE, REAL_MUL_LID] THEN MESON_TAC[]); 16661 16662val HOMEOMORPHIC_TRANSLATION = store_thm ("HOMEOMORPHIC_TRANSLATION", 16663 ``!s a:real. s homeomorphic (IMAGE (\x. a + x) s)``, 16664 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 16665 MAP_EVERY EXISTS_TAC [``\x:real. a + x``, ``\x:real. -a + x``] THEN 16666 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID] THEN 16667 SIMP_TAC std_ss [REAL_ADD_ASSOC, REAL_ADD_LINV, REAL_ADD_RINV, 16668 FORALL_IN_IMAGE, REAL_ADD_LID] THEN 16669 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]); 16670 16671val HOMEOMORPHIC_AFFINITY = store_thm ("HOMEOMORPHIC_AFFINITY", 16672 ``!s a:real c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. a + c * x) s)``, 16673 REPEAT STRIP_TAC THEN 16674 MATCH_MP_TAC HOMEOMORPHIC_TRANS THEN 16675 EXISTS_TAC ``IMAGE (\x:real. c * x) s`` THEN 16676 ASM_SIMP_TAC std_ss [HOMEOMORPHIC_SCALING] THEN 16677 SUBGOAL_THEN ``(\x:real. a + c * x) = (\x. a + x) o (\x. c * x)`` 16678 SUBST1_TAC THENL [REWRITE_TAC[o_DEF], ALL_TAC] THEN 16679 SIMP_TAC std_ss [IMAGE_COMPOSE, HOMEOMORPHIC_TRANSLATION]); 16680 16681val HOMEOMORPHIC_BALLS_CBALL_SPHERE = store_thm ("HOMEOMORPHIC_BALLS_CBALL_SPHERE", 16682 ``(!a:real b:real d e. 16683 &0 < d /\ &0 < e ==> ball(a,d) homeomorphic ball(b,e)) /\ 16684 (!a:real b:real d e. 16685 &0 < d /\ &0 < e ==> cball(a,d) homeomorphic cball(b,e)) /\ 16686 (!a:real b:real d e. 16687 &0 < d /\ &0 < e ==> sphere(a,d) homeomorphic sphere(b,e))``, 16688 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 16689 EXISTS_TAC ``\x:real. b + (e / d) * (x - a)`` THEN 16690 EXISTS_TAC ``\x:real. a + (d / e) * (x - b)`` THEN 16691 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_SUB, CONTINUOUS_ON_CMUL, 16692 CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID, IN_BALL, IN_CBALL, IN_SPHERE] THEN 16693 REWRITE_TAC[dist, REAL_ARITH ``a - (a + b) = -b:real``, ABS_NEG] THEN 16694 REWRITE_TAC[real_div, REAL_ARITH 16695 ``a + d * ((b + e * (x - a)) - b) = (&1 - d * e) * a + (d * e) * x:real``] THEN 16696 ONCE_REWRITE_TAC[REAL_ARITH 16697 ``(e * d') * (d * e') = (d * d') * (e * e':real)``] THEN 16698 ASM_SIMP_TAC std_ss [REAL_MUL_RINV, REAL_LT_IMP_NE, REAL_MUL_LID, REAL_SUB_REFL] THEN 16699 REWRITE_TAC[ABS_MUL, REAL_MUL_LZERO, REAL_MUL_LID, REAL_ADD_LID] THEN 16700 ASM_SIMP_TAC std_ss [ABS_MUL, ABS_INV, REAL_ARITH 16701 ``&0 < x ==> (abs x = x:real)``, REAL_LT_IMP_NE] THEN 16702 GEN_REWR_TAC(BINOP_CONV o BINDER_CONV o funpow 2 RAND_CONV) 16703 [GSYM REAL_MUL_RID] THEN 16704 ONCE_REWRITE_TAC[REAL_ARITH ``(a * b) * c = (a * c) * b:real``] THEN 16705 ASM_SIMP_TAC std_ss [REAL_LE_LMUL, GSYM real_div, REAL_LE_LDIV_EQ, REAL_MUL_LID, 16706 GSYM REAL_MUL_ASSOC, REAL_LT_LMUL, REAL_LT_LDIV_EQ, ABS_SUB] THEN 16707 ASM_SIMP_TAC std_ss [REAL_DIV_REFL, REAL_LT_IMP_NE, REAL_MUL_RID]); 16708 16709val HOMEOMORPHIC_BALLS = store_thm ("HOMEOMORPHIC_BALLS", 16710 ``(!a:real b:real d e. 16711 &0 < d /\ &0 < e ==> ball(a,d) homeomorphic ball(b,e))``, 16712 REWRITE_TAC [HOMEOMORPHIC_BALLS_CBALL_SPHERE]); 16713 16714val HOMEOMORPHIC_CBALL = store_thm ("HOMEOMORPHIC_CBALL", 16715 ``(!a:real b:real d e. 16716 &0 < d /\ &0 < e ==> cball(a,d) homeomorphic cball(b,e))``, 16717 REWRITE_TAC [HOMEOMORPHIC_BALLS_CBALL_SPHERE]); 16718 16719val HOMEOMORPHIC_SPHERE = store_thm ("HOMEOMORPHIC_SPHERE", 16720 ``(!a:real b:real d e. 16721 &0 < d /\ &0 < e ==> sphere(a,d) homeomorphic sphere(b,e))``, 16722 REWRITE_TAC [HOMEOMORPHIC_BALLS_CBALL_SPHERE]); 16723 16724(* ------------------------------------------------------------------------- *) 16725(* Homeomorphism of one-point compactifications. *) 16726(* ------------------------------------------------------------------------- *) 16727 16728val HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS = store_thm ("HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS", 16729 ``!s:real->bool t:real->bool a b. 16730 compact s /\ compact t /\ a IN s /\ b IN t /\ 16731 (s DELETE a) homeomorphic (t DELETE b) 16732 ==> s homeomorphic t``, 16733 REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN 16734 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [homeomorphic]) THEN 16735 SIMP_TAC std_ss [HOMEOMORPHISM, LEFT_IMP_EXISTS_THM] THEN 16736 MAP_EVERY X_GEN_TAC [``f:real->real``, ``g:real->real``] THEN 16737 STRIP_TAC THEN 16738 EXISTS_TAC ``\x. if x = a then b else (f:real->real) x`` THEN 16739 ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 16740 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 16741 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 16742 ASM_CASES_TAC ``x:real = a`` THEN ASM_REWRITE_TAC[] THENL 16743 [REWRITE_TAC[continuous_within] THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 16744 MP_TAC(ISPECL [``b:real``, ``e:real``] CENTRE_IN_BALL) THEN 16745 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 16746 SUBGOAL_THEN 16747 ``closed_in (subtopology euclidean s) 16748 { x | x IN (s DELETE a) /\ 16749 (f:real->real)(x) IN t DIFF ball(b,e)}`` 16750 MP_TAC THENL 16751 [MATCH_MP_TAC CLOSED_SUBSET THEN CONJ_TAC THENL [SET_TAC[], ALL_TAC] THEN 16752 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN SUBGOAL_THEN 16753 ``{x | x IN s DELETE a /\ f x IN t DIFF ball(b,e)} = 16754 IMAGE (g:real->real) (t DIFF ball (b,e))`` 16755 SUBST1_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 16756 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN 16757 ASM_SIMP_TAC std_ss [COMPACT_DIFF, OPEN_BALL] THEN 16758 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 16759 CONTINUOUS_ON_SUBSET)) THEN ASM_SET_TAC[], 16760 REWRITE_TAC[closed_in, open_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN 16761 DISCH_THEN(MP_TAC o SPEC ``a:real`` o last o CONJUNCTS) THEN 16762 ASM_SIMP_TAC std_ss [GSPECIFICATION, IN_DIFF, IN_DELETE] THEN 16763 SIMP_TAC std_ss [CONJ_EQ_IMP, DE_MORGAN_THM] THEN 16764 STRIP_TAC THEN EXISTS_TAC ``e':real`` THEN 16765 ASM_REWRITE_TAC[] THEN GEN_TAC THEN COND_CASES_TAC THEN 16766 ASM_REWRITE_TAC[DIST_REFL] THEN 16767 GEN_REWR_TAC (RAND_CONV o RAND_CONV o LAND_CONV) [DIST_SYM] THEN 16768 RULE_ASSUM_TAC(REWRITE_RULE[IN_BALL]) THEN ASM_SET_TAC[]], 16769 UNDISCH_TAC ``(f:real->real) continuous_on (s DELETE a)`` THEN 16770 SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 16771 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[IN_DELETE] THEN 16772 REWRITE_TAC[continuous_within] THEN 16773 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN 16774 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[IN_DELETE] THEN 16775 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 16776 EXISTS_TAC ``min d (dist(a:real,x))`` THEN 16777 ASM_SIMP_TAC std_ss [REAL_LT_MIN, GSYM DIST_NZ] THEN 16778 METIS_TAC[REAL_LT_REFL]]); 16779 16780(* ------------------------------------------------------------------------- *) 16781(* Homeomorphisms between open intervals in real and then in real. *) 16782(* Could prove similar things for closed intervals, but they drop out of *) 16783(* later stuff in "convex.ml" even more easily. *) 16784(* ------------------------------------------------------------------------- *) 16785 16786val HOMEOMORPHIC_OPEN_INTERVALS = store_thm ("HOMEOMORPHIC_OPEN_INTERVALS", 16787 ``!a b c d. 16788 a < b /\ c < d 16789 ==> interval(a,b) homeomorphic interval(c,d)``, 16790 SUBGOAL_THEN 16791 ``!a b. a < b 16792 ==> interval(0:real,1) homeomorphic interval(a,b)`` 16793 ASSUME_TAC THENL 16794 [REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN 16795 EXISTS_TAC ``(\x. a + x * (b - a)):real->real`` THEN 16796 EXISTS_TAC ``(\x. inv(b - a) * (x - a)):real->real`` THEN 16797 ASM_SIMP_TAC std_ss [IN_INTERVAL] THEN 16798 REWRITE_TAC[METIS [REAL_MUL_SYM, GSYM real_div] ``inv b * a:real = a / b``] THEN 16799 ASM_SIMP_TAC std_ss [REAL_LT_LDIV_EQ, REAL_LT_RDIV_EQ, REAL_SUB_LT, 16800 REAL_LT_ADDR, REAL_EQ_LDIV_EQ, REAL_DIV_RMUL, REAL_LT_IMP_NE, 16801 REAL_LT_MUL, REAL_MUL_LZERO, REAL_ADD_SUB, REAL_LT_RMUL, 16802 REAL_ARITH ``a + x < b <=> x < &1 * (b - a:real)``] THEN 16803 REPEAT CONJ_TAC THENL 16804 [REAL_ARITH_TAC, 16805 ONCE_REWRITE_TAC [METIS [] ``(\x. a + x * (b - a)) = 16806 (\x. (\x. a) x + (\x. x * (b - a)) x:real)``] THEN 16807 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN 16808 ONCE_REWRITE_TAC [METIS [] ``(\x. x * (b - a)) = 16809 (\x. (\x. x) x * (\x. (b - a)) x:real)``] THEN 16810 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN 16811 REWRITE_TAC[o_DEF, CONTINUOUS_ON_ID, CONTINUOUS_ON_CONST], 16812 ONCE_REWRITE_TAC [METIS [real_div, REAL_MUL_SYM] ``(\x. (x - a) / (b - a)) = 16813 (\x. inv(b - a) * (\x. (x - a)) x:real)``] THEN 16814 MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN 16815 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID]], 16816 REPEAT STRIP_TAC THEN 16817 FIRST_ASSUM(MP_TAC o SPECL [``a:real``, ``b:real``]) THEN 16818 FIRST_X_ASSUM(MP_TAC o SPECL [``c:real``, ``d:real``]) THEN 16819 ASM_REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN 16820 GEN_REWR_TAC (LAND_CONV o LAND_CONV) [HOMEOMORPHIC_SYM] THEN 16821 REWRITE_TAC[HOMEOMORPHIC_TRANS]]); 16822 16823val HOMEOMORPHIC_OPEN_INTERVAL_UNIV = store_thm ("HOMEOMORPHIC_OPEN_INTERVAL_UNIV", 16824 ``!a b. a < b ==> interval(a,b) homeomorphic univ(:real)``, 16825 REPEAT STRIP_TAC THEN 16826 MP_TAC(SPECL [``a:real``, ``b:real``, ``-1:real``, ``1:real``] 16827 HOMEOMORPHIC_OPEN_INTERVALS) THEN 16828 ASM_REWRITE_TAC[] THEN REWRITE_TAC [REAL_ARITH ``-1 < 1:real``] THEN 16829 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMEOMORPHIC_TRANS) THEN 16830 POP_ASSUM_LIST(K ALL_TAC) THEN 16831 REWRITE_TAC[HOMEOMORPHIC_MINIMAL, IN_UNIV] THEN 16832 EXISTS_TAC ``\x:real. inv(&1 - abs x) * x`` THEN 16833 EXISTS_TAC ``\y:real. if &0 <= y then inv(&1 + y) * y 16834 else inv(&1 - y) * y`` THEN 16835 SIMP_TAC std_ss [] THEN REPEAT CONJ_TAC THENL 16836 [X_GEN_TAC ``x:real`` THEN REWRITE_TAC[IN_INTERVAL] THEN 16837 SIMP_TAC std_ss [REAL_LE_MUL, REAL_LT_INV_EQ, REAL_LE_MUL, REAL_ARITH 16838 ``-a < x /\ x < a ==> &0 < a - abs x:real``] THEN 16839 SIMP_TAC std_ss [abs, REAL_MUL_ASSOC] THEN 16840 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN 16841 GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN 16842 AP_THM_TAC THEN AP_TERM_TAC THEN COND_CASES_TAC THEN 16843 (Cases_on `x = 0:real` THENL 16844 [ASM_REWRITE_TAC [REAL_INV1, REAL_NEG_0, REAL_SUB_RZERO, 16845 REAL_ADD_RID, REAL_MUL_RZERO] THEN REAL_ARITH_TAC, ALL_TAC]) THEN 16846 (KNOW_TAC ``!y. y <> 0:real ==> ((1 + inv y * x) = (y + x) / y:real) /\ 16847 ((1 - inv y * x) = (y - x) / y:real)`` THENL 16848 [ASM_SIMP_TAC real_ss [real_div, REAL_ADD_RDISTRIB, REAL_MUL_RINV, REAL_SUB_RDISTRIB] THEN 16849 REAL_ARITH_TAC, STRIP_TAC] THEN 16850 KNOW_TAC ``(1 - x) <> 0 /\ (1 - -x) <> 0:real`` THENL 16851 [METIS_TAC [REAL_ARITH ``x < 1 ==> 1 - x <> 0:real``, 16852 REAL_ARITH ``-1 < x ==> 1 - -x <> 0:real``], 16853 STRIP_TAC] THEN ASM_SIMP_TAC real_ss []) THENL 16854 [METIS_TAC [REAL_INV_1OVER, REAL_MUL_RINV, REAL_INV_INV], 16855 FULL_SIMP_TAC real_ss [REAL_LT_IMP_LE] THEN 16856 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_MUL_SYM]) THEN 16857 FULL_SIMP_TAC real_ss [GSYM real_div, REAL_LE_RDIV_EQ, 16858 REAL_ARITH ``(-1 < x) = (0 < 1 + x:real)``], 16859 FULL_SIMP_TAC real_ss [REAL_LT_IMP_LE, REAL_NOT_LE] THEN 16860 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_MUL_SYM]) THEN 16861 FULL_SIMP_TAC real_ss [GSYM real_div, REAL_LT_LDIV_EQ, 16862 REAL_ARITH ``(x < 1) = (0 < 1 - x:real)``] THEN 16863 METIS_TAC [REAL_ARITH ``~(x < 0 /\ 0 <= x:real)``], 16864 FULL_SIMP_TAC real_ss [] THEN 16865 METIS_TAC [REAL_INV_1OVER, REAL_MUL_RINV, REAL_INV_INV]], 16866 X_GEN_TAC ``y:real`` THEN COND_CASES_TAC THEN 16867 ASM_SIMP_TAC real_ss [IN_INTERVAL, REAL_BOUNDS_LT] THEN 16868 ASM_SIMP_TAC real_ss [ABS_MUL, ABS_INV, REAL_ARITH 16869 ``(0 <= y ==> 1 + y <> 0:real) /\ (~(0 <= y) ==> 1 - y <> 0:real)``] THEN 16870 REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div)] THEN 16871 ASM_SIMP_TAC real_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``&0 <= x ==> &0 < abs(&1 + x:real)``, 16872 REAL_ARITH ``~(&0 <= x) ==> &0 < abs(&1 - x:real)``] THEN 16873 (CONJ_TAC THENL [ASM_REAL_ARITH_TAC, ALL_TAC]) THEN 16874 REWRITE_TAC [real_div] THEN 16875 ONCE_REWRITE_TAC [REAL_ARITH ``a * b * c = c * b * a:real``] THEN 16876 REWRITE_TAC[REAL_MUL_ASSOC] THEN REWRITE_TAC[ABS_MUL] THEN 16877 ASM_REWRITE_TAC[abs, REAL_LE_INV_EQ] THEN 16878 ASM_SIMP_TAC real_ss [REAL_ARITH ``&0 <= x ==> &0 <= &1 + x:real``, 16879 REAL_ARITH ``~(&0 <= x) ==> &0 <= &1 - x:real``] THEN 16880 GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN 16881 AP_THM_TAC THEN AP_TERM_TAC THEN 16882 (KNOW_TAC ``!x. x <> 0:real ==> ((1 + y * inv x) = (x + y) / x:real) /\ 16883 ((1 - y * inv x) = (x - y) / x:real)`` THENL 16884 [ASM_SIMP_TAC real_ss [real_div, REAL_ADD_RDISTRIB, REAL_MUL_RINV, REAL_SUB_RDISTRIB], 16885 STRIP_TAC]) THENL 16886 [KNOW_TAC ``(1 + y) <> 0:real`` THENL 16887 [METIS_TAC [REAL_ARITH ``(0 <= x) ==> 1 + x <> 0:real``], 16888 STRIP_TAC] THEN ASM_SIMP_TAC real_ss [], 16889 KNOW_TAC ``(1 - y) <> 0:real`` THENL 16890 [METIS_TAC [REAL_ARITH ``~(0 <= x) ==> 1 - x <> 0:real``], 16891 STRIP_TAC] THEN ASM_SIMP_TAC real_ss []] THEN 16892 METIS_TAC [REAL_INV_1OVER, REAL_MUL_RINV, REAL_INV_INV], 16893 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 16894 X_GEN_TAC ``x:real`` THEN 16895 REWRITE_TAC[IN_INTERVAL] THEN DISCH_TAC THEN 16896 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (1 - abs x) * x) = 16897 (\x. (\x. inv (1 - abs x)) x * (\x. x) x:real)``] THEN 16898 MATCH_MP_TAC CONTINUOUS_MUL THEN 16899 REWRITE_TAC[CONTINUOUS_AT_ID] THEN 16900 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (1 - abs x)) = 16901 (\x. inv ((\x. 1 - abs x) x:real))``] THEN 16902 ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN 16903 SIMP_TAC real_ss [NETLIMIT_AT, o_DEF] THEN 16904 CONJ_TAC THENL 16905 [ONCE_REWRITE_TAC [METIS [] 16906 ``(\x. 1 - abs x) = (\x. (\x. 1) x - (\x. abs x) x:real)``] THEN 16907 MATCH_MP_TAC CONTINUOUS_SUB THEN 16908 SIMP_TAC std_ss [CONTINUOUS_CONST] THEN 16909 ONCE_REWRITE_TAC [METIS [] ``(\x. abs x) = (\x. abs ((\x. x) x:real))``] THEN 16910 METIS_TAC [REWRITE_RULE[o_DEF] CONTINUOUS_AT_ABS], ASM_REAL_ARITH_TAC], 16911 SUBGOAL_THEN ``univ(:real) = {x | x >= &0} UNION {x | x <= &0}`` 16912 SUBST1_TAC THENL 16913 [SIMP_TAC std_ss [EXTENSION, IN_UNION, IN_UNION, GSPECIFICATION, IN_UNIV] THEN 16914 REAL_ARITH_TAC, 16915 ONCE_REWRITE_TAC [METIS [] 16916 ``(\y. if 0 <= y then inv (1 + y) * y else inv (1 - y) * y) = 16917 (\y. if (\y. 0 <= y) y then (\y. inv (1 + y) * y) y 16918 else (\y. inv (1 - y) * y) y:real)``] THEN 16919 MATCH_MP_TAC CONTINUOUS_ON_CASES THEN 16920 SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_LE, CLOSED_HALFSPACE_COMPONENT_GE, 16921 GSPECIFICATION] THEN 16922 REWRITE_TAC[REAL_NOT_LE, real_ge, REAL_LET_ANTISYM] THEN 16923 SIMP_TAC std_ss [REAL_LE_ANTISYM, REAL_SUB_RZERO, REAL_ADD_RID] THEN 16924 CONJ_TAC THENL 16925 [MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 16926 X_GEN_TAC ``y:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, real_ge] THEN 16927 DISCH_TAC THEN ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 + y) * y) = 16928 (\y. (\y. inv (1 + y)) y * (\y. y) y:real)``] THEN 16929 MATCH_MP_TAC CONTINUOUS_MUL THEN 16930 REWRITE_TAC[CONTINUOUS_AT_ID] THEN 16931 ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 + y)) = (\y. inv ((\y. (1 + y)) y:real))``] THEN 16932 ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN 16933 SIMP_TAC std_ss [NETLIMIT_AT, o_DEF] THEN 16934 ASM_SIMP_TAC std_ss [CONTINUOUS_ADD, CONTINUOUS_AT_ID, CONTINUOUS_SUB, 16935 CONTINUOUS_CONST] THEN 16936 ASM_REAL_ARITH_TAC, ALL_TAC] THEN CONJ_TAC THENL 16937 [MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN 16938 X_GEN_TAC ``y:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, real_ge] THEN 16939 DISCH_TAC THEN ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 - y) * y) = 16940 (\y. (\y. inv (1 - y)) y * (\y. y) y:real)``] THEN 16941 MATCH_MP_TAC CONTINUOUS_MUL THEN 16942 REWRITE_TAC[CONTINUOUS_AT_ID] THEN 16943 ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 - y)) = (\y. inv ((\y. (1 - y)) y:real))``] THEN 16944 ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN 16945 SIMP_TAC std_ss [NETLIMIT_AT, o_DEF] THEN 16946 ASM_SIMP_TAC std_ss [CONTINUOUS_ADD, CONTINUOUS_AT_ID, CONTINUOUS_SUB, 16947 CONTINUOUS_CONST] THEN 16948 ASM_REAL_ARITH_TAC, 16949 REPEAT STRIP_TAC THENL [METIS_TAC [REAL_ARITH ``~(0 <= x /\ x < 0:real)``], 16950 ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC]]]]); 16951 16952(* ------------------------------------------------------------------------- *) 16953(* Cardinality of the reals. This is done in a rather laborious way to avoid *) 16954(* any dependence on the theories of analysis. *) 16955(* ------------------------------------------------------------------------- *) 16956 16957val lemma = prove ( 16958 ``!s m n. sum (s INTER (m..n)) (\i. inv(&3 pow i)) < &3 / &2 / &3 pow m``, 16959 REPEAT GEN_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN 16960 EXISTS_TAC ``sum (m..n) (\i. inv(&3 pow i))`` THEN CONJ_TAC THENL 16961 [ (* goal 1 (of 2) *) 16962 MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN 16963 SIMP_TAC std_ss [FINITE_NUMSEG, INTER_SUBSET, REAL_LE_INV_EQ, 16964 POW_POS, REAL_POS], 16965 (* goal 2 (of 2) *) 16966 completeInduct_on `n - m:num` THEN GEN_TAC THEN GEN_TAC THEN 16967 DISCH_TAC THEN FULL_SIMP_TAC std_ss [] THEN POP_ASSUM K_TAC THEN 16968 KNOW_TAC ``(!m'. m' < n - m ==> 16969 !n m''. (m' = n - m'') ==> 16970 sum (m'' .. n) (\i. inv (3 pow i)) < 3 / 2 / 3 pow m'') ==> 16971 (!n' m''. (n' - m'' < n - m) ==> 16972 sum (m'' .. n') (\i. inv (3 pow i)) < 3 / 2 / 3 pow m'')`` THENL 16973 [ METIS_TAC [], ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN DISCH_TAC ] THEN 16974 ASM_CASES_TAC ``m:num <= n`` THENL 16975 [ (* goal 2.1 (of 2) *) 16976 ASM_SIMP_TAC std_ss [SUM_CLAUSES_LEFT] THEN ASM_CASES_TAC ``m + 1 <= n:num`` THENL 16977 [ (* goal 2.1.1 (of 2) *) 16978 FIRST_X_ASSUM (MP_TAC o SPECL [``n:num``, ``SUC m``]) THEN 16979 KNOW_TAC ``n - SUC m < n - m`` THENL 16980 [ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 16981 ASM_SIMP_TAC arith_ss [ADD1, REAL_POW_ADD]] THEN 16982 MATCH_MP_TAC (REAL_ARITH 16983 ``a + j:real <= k ==> x < j ==> a + x < k:real``) THEN 16984 KNOW_TAC ``3 pow m <> 0:real`` THENL 16985 [MATCH_MP_TAC POW_NZ THEN REAL_ARITH_TAC, DISCH_TAC] THEN 16986 ASM_SIMP_TAC real_ss [real_div, REAL_INV_MUL, POW_1] THEN 16987 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 16988 GEN_REWR_TAC (LAND_CONV o LAND_CONV) [GSYM REAL_MUL_RID] THEN 16989 REWRITE_TAC [GSYM REAL_ADD_LDISTRIB, GSYM REAL_MUL_ASSOC] THEN 16990 MATCH_MP_TAC REAL_LE_LMUL_IMP THEN CONJ_TAC THENL 16991 [REWRITE_TAC [REAL_LE_INV_EQ] THEN MATCH_MP_TAC POW_POS THEN 16992 REAL_ARITH_TAC, ALL_TAC] THEN REWRITE_TAC [GSYM real_div] THEN 16993 SIMP_TAC real_ss [REAL_LE_RDIV_EQ, REAL_ADD_RDISTRIB, real_div] THEN 16994 REWRITE_TAC [REAL_MUL_ASSOC] THEN SIMP_TAC real_ss [REAL_MUL_LINV], 16995 ALL_TAC], ALL_TAC] THEN 16996 RULE_ASSUM_TAC (REWRITE_RULE[NOT_LESS_EQUAL, GSYM NUMSEG_EMPTY]) THEN 16997 ASM_REWRITE_TAC [SUM_CLAUSES, REAL_ADD_RID] THEN 16998 (KNOW_TAC ``0:real < 3 pow m`` THENL 16999 [MATCH_MP_TAC REAL_POW_LT THEN REAL_ARITH_TAC, DISCH_TAC] THEN 17000 ASM_SIMP_TAC real_ss [REAL_LT_RDIV_EQ, REAL_MUL_LINV, REAL_LT_IMP_NE])]); 17001 17002val CARD_EQ_REAL = store_thm 17003 ("CARD_EQ_REAL", ``univ(:real) =_c univ(:num->bool)``, 17004 REWRITE_TAC [GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL 17005 [ (* goal 1 (of 2) *) 17006 KNOW_TAC ``univ(:real) <=_c (univ(:num) *_c univ(:num->bool)) /\ 17007 (univ(:num) *_c univ(:num->bool)) <=_c univ(:num -> bool)`` THENL 17008 [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN 17009 CONJ_TAC THENL 17010 [ALL_TAC, 17011 MATCH_MP_TAC CARD_MUL2_ABSORB_LE THEN REWRITE_TAC[INFINITE_CARD_LE] THEN 17012 SIMP_TAC std_ss [CANTOR_THM_UNIV, CARD_LT_IMP_LE, CARD_LE_REFL]] THEN 17013 KNOW_TAC ``univ(:real) <=_c (univ(:num) *_c {x:real | &0 <= x}) /\ 17014 (univ(:num) *_c {x:real | &0 <= x}) <=_c 17015 (univ(:num) *_c univ(:num -> bool))`` THENL 17016 [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN 17017 CONJ_TAC THENL 17018 [SIMP_TAC std_ss [LE_C, mul_c, EXISTS_PROD, IN_ELIM_PAIR_THM, IN_UNIV] THEN 17019 EXISTS_TAC ``\(n,x:real). -(&1) pow n * x`` THEN X_GEN_TAC ``x:real`` THEN 17020 KNOW_TAC ``?(p_2 :real). (p_2 IN {x | (0 :real) <= x} /\ 17021 ((\((n :num),(x :real)). -(1 :real) pow n * x) (0,p_2) = (x :real))) \/ 17022 (p_2 IN {x | (0 :real) <= x} /\ 17023 ((\((n :num),(x :real)). -(1 :real) pow n * x) (1,p_2) = (x :real)))`` THENL 17024 [ALL_TAC, METIS_TAC [OR_EXISTS_THM]] THEN EXISTS_TAC ``abs x:real`` THEN 17025 SIMP_TAC std_ss [GSPECIFICATION, pow, POW_1] THEN REAL_ARITH_TAC, 17026 ALL_TAC] THEN 17027 MATCH_MP_TAC CARD_LE_MUL THEN SIMP_TAC std_ss [CARD_LE_REFL] THEN 17028 MP_TAC(ISPECL [``univ(:num)``, ``univ(:num)``] CARD_MUL_ABSORB_LE) THEN 17029 SIMP_TAC std_ss [CARD_LE_REFL, num_INFINITE] THEN 17030 SIMP_TAC std_ss [le_c, mul_c, IN_UNIV, FORALL_PROD, IN_ELIM_PAIR_THM] THEN 17031 REWRITE_TAC [GSYM PAIR_EQ] THEN 17032 SIMP_TAC std_ss [GSYM FORALL_PROD, INJECTIVE_LEFT_INVERSE] THEN 17033 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] 17034 17035 THEN 17036 MAP_EVERY X_GEN_TAC [``Pair:num#num->num``, ``Unpair:num->num#num``] THEN 17037 DISCH_TAC THEN 17038 EXISTS_TAC ``\x:real n:num. &(FST(Unpair n)) * x <= &(SND(Unpair n))`` THEN 17039 SIMP_TAC std_ss [] THEN 17040 KNOW_TAC ``!(x :real) (y :real). (\x y. 17041 x IN {x | (0 :real) <= x} /\ y IN {x | (0 :real) <= x} /\ 17042 ((\(n :num). ((&FST ((Unpair :num -> num # num) n)) :real) * x <= 17043 ((&SND (Unpair n)) :real)) = 17044 (\(n :num). ((&FST (Unpair n)) :real) * y <= ((&SND (Unpair n)) :real))) ==> 17045 (x = y)) x y`` THENL 17046 [ALL_TAC, METIS_TAC []] 17047 17048 THEN 17049 MATCH_MP_TAC REAL_WLOG_LT THEN SIMP_TAC std_ss [GSPECIFICATION, FUN_EQ_THM] THEN 17050 CONJ_TAC THENL [SIMP_TAC std_ss [EQ_SYM_EQ, CONJ_ACI], ALL_TAC] THEN 17051 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN REPEAT STRIP_TAC THEN 17052 FIRST_X_ASSUM(MP_TAC o GENL [``p:num``, ``q:num``] o 17053 SPEC ``(Pair:num#num->num) (p,q)``) THEN 17054 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN 17055 MP_TAC(SPEC ``y - x:real`` REAL_ARCH) THEN 17056 ASM_SIMP_TAC std_ss [REAL_SUB_LT, NOT_FORALL_THM] THEN 17057 DISCH_THEN(MP_TAC o SPEC ``&2:real``) THEN 17058 DISCH_THEN (X_CHOOSE_TAC ``p:num``) THEN EXISTS_TAC ``p:num`` THEN 17059 MP_TAC(ISPEC ``&p * x:real`` REAL_BIGNUM) THEN 17060 ONCE_REWRITE_TAC [METIS [] ``(?n. &p * x < &n:real) = (?n. (\n. &p * x < &n) n)``] THEN 17061 DISCH_THEN (MP_TAC o MATCH_MP WOP) THEN SIMP_TAC std_ss [] THEN 17062 DISCH_THEN (X_CHOOSE_TAC ``n:num``) THEN EXISTS_TAC ``n:num`` THEN 17063 POP_ASSUM MP_TAC THEN SPEC_TAC (``n:num``,``n:num``) THEN 17064 KNOW_TAC ``!n. (\n. &p * x < &n:real /\ (!m. m < n ==> ~(&p * x < &m)) ==> 17065 ~(&p * x <= &n <=> &p * y <= &n:real)) n`` THENL 17066 [ALL_TAC, METIS_TAC []] THEN MATCH_MP_TAC INDUCTION THEN 17067 17068 ASM_SIMP_TAC std_ss [REAL_LE_MUL, REAL_POS, 17069 REAL_ARITH ``x:real < &0 <=> ~(&0 <= x)``] 17070 17071 THEN 17072 X_GEN_TAC ``q:num`` THEN REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN 17073 DISCH_THEN(K ALL_TAC) THEN STRIP_TAC THEN 17074 FIRST_X_ASSUM(MP_TAC o SPEC ``q:num``) THEN 17075 SIMP_TAC arith_ss [LT] THEN POP_ASSUM MP_TAC THEN 17076 POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN 17077 POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC, 17078 17079 (* goal 2 (of 2) *) 17080 REWRITE_TAC[le_c, IN_UNIV] THEN 17081 EXISTS_TAC ``\s:num->bool. sup { sum (s INTER ((0:num)..n)) (\i. inv(&3 pow i)) | 17082 n IN univ(:num) }`` THEN 17083 MAP_EVERY X_GEN_TAC [``x:num->bool``, ``y:num->bool``] THEN 17084 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 17085 SIMP_TAC std_ss [EXTENSION, NOT_FORALL_THM] THEN 17086 ONCE_REWRITE_TAC [METIS [] ``(?x':num. x' IN x <=/=> x' IN y) = 17087 (?x'. (\x'. x' IN x <=/=> x' IN y) x')``] THEN 17088 DISCH_THEN (MP_TAC o MATCH_MP WOP) THEN SIMP_TAC std_ss [] THEN 17089 MAP_EVERY (fn w => SPEC_TAC(w,w)) [``y:num->bool``, ``x:num->bool``] THEN 17090 KNOW_TAC ``!x y. 17091 (?n. ~(n IN x <=> n IN y) /\ (\x y n. !m. m < n ==> (m IN x <=> m IN y)) x y n) ==> 17092 (\x y. sup {sum (x INTER (0 .. n)) (\i. inv (3 pow i)) | n IN univ(:num)} <> 17093 sup {sum (y INTER (0 .. n)) (\i. inv (3 pow i)) | n IN univ(:num)}) x y`` THENL 17094 [ALL_TAC, METIS_TAC []] THEN 17095 MATCH_MP_TAC(MESON[] 17096 ``((!P Q n. R P Q n <=> R Q P n) /\ (!P Q. SS P Q <=> SS Q P)) /\ 17097 (!P Q. (?n. n IN P /\ ~(n IN Q) /\ R P Q n) ==> SS P Q) 17098 ==> !P Q. (?n:num. ~(n IN P <=> n IN Q) /\ R P Q n) ==> SS P Q``) THEN 17099 SIMP_TAC std_ss [] THEN CONJ_TAC THENL 17100 [ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN METIS_TAC [], SIMP_TAC std_ss []] THEN 17101 MAP_EVERY X_GEN_TAC [``x:num->bool``, ``y:num->bool``] THEN 17102 DISCH_THEN(X_CHOOSE_THEN ``n:num`` STRIP_ASSUME_TAC) THEN 17103 MATCH_MP_TAC(REAL_ARITH ``!z:real. y < z /\ z <= x ==> ~(x = y)``) THEN 17104 17105 EXISTS_TAC ``sum (x INTER ((0:num)..n)) (\i. inv(&3 pow i))`` THEN CONJ_TAC THENL 17106 [ (* goal 2.1 (of 2) *) 17107 MATCH_MP_TAC REAL_LET_TRANS THEN 17108 EXISTS_TAC 17109 ``sum (y INTER ((0:num)..n)) (\i. inv(&3 pow i)) + 17110 &3 / &2 / &3 pow (SUC n)`` THEN 17111 17112 CONJ_TAC THENL 17113 [MATCH_MP_TAC REAL_SUP_LE_S THEN 17114 CONJ_TAC THENL [SET_TAC[], SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV]] THEN 17115 X_GEN_TAC ``p:num`` THEN ASM_CASES_TAC ``n:num <= p`` THENL 17116 [MATCH_MP_TAC(REAL_ARITH 17117 ``!d. (s:real = t + d) /\ d <= e ==> s <= t + e``) THEN 17118 EXISTS_TAC ``sum(y INTER (n+(1:num)..p)) (\i. inv (&3 pow i))`` THEN 17119 CONJ_TAC THENL 17120 [ONCE_REWRITE_TAC[INTER_COMM] THEN 17121 SIMP_TAC std_ss [INTER_DEF, SUM_RESTRICT_SET] THEN 17122 ASM_SIMP_TAC std_ss [SUM_COMBINE_R, ZERO_LESS_EQ], 17123 SIMP_TAC std_ss [ADD1, lemma, REAL_LT_IMP_LE]], 17124 MATCH_MP_TAC(REAL_ARITH ``y:real <= x /\ &0 <= d ==> y <= x + d``) THEN 17125 SIMP_TAC real_ss [REAL_LE_DIV, REAL_POS, POW_POS] THEN 17126 MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN 17127 SIMP_TAC real_ss [REAL_LE_INV_EQ, POW_POS, REAL_POS] THEN 17128 SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN MATCH_MP_TAC 17129 (SET_RULE ``s SUBSET t ==> u INTER s SUBSET u INTER t``) THEN 17130 REWRITE_TAC[SUBSET_NUMSEG] THEN ASM_SIMP_TAC arith_ss []], 17131 ONCE_REWRITE_TAC[INTER_COMM] THEN 17132 SIMP_TAC std_ss [INTER_DEF, SUM_RESTRICT_SET] THEN ASM_CASES_TAC ``n = 0:num`` THENL 17133 [FIRST_X_ASSUM SUBST_ALL_TAC THEN 17134 FULL_SIMP_TAC real_ss [SUM_SING, NUMSEG_SING, pow] THEN 17135 SIMP_TAC real_ss [REAL_LT_LDIV_EQ, REAL_INV1] THEN REAL_ARITH_TAC, 17136 ASM_SIMP_TAC std_ss [SUM_CLAUSES_RIGHT, LE_1, ZERO_LESS_EQ, REAL_ADD_RID] THEN 17137 MATCH_MP_TAC(REAL_ARITH ``(s:real = t) /\ d < e ==> s + d < t + e``) THEN 17138 CONJ_TAC THENL 17139 [MATCH_MP_TAC SUM_EQ_NUMSEG THEN 17140 ASM_SIMP_TAC std_ss [ARITH_PROVE ``~(n = 0:num) /\ m <= n - 1 ==> m < n``], 17141 SIMP_TAC real_ss [pow, real_div, REAL_INV_MUL, REAL_MUL_ASSOC] THEN 17142 KNOW_TAC ``3 pow n <> 0:real`` THENL 17143 [MATCH_MP_TAC POW_NZ THEN REAL_ARITH_TAC, DISCH_TAC] THEN 17144 KNOW_TAC ``0:real < 3 pow n`` THENL 17145 [MATCH_MP_TAC REAL_POW_LT THEN REAL_ARITH_TAC, DISCH_TAC] THEN 17146 ASM_SIMP_TAC real_ss [REAL_INV_MUL, REAL_MUL_ASSOC] THEN 17147 GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN 17148 MATCH_MP_TAC REAL_LT_RMUL_IMP THEN ASM_SIMP_TAC real_ss [REAL_LT_INV_EQ] THEN 17149 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 17150 SIMP_TAC real_ss [REAL_MUL_ASSOC, REAL_MUL_LINV] THEN 17151 SIMP_TAC real_ss [REAL_INV_1OVER, REAL_LT_LDIV_EQ]]]], 17152 MP_TAC(ISPEC ``{ sum (x INTER ((0:num)..n)) (\i. inv(&3 pow i)) | n IN univ(:num) }`` 17153 SUP) THEN SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV] THEN 17154 KNOW_TAC ``{sum (x INTER (0 .. n)) (\i. inv (3 pow i)) | n | T} <> {} /\ 17155 (?b. !n. sum (x INTER (0 .. n)) (\i. inv (3 pow i)) <= b)`` THENL 17156 [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 17157 SIMP_TAC std_ss []] THEN 17158 CONJ_TAC THENL [SET_TAC[], ALL_TAC] THEN 17159 EXISTS_TAC ``&3 / &2 / (&3:real) pow 0`` THEN 17160 SIMP_TAC std_ss [lemma, REAL_LT_IMP_LE]]]); 17161 17162val UNCOUNTABLE_REAL = store_thm ("UNCOUNTABLE_REAL", 17163 ``~COUNTABLE univ(:real)``, 17164 REWRITE_TAC[COUNTABLE, ge_c] THEN 17165 KNOW_TAC ``univ(:num) <_c univ(:num->bool) /\ 17166 univ(:num->bool) <=_c univ(:real)`` THENL 17167 [ALL_TAC, METIS_TAC [CARD_LTE_TRANS]] THEN 17168 REWRITE_TAC[CANTOR_THM_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN 17169 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN REWRITE_TAC[CARD_EQ_REAL]); 17170 17171val CARD_EQ_REAL_IMP_UNCOUNTABLE = store_thm ("CARD_EQ_REAL_IMP_UNCOUNTABLE", 17172 ``!s:real->bool. s =_c univ(:real) ==> ~COUNTABLE s``, 17173 GEN_TAC THEN STRIP_TAC THEN 17174 DISCH_THEN (MP_TAC o SPEC ``univ(:real)`` o MATCH_MP 17175 (SIMP_RULE std_ss [CONJ_EQ_IMP] CARD_EQ_COUNTABLE)) THEN 17176 REWRITE_TAC[UNCOUNTABLE_REAL] THEN ASM_MESON_TAC[CARD_EQ_SYM]); 17177 17178(* ------------------------------------------------------------------------- *) 17179(* Cardinalities of various useful sets. *) 17180(* ------------------------------------------------------------------------- *) 17181 17182(* TODO: maybe the original theorem is about R^N spaces *) 17183val CARD_EQ_EUCLIDEAN = store_thm ("CARD_EQ_EUCLIDEAN", 17184 ``univ(:real) =_c univ(:real)``, 17185 REWRITE_TAC [eq_c, IN_UNIV] THEN EXISTS_TAC ``(\x. x:real)`` THEN 17186 METIS_TAC []); 17187 17188(* TODO: maybe the original theorem is about R^N spaces *) 17189val UNCOUNTABLE_EUCLIDEAN = store_thm ("UNCOUNTABLE_EUCLIDEAN", 17190 ``~COUNTABLE univ(:real)``, 17191 MATCH_MP_TAC CARD_EQ_REAL_IMP_UNCOUNTABLE THEN 17192 REWRITE_TAC[CARD_EQ_EUCLIDEAN]); 17193 17194val CARD_EQ_INTERVAL = store_thm ("CARD_EQ_INTERVAL", 17195 ``(!a b:real. ~(interval(a,b) = {}) ==> (interval[a,b] =_c univ(:real))) /\ 17196 (!a b:real. ~(interval(a,b) = {}) ==> (interval(a,b) =_c univ(:real)))``, 17197 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN 17198 ASM_CASES_TAC ``interval(a:real,b) = {}`` THEN ASM_REWRITE_TAC[] THEN 17199 CONJ_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL 17200 [REWRITE_TAC[CARD_LE_UNIV], 17201 KNOW_TAC ``univ(:real) <=_c interval(a:real,b) /\ 17202 interval(a:real,b) <=_c interval [(a,b)]`` THENL 17203 [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN 17204 SIMP_TAC std_ss [CARD_LE_SUBSET, INTERVAL_OPEN_SUBSET_CLOSED], 17205 REWRITE_TAC[CARD_LE_UNIV], 17206 ALL_TAC] THEN 17207 RULE_ASSUM_TAC (REWRITE_RULE [INTERVAL_NE_EMPTY]) THEN 17208 FIRST_X_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_OPEN_INTERVAL_UNIV) THEN 17209 DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN 17210 MESON_TAC[CARD_EQ_IMP_LE, CARD_EQ_SYM]); 17211 17212val UNCOUNTABLE_INTERVAL = store_thm ("UNCOUNTABLE_INTERVAL", 17213 ``(!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval[a,b])) /\ 17214 (!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval(a,b)))``, 17215 SIMP_TAC std_ss [CARD_EQ_REAL_IMP_UNCOUNTABLE, CARD_EQ_INTERVAL]); 17216 17217val COUNTABLE_OPEN_INTERVAL = store_thm ("COUNTABLE_OPEN_INTERVAL", 17218 ``!a b. COUNTABLE(interval(a,b)) <=> (interval(a,b) = {})``, 17219 MESON_TAC[COUNTABLE_EMPTY, UNCOUNTABLE_INTERVAL]); 17220 17221val CARD_EQ_OPEN = store_thm ("CARD_EQ_OPEN", 17222 ``!s:real->bool. open s /\ ~(s = {}) ==> s =_c univ(:real)``, 17223 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL 17224 [REWRITE_TAC[CARD_LE_UNIV], 17225 UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN 17226 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_INTERVAL]) THEN 17227 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 17228 DISCH_THEN(X_CHOOSE_TAC ``c:real``) THEN 17229 DISCH_THEN(MP_TAC o SPEC ``c:real``) THEN 17230 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 17231 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN 17232 ASM_CASES_TAC ``interval(a:real,b) = {}`` THEN 17233 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN STRIP_TAC THEN 17234 KNOW_TAC ``univ(:real) <=_c interval[a:real,b] /\ 17235 interval[a:real,b] <=_c s:real->bool`` THENL 17236 [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN 17237 ASM_SIMP_TAC std_ss [CARD_LE_SUBSET] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN 17238 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC std_ss [CARD_EQ_INTERVAL]]); 17239 17240val UNCOUNTABLE_OPEN = store_thm ("UNCOUNTABLE_OPEN", 17241 ``!s:real->bool. open s /\ ~(s = {}) ==> ~(COUNTABLE s)``, 17242 SIMP_TAC std_ss [CARD_EQ_OPEN, CARD_EQ_REAL_IMP_UNCOUNTABLE]); 17243 17244val CARD_EQ_BALL = store_thm ("CARD_EQ_BALL", 17245 ``!a:real r. &0 < r ==> ball(a,r) =_c univ(:real)``, 17246 SIMP_TAC std_ss [CARD_EQ_OPEN, OPEN_BALL, BALL_EQ_EMPTY, GSYM REAL_NOT_LT]); 17247 17248val CARD_EQ_CBALL = store_thm ("CARD_EQ_CBALL", 17249 ``!a:real r. &0 < r ==> cball(a,r) =_c univ(:real)``, 17250 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL 17251 [REWRITE_TAC[CARD_LE_UNIV], 17252 KNOW_TAC ``univ(:real) <=_c ball(a:real,r) /\ 17253 ball(a:real,r) <=_c cball (a,r:real)`` THENL 17254 [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN 17255 SIMP_TAC std_ss [CARD_LE_SUBSET, BALL_SUBSET_CBALL] THEN 17256 MATCH_MP_TAC CARD_EQ_IMP_LE THEN 17257 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC std_ss [CARD_EQ_BALL]]); 17258 17259val FINITE_IMP_NOT_OPEN = store_thm ("FINITE_IMP_NOT_OPEN", 17260 ``!s:real->bool. FINITE s /\ ~(s = {}) ==> ~(open s)``, 17261 MESON_TAC[UNCOUNTABLE_OPEN, FINITE_IMP_COUNTABLE]); 17262 17263val OPEN_IMP_INFINITE = store_thm ("OPEN_IMP_INFINITE", 17264 ``!s. open s ==> (s = {}) \/ INFINITE s``, 17265 MESON_TAC[FINITE_IMP_NOT_OPEN]); 17266 17267val EMPTY_INTERIOR_FINITE = store_thm ("EMPTY_INTERIOR_FINITE", 17268 ``!s:real->bool. FINITE s ==> (interior s = {})``, 17269 REPEAT STRIP_TAC THEN MP_TAC(ISPEC ``s:real->bool`` OPEN_INTERIOR) THEN 17270 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 17271 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] FINITE_IMP_NOT_OPEN) THEN 17272 MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``s:real->bool`` THEN 17273 ASM_REWRITE_TAC[INTERIOR_SUBSET]); 17274 17275val FINITE_CBALL = store_thm ("FINITE_CBALL", 17276 ``!a:real r. FINITE(cball(a,r)) <=> r <= &0``, 17277 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``r < &0:real`` THEN 17278 ASM_SIMP_TAC std_ss [CBALL_EMPTY, REAL_LT_IMP_LE, FINITE_EMPTY] THEN 17279 ASM_CASES_TAC ``r = &0:real`` THEN 17280 ASM_REWRITE_TAC[CBALL_TRIVIAL, FINITE_SING, REAL_LE_REFL] THEN 17281 EQ_TAC THENL [ALL_TAC, ASM_REAL_ARITH_TAC] THEN 17282 DISCH_THEN(MP_TAC o MATCH_MP EMPTY_INTERIOR_FINITE) THEN 17283 REWRITE_TAC[INTERIOR_CBALL, BALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC); 17284 17285val FINITE_BALL = store_thm ("FINITE_BALL", 17286 ``!a:real r. FINITE(ball(a,r)) <=> r <= &0``, 17287 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``r <= &0:real`` THEN 17288 ASM_SIMP_TAC std_ss [BALL_EMPTY, REAL_LT_IMP_LE, FINITE_EMPTY] THEN 17289 DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[CONJ_EQ_IMP] 17290 FINITE_IMP_NOT_OPEN)) THEN 17291 REWRITE_TAC[OPEN_BALL, BALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC); 17292 17293(* ------------------------------------------------------------------------- *) 17294(* "Iff" forms of constancy of function from connected set into a set that *) 17295(* is smaller than R, or countable, or finite, or disconnected, or discrete. *) 17296(* ------------------------------------------------------------------------- *) 17297 17298val CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ = store_thm 17299 ("CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ", 17300 ``(!s. connected s <=> 17301 !f:real->real t. 17302 f continuous_on s /\ IMAGE f s SUBSET t /\ 17303 (!y. y IN t ==> (connected_component t y = {y})) 17304 ==> ?a. !x. x IN s ==> (f x = a)) /\ 17305 (!s. connected s <=> 17306 !f:real->real. 17307 f continuous_on s /\ 17308 (!x. x IN s 17309 ==> ?e. &0 < e /\ 17310 !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x)) 17311 ==> ?a. !x. x IN s ==> (f x = a)) /\ 17312 (!s. connected s <=> 17313 !f:real->real. 17314 f continuous_on s /\ FINITE(IMAGE f s) 17315 ==> ?a. !x. x IN s ==> (f x = a))``, 17316 SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN X_GEN_TAC ``s:real->bool`` THEN 17317 MATCH_MP_TAC(TAUT 17318 `(s ==> t) /\ (t ==> u) /\ (u ==> v) /\ (v ==> s) 17319 ==> (s <=> t) /\ (s <=> u) /\ (s <=> v)`) THEN 17320 REPEAT CONJ_TAC THENL 17321 [REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 17322 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN 17323 FIRST_X_ASSUM(X_CHOOSE_TAC ``x:real`` o 17324 REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 17325 EXISTS_TAC ``(f:real->real) x`` THEN 17326 MATCH_MP_TAC(SET_RULE 17327 ``IMAGE f s SUBSET {a} ==> !y. y IN s ==> (f y = a)``) THEN 17328 FIRST_X_ASSUM(MP_TAC o SPEC ``(f:real->real) x``) THEN 17329 KNOW_TAC ``(f:real->real) x IN t`` THENL 17330 [ASM_SET_TAC [], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 17331 DISCH_THEN(SUBST1_TAC o SYM)] THEN 17332 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN 17333 ASM_SIMP_TAC std_ss [CONNECTED_CONTINUOUS_IMAGE] THEN ASM_SET_TAC [], 17334 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN 17335 EXISTS_TAC ``IMAGE (f:real->real) s`` THEN 17336 ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE, SUBSET_REFL] THEN 17337 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 17338 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 17339 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 17340 MATCH_MP_TAC(SET_RULE 17341 ``(!y. y IN s /\ f y IN connected_component (IMAGE f s) a ==> (f y = a)) /\ 17342 connected_component (IMAGE f s) a SUBSET (IMAGE f s) /\ 17343 connected_component (IMAGE f s) a a 17344 ==> (connected_component (IMAGE f s) a = {a})``) THEN 17345 SIMP_TAC std_ss [CONNECTED_COMPONENT_SUBSET, CONNECTED_COMPONENT_REFL_EQ] THEN 17346 ASM_SIMP_TAC std_ss [FUN_IN_IMAGE] THEN X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN 17347 MP_TAC(ISPEC ``connected_component (IMAGE (f:real->real) s) (f x)`` 17348 CONNECTED_CLOSED) THEN 17349 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN 17350 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 17351 ASM_REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC 17352 [``cball((f:real->real) x,e / &2)``, 17353 ``univ(:real) DIFF ball((f:real->real) x,e)``] THEN 17354 SIMP_TAC std_ss [GSYM OPEN_CLOSED, OPEN_BALL, CLOSED_CBALL] THEN 17355 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REPEAT CONJ_TAC THENL 17356 [REWRITE_TAC[SUBSET_DEF, IN_CBALL, IN_UNION, IN_DIFF, IN_BALL, IN_UNIV] THEN 17357 ONCE_REWRITE_TAC [METIS [] 17358 ``(dist (f x,x') <= e / 2 \/ ~(dist (f x,x') < e)) = 17359 (\x'. dist (f x,x') <= e / 2 \/ ~(dist (f x,x') < e)) x'``] THEN 17360 MATCH_MP_TAC(MESON[SUBSET_DEF, CONNECTED_COMPONENT_SUBSET] 17361 ``(!x. x IN s ==> P x) 17362 ==> (!x. x IN connected_component s y ==> P x)``) THEN 17363 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN X_GEN_TAC ``z:real`` THEN 17364 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``z:real``) THEN 17365 ASM_SIMP_TAC real_ss [dist, REAL_LE_RDIV_EQ] THEN ASM_REAL_ARITH_TAC, 17366 MATCH_MP_TAC(SET_RULE 17367 ``(!x. x IN s /\ x IN t ==> F) ==> (s INTER t INTER u = {})``) THEN 17368 REWRITE_TAC[IN_BALL, IN_CBALL, IN_DIFF, IN_UNIV] THEN 17369 UNDISCH_TAC ``&0 < e:real`` THEN 17370 ASM_SIMP_TAC real_ss [dist, REAL_LE_RDIV_EQ] THEN REAL_ARITH_TAC, 17371 EXISTS_TAC ``(f:real->real) x`` THEN 17372 ASM_SIMP_TAC std_ss [CENTRE_IN_CBALL, REAL_HALF, REAL_LT_IMP_LE, IN_INTER] THEN 17373 SIMP_TAC std_ss [SPECIFICATION] THEN 17374 ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_REFL_EQ, FUN_IN_IMAGE], 17375 EXISTS_TAC ``(f:real->real) y`` THEN 17376 ASM_REWRITE_TAC[IN_INTER, IN_DIFF, IN_UNIV, IN_BALL, REAL_NOT_LT] THEN 17377 ASM_SIMP_TAC std_ss [ONCE_REWRITE_RULE[DIST_SYM] dist]], 17378 DISCH_TAC THEN X_GEN_TAC ``f:real->real`` THEN 17379 POP_ASSUM (MP_TAC o SPEC ``f:real->real``) THEN 17380 DISCH_THEN(fn th => STRIP_TAC THEN MATCH_MP_TAC th) THEN 17381 ASM_REWRITE_TAC[] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 17382 ASM_CASES_TAC ``IMAGE (f:real->real) s DELETE (f x) = {}`` THENL 17383 [EXISTS_TAC ``&1:real`` THEN REWRITE_TAC[REAL_LT_01] THEN ASM_SET_TAC [], 17384 ALL_TAC] THEN 17385 EXISTS_TAC 17386 ``inf{abs(z - f x) |z| z IN IMAGE (f:real->real) s DELETE (f x)}`` THEN 17387 SIMP_TAC real_ss [GSYM IMAGE_DEF] THEN 17388 ASM_SIMP_TAC std_ss [REAL_LT_INF_FINITE, REAL_INF_LE_FINITE, FINITE_DELETE, 17389 IMAGE_FINITE, IMAGE_EQ_EMPTY] THEN 17390 SIMP_TAC std_ss [FORALL_IN_IMAGE, EXISTS_IN_IMAGE] THEN 17391 SIMP_TAC real_ss [IN_DELETE, GSYM ABS_NZ, REAL_SUB_0, IN_IMAGE] THEN 17392 MESON_TAC[REAL_LE_REFL], 17393 REWRITE_TAC[CONNECTED_CLOSED_IN_EQ] THEN 17394 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 17395 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 17396 MAP_EVERY X_GEN_TAC [``t:real->bool``, ``u:real->bool``] THEN 17397 STRIP_TAC THEN EXISTS_TAC 17398 ``(\x. if x IN t then 0 else 1:real):real->real`` THEN 17399 SIMP_TAC std_ss [NOT_IMP] THEN REPEAT CONJ_TAC THENL 17400 [EXPAND_TAC "s" THEN 17401 ONCE_REWRITE_TAC [METIS [] ``(\x:real. if x IN t then 0 else 1:real) = 17402 (\x. if (\x. x IN t) x then (\x. 0) x else (\x. 1) x)``] THEN 17403 MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN 17404 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CONST] THEN ASM_SET_TAC [], 17405 MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``{0:real;1:real}`` THEN 17406 REWRITE_TAC[FINITE_INSERT, FINITE_EMPTY] THEN SET_TAC[], 17407 SUBGOAL_THEN ``?a b:real. a IN s /\ a IN t /\ b IN s /\ ~(b IN t)`` 17408 STRIP_ASSUME_TAC THENL 17409 [ASM_SET_TAC [], GEN_TAC] THEN CCONTR_TAC THEN 17410 POP_ASSUM (MP_TAC o SIMP_RULE std_ss []) THEN 17411 DISCH_THEN(fn th => MP_TAC(SPEC ``a:real`` th) THEN 17412 MP_TAC(SPEC ``b:real`` th)) THEN 17413 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]]); 17414 17415val CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ = store_thm 17416 ("CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ", 17417 ``(!s. connected s <=> 17418 !f:real->real t. 17419 f continuous_on s /\ IMAGE f s SUBSET t /\ 17420 (!y. y IN t ==> (connected_component t y = {y})) 17421 ==> ?a. !x. x IN s ==> (f x = a))``, 17422 REWRITE_TAC [CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ]); 17423 17424val CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ = store_thm 17425 ("CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ", 17426 ``(!s. connected s <=> 17427 !f:real->real. 17428 f continuous_on s /\ 17429 (!x. x IN s 17430 ==> ?e. &0 < e /\ 17431 !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x)) 17432 ==> ?a. !x. x IN s ==> (f x = a)) ``, 17433 METIS_TAC [CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ]); 17434 17435val CONTINUOUS_FINITE_RANGE_CONSTANT_EQ = store_thm 17436 ("CONTINUOUS_FINITE_RANGE_CONSTANT_EQ", 17437 ``(!s. connected s <=> 17438 !f:real->real. 17439 f continuous_on s /\ FINITE(IMAGE f s) 17440 ==> ?a. !x. x IN s ==> (f x = a))``, 17441 METIS_TAC [CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ]); 17442 17443val CONTINUOUS_DISCONNECTED_RANGE_CONSTANT = store_thm 17444 ("CONTINUOUS_DISCONNECTED_RANGE_CONSTANT", 17445 ``!f:real->real s. 17446 connected s /\ 17447 f continuous_on s /\ IMAGE f s SUBSET t /\ 17448 (!y. y IN t ==> (connected_component t y = {y})) 17449 ==> ?a. !x. x IN s ==> (f x = a)``, 17450 MESON_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ]); 17451 17452val CONTINUOUS_DISCRETE_RANGE_CONSTANT = store_thm 17453 ("CONTINUOUS_DISCRETE_RANGE_CONSTANT", 17454 ``!f:real->real s. 17455 connected s /\ 17456 f continuous_on s /\ 17457 (!x. x IN s 17458 ==> ?e. &0 < e /\ 17459 !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x)) 17460 ==> ?a. !x. x IN s ==> (f x = a)``, 17461 KNOW_TAC ``!s f:real->real. 17462 connected s /\ 17463 f continuous_on s /\ 17464 (!x. x IN s 17465 ==> ?e. &0 < e /\ 17466 !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x)) 17467 ==> ?a. !x. x IN s ==> (f x = a)`` THENL 17468 [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]] THEN 17469 SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM, CONJ_EQ_IMP] THEN 17470 SIMP_TAC std_ss [AND_IMP_INTRO, GSYM CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ]); 17471 17472val CONTINUOUS_FINITE_RANGE_CONSTANT = store_thm 17473 ("CONTINUOUS_FINITE_RANGE_CONSTANT", 17474 ``!f:real->real s. 17475 connected s /\ 17476 f continuous_on s /\ 17477 FINITE(IMAGE f s) 17478 ==> ?a. !x. x IN s ==> (f x = a)``, 17479 MESON_TAC[CONTINUOUS_FINITE_RANGE_CONSTANT_EQ]); 17480 17481(* ------------------------------------------------------------------------- *) 17482(* Homeomorphism of hyperplanes. *) 17483(* ------------------------------------------------------------------------- *) 17484 17485val lemma = prove ( 17486 ``~(a = 0) 17487 ==> {x:real | a * x = b} homeomorphic {x:real | x = &0}``, 17488 REPEAT STRIP_TAC THEN SUBGOAL_THEN ``?c:real. a * c = b`` 17489 STRIP_ASSUME_TAC THENL 17490 [EXISTS_TAC ``inv a * b:real`` THEN 17491 ASM_SIMP_TAC real_ss [REAL_MUL_RINV, REAL_MUL_ASSOC], ALL_TAC] THEN 17492 REWRITE_TAC [homeomorphic, homeomorphism] THEN 17493 EXISTS_TAC ``(\x. 0):real->real`` THEN 17494 EXISTS_TAC ``(\x:real. inv a * b:real)`` THEN 17495 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN 17496 SIMP_TAC std_ss [CONTINUOUS_ON_CONST] THEN 17497 REPEAT STRIP_TAC THENL 17498 [ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN 17499 ASM_CASES_TAC ``0 < a:real`` THENL 17500 [ASM_SIMP_TAC real_ss [REAL_EQ_LDIV_EQ] THEN ASM_REAL_ARITH_TAC, ALL_TAC] THEN 17501 FULL_SIMP_TAC real_ss [REAL_NOT_LT, REAL_LE_LT] THENL [ALL_TAC, METIS_TAC []] THEN 17502 KNOW_TAC ``a < 0 ==> 0 < -a:real`` THENL [REAL_ARITH_TAC, ASM_REWRITE_TAC []] THEN 17503 DISCH_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_EQ_NEG] THEN 17504 REWRITE_TAC [real_div, REAL_ARITH ``-(a * b) = a * -b:real``] THEN 17505 ASM_SIMP_TAC std_ss [REAL_NEG_INV, GSYM real_div] THEN 17506 ASM_SIMP_TAC real_ss [REAL_EQ_LDIV_EQ] THEN ASM_REAL_ARITH_TAC, 17507 METIS_TAC [], 17508 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN 17509 ASM_CASES_TAC ``0 < a:real`` THENL 17510 [ASM_SIMP_TAC real_ss [REAL_EQ_RDIV_EQ] THEN ASM_REAL_ARITH_TAC, ALL_TAC] THEN 17511 FULL_SIMP_TAC real_ss [REAL_NOT_LT, REAL_LE_LT] THENL [ALL_TAC, METIS_TAC []] THEN 17512 KNOW_TAC ``a < 0 ==> 0 < -a:real`` THENL [REAL_ARITH_TAC, ASM_REWRITE_TAC []] THEN 17513 DISCH_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_EQ_NEG] THEN 17514 REWRITE_TAC [real_div, REAL_ARITH ``-(a * b) = a * -b:real``] THEN 17515 ASM_SIMP_TAC std_ss [REAL_NEG_INV, GSYM real_div] THEN 17516 ASM_SIMP_TAC real_ss [REAL_EQ_RDIV_EQ] THEN ASM_REAL_ARITH_TAC]); 17517 17518val HOMEOMORPHIC_HYPERPLANES = store_thm ("HOMEOMORPHIC_HYPERPLANES", 17519 ``!a:real b c:real d. 17520 ~(a = 0) /\ ~(c = 0) 17521 ==> {x | a * x = b} homeomorphic {x | c * x = d}``, 17522 REPEAT STRIP_TAC THEN 17523 MATCH_MP_TAC HOMEOMORPHIC_TRANS THEN EXISTS_TAC ``{x:real | x = &0}`` THEN 17524 ASM_SIMP_TAC std_ss [lemma] THEN ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN 17525 ASM_SIMP_TAC std_ss [lemma]); 17526 17527val HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE = store_thm 17528 ("HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE", 17529 ``!a:real b c. 17530 ~(a = 0) 17531 ==> {x | a * x = b} homeomorphic {x:real | x = c}``, 17532 REPEAT STRIP_TAC THEN 17533 SUBGOAL_THEN ``{x:real | x = c} = {x | 1 * x = c}`` SUBST1_TAC 17534 THENL [ASM_SIMP_TAC real_ss [], MATCH_MP_TAC HOMEOMORPHIC_HYPERPLANES] THEN 17535 ASM_SIMP_TAC real_ss []); 17536 17537val HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE = store_thm 17538 ("HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE", 17539 ``!a:real b c. 17540 ~(a = 0) 17541 ==> {x:real | x = c} homeomorphic {x | a * x = b}``, 17542 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN 17543 SIMP_TAC std_ss [HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE]); 17544 17545(* ------------------------------------------------------------------------- *) 17546(* "Isometry" (up to constant bounds) of injective linear map etc. *) 17547(* ------------------------------------------------------------------------- *) 17548 17549val CAUCHY_ISOMETRIC = store_thm ("CAUCHY_ISOMETRIC", 17550 ``!f s e x. 17551 &0 < e /\ subspace s /\ 17552 linear f /\ (!x. x IN s ==> abs(f x) >= e * abs(x)) /\ 17553 (!n. x(n) IN s) /\ cauchy(f o x) 17554 ==> cauchy x``, 17555 REPEAT GEN_TAC THEN REWRITE_TAC[real_ge] THEN 17556 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 17557 SIMP_TAC std_ss [CAUCHY, dist, o_THM] THEN 17558 FIRST_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN 17559 DISCH_THEN(fn th => X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN MP_TAC th) THEN 17560 DISCH_THEN(MP_TAC o SPEC ``d * e:real``) THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL] THEN 17561 METIS_TAC[REAL_LE_RDIV_EQ, REAL_MUL_SYM, REAL_LET_TRANS, SUBSPACE_SUB, 17562 REAL_LT_LDIV_EQ]); 17563 17564val COMPLETE_ISOMETRIC_IMAGE = store_thm ("COMPLETE_ISOMETRIC_IMAGE", 17565 ``!f:real->real s e. 17566 &0 < e /\ subspace s /\ 17567 linear f /\ (!x. x IN s ==> abs(f x) >= e * abs(x)) /\ 17568 complete s 17569 ==> complete(IMAGE f s)``, 17570 REPEAT GEN_TAC THEN SIMP_TAC std_ss [complete, EXISTS_IN_IMAGE] THEN 17571 STRIP_TAC THEN X_GEN_TAC ``g:num->real`` THEN 17572 SIMP_TAC std_ss [IN_IMAGE, SKOLEM_THM, FORALL_AND_THM] THEN 17573 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN 17574 DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` MP_TAC) THEN 17575 ONCE_REWRITE_TAC [METIS [] ``(!n. g n = f (x n)) = (!n. g n = (\n. f (x n)) n)``] THEN 17576 GEN_REWR_TAC (LAND_CONV o LAND_CONV) [GSYM FUN_EQ_THM] THEN 17577 REWRITE_TAC[GSYM o_DEF] THEN 17578 DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN 17579 FIRST_X_ASSUM(MP_TAC o SPEC ``x:num->real``) THEN 17580 ASM_MESON_TAC[CAUCHY_ISOMETRIC, LINEAR_CONTINUOUS_AT, 17581 CONTINUOUS_AT_SEQUENTIALLY]); 17582 17583val INJECTIVE_IMP_ISOMETRIC = store_thm ("INJECTIVE_IMP_ISOMETRIC", 17584 ``!f:real->real s. 17585 closed s /\ subspace s /\ 17586 linear f /\ (!x. x IN s /\ (f x = 0) ==> (x = 0)) 17587 ==> ?e. &0 < e /\ !x. x IN s ==> abs(f x) >= e * abs(x)``, 17588 REPEAT STRIP_TAC THEN 17589 ASM_CASES_TAC ``s SUBSET {0 :real}`` THENL 17590 [EXISTS_TAC ``&1:real`` THEN REWRITE_TAC[REAL_LT_01, REAL_MUL_LID, real_ge] THEN 17591 ASM_MESON_TAC[SUBSET_DEF, IN_SING, ABS_0, LINEAR_0, REAL_LE_REFL], 17592 ALL_TAC] THEN 17593 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 17594 SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, IN_SING] THEN 17595 DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN 17596 MP_TAC(ISPECL 17597 [``{(f:real->real) x | x IN s /\ (abs(x) = abs(a:real))}``, 17598 ``0:real``] DISTANCE_ATTAINS_INF) THEN 17599 KNOW_TAC ``closed {(f:real->real) x | x IN s /\ (abs x = abs a)} /\ 17600 {f x | x IN s /\ (abs x = abs a)} <> {}`` THENL 17601 [SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, GSPECIFICATION] THEN 17602 CONJ_TAC THENL [ALL_TAC, METIS_TAC[]] THEN 17603 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 17604 SUBST1_TAC(SET_RULE 17605 ``{f x | x IN s /\ (abs(x) = abs(a:real))} = 17606 IMAGE (f:real->real) (s INTER {x | abs x = abs a})``) THEN 17607 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN 17608 ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON] THEN 17609 MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN 17610 SUBGOAL_THEN 17611 ``{x:real | abs x = abs(a:real)} = frontier(cball(0,abs a))`` 17612 SUBST1_TAC THENL 17613 [ASM_SIMP_TAC real_ss [FRONTIER_CBALL, GSYM ABS_NZ, dist, REAL_SUB_LZERO, 17614 ABS_NEG, sphere], 17615 ASM_SIMP_TAC std_ss [COMPACT_FRONTIER, COMPACT_CBALL]], 17616 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 17617 ONCE_REWRITE_TAC [METIS [] ``{(f:real->real) x | x IN s /\ (abs x = abs a)} = 17618 {f x | (\x. x IN s /\ (abs x = abs a)) x}``] THEN 17619 ONCE_REWRITE_TAC[SET_RULE ``{f x | P x} = IMAGE f {x | P x}``] THEN 17620 SIMP_TAC std_ss [FORALL_IN_IMAGE, EXISTS_IN_IMAGE] THEN 17621 DISCH_THEN(X_CHOOSE_THEN ``b:real`` MP_TAC) THEN 17622 SIMP_TAC std_ss [GSPECIFICATION, dist, REAL_SUB_LZERO, ABS_NEG] THEN 17623 STRIP_TAC THEN SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_APPROACHABLE] THEN 17624 EXISTS_TAC ``abs((f:real->real) b) / abs(b)`` THEN CONJ_TAC THENL 17625 [ASM_MESON_TAC[REAL_LT_DIV, GSYM ABS_NZ, ABS_ZERO], ALL_TAC] THEN 17626 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 17627 ASM_CASES_TAC ``x:real = 0`` THENL 17628 [FIRST_ASSUM(fn th => ASM_REWRITE_TAC[MATCH_MP LINEAR_0 th]) THEN 17629 REWRITE_TAC[ABS_0, REAL_MUL_RZERO, real_ge, REAL_LE_REFL], 17630 ALL_TAC] THEN 17631 FIRST_X_ASSUM(MP_TAC o SPEC ``(abs(a:real) / abs(x)) * x:real``) THEN 17632 KNOW_TAC ``abs a / abs x * x IN s /\ (abs (abs a / abs x * x) = abs a:real)`` THENL 17633 [KNOW_TAC ``(abs x <> 0:real) /\ (abs a <> 0:real)`` THENL 17634 [UNDISCH_TAC ``a <> 0:real`` THEN POP_ASSUM MP_TAC THEN 17635 REAL_ARITH_TAC, STRIP_TAC] THEN 17636 ASM_SIMP_TAC real_ss [ABS_MUL, ABS_DIV, ABS_ABS] THEN 17637 FULL_SIMP_TAC std_ss [subspace] THEN 17638 ASM_SIMP_TAC real_ss [REAL_DIV_RMUL, ABS_ZERO], 17639 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 17640 UNDISCH_TAC ``linear f`` THEN DISCH_TAC THEN 17641 FIRST_ASSUM(fn th => SIMP_TAC std_ss [MATCH_MP LINEAR_CMUL th]) THEN 17642 KNOW_TAC ``(abs x <> 0:real) /\ (abs a <> 0:real)`` THENL 17643 [UNDISCH_TAC ``a <> 0:real`` THEN UNDISCH_TAC ``x <> 0:real`` THEN 17644 REAL_ARITH_TAC, STRIP_TAC] THEN 17645 ASM_SIMP_TAC real_ss [ABS_MUL, ABS_DIV, ABS_ABS, real_ge] THEN 17646 ASM_SIMP_TAC real_ss [GSYM REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ, GSYM ABS_NZ] THEN 17647 SIMP_TAC std_ss [real_div, REAL_MUL_ASSOC] THEN REAL_ARITH_TAC); 17648 17649val CLOSED_INJECTIVE_IMAGE_SUBSPACE = store_thm ("CLOSED_INJECTIVE_IMAGE_SUBSPACE", 17650 ``!f s. subspace s /\ 17651 linear f /\ 17652 (!x. x IN s /\ (f(x) = 0) ==> (x = 0)) /\ 17653 closed s 17654 ==> closed(IMAGE f s)``, 17655 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED] THEN 17656 MATCH_MP_TAC COMPLETE_ISOMETRIC_IMAGE THEN 17657 ASM_SIMP_TAC std_ss [COMPLETE_EQ_CLOSED] THEN 17658 MATCH_MP_TAC INJECTIVE_IMP_ISOMETRIC THEN 17659 ASM_REWRITE_TAC[]); 17660 17661(* ------------------------------------------------------------------------- *) 17662(* Relating linear images to open/closed/interior/closure. *) 17663(* ------------------------------------------------------------------------- *) 17664 17665val OPEN_SURJECTIVE_LINEAR_IMAGE = store_thm ("OPEN_SURJECTIVE_LINEAR_IMAGE", 17666 ``!f:real->real. 17667 linear f /\ (!y. ?x. f x = y) 17668 ==> !s. open s ==> open(IMAGE f s)``, 17669 GEN_TAC THEN STRIP_TAC THEN 17670 SIMP_TAC std_ss [open_def, FORALL_IN_IMAGE] THEN 17671 FIRST_ASSUM(MP_TAC o GEN ``k:num`` o SPEC ``if (1 = k:num) then &1 else &0:real``) THEN 17672 SIMP_TAC std_ss [SKOLEM_THM] THEN 17673 DISCH_THEN(X_CHOOSE_THEN ``b:num->real`` STRIP_ASSUME_TAC) THEN 17674 SUBGOAL_THEN ``bounded(IMAGE (b:num->real) ((1:num)..(1:num)))`` MP_TAC THENL 17675 [SIMP_TAC std_ss [FINITE_IMP_BOUNDED, IMAGE_FINITE, FINITE_NUMSEG], ALL_TAC] THEN 17676 SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE, IN_NUMSEG] THEN 17677 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 17678 X_GEN_TAC ``s:real->bool`` THEN DISCH_TAC THEN 17679 X_GEN_TAC ``x:real`` THEN POP_ASSUM (MP_TAC o SPEC ``x:real``) THEN 17680 ASM_CASES_TAC ``(x:real) IN s`` THEN 17681 ASM_REWRITE_TAC[] THEN 17682 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 17683 EXISTS_TAC ``e / B / &(1):real`` THEN 17684 ASM_SIMP_TAC real_ss [REAL_LT_DIV, REAL_LT, LE_1] THEN 17685 X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN 17686 ABBREV_TAC ``u = y - (f:real->real) x`` THEN 17687 EXISTS_TAC ``x + sum(1 .. 1) (\i. (u:real) * b i):real`` THEN 17688 ASM_SIMP_TAC std_ss [LINEAR_ADD, LINEAR_SUM, FINITE_NUMSEG, o_DEF, 17689 LINEAR_CMUL] THEN 17690 CONJ_TAC THENL [EXPAND_TAC "u" THEN SIMP_TAC std_ss [NUMSEG_SING, SUM_SING] THEN 17691 REAL_ARITH_TAC, ALL_TAC] THEN 17692 FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC [dist] THEN 17693 REWRITE_TAC[REAL_ARITH ``abs(x + y - x) = abs y:real``] THEN 17694 MATCH_MP_TAC REAL_LET_TRANS THEN 17695 EXISTS_TAC ``(dist(y,(f:real->real) x) * &(1)) * B:real`` THEN 17696 ASM_SIMP_TAC real_ss [GSYM REAL_LT_RDIV_EQ, REAL_LT, LE_1] THEN 17697 MATCH_MP_TAC SUM_ABS_TRIANGLE THEN REWRITE_TAC[FINITE_NUMSEG] THEN 17698 EXPAND_TAC "u" THEN SIMP_TAC std_ss [NUMSEG_SING, SUM_SING] THEN 17699 REWRITE_TAC [ABS_MUL] THEN 17700 UNDISCH_TAC ``!x. 1 <= x /\ x <= 1 ==> abs ((b:num->real) x) <= B`` THEN 17701 DISCH_THEN (MP_TAC o SPEC ``1:num``) THEN ASM_SIMP_TAC real_ss [dist] THEN 17702 DISCH_TAC THEN MATCH_MP_TAC REAL_LE_LMUL_IMP THEN 17703 ASM_SIMP_TAC std_ss [ABS_POS]); 17704 17705val OPEN_BIJECTIVE_LINEAR_IMAGE_EQ = store_thm ("OPEN_BIJECTIVE_LINEAR_IMAGE_EQ", 17706 ``!f:real->real s. 17707 linear f /\ (!x y. (f x = f y) ==> (x = y)) /\ (!y. ?x. f x = y) 17708 ==> (open(IMAGE f s) <=> open s)``, 17709 REPEAT STRIP_TAC THEN EQ_TAC THENL 17710 [DISCH_TAC, ASM_MESON_TAC[OPEN_SURJECTIVE_LINEAR_IMAGE]] THEN 17711 SUBGOAL_THEN ``s = {x | (f:real->real) x IN IMAGE f s}`` 17712 SUBST1_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN 17713 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN 17714 ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_AT]); 17715 17716val CLOSED_INJECTIVE_LINEAR_IMAGE = store_thm ("CLOSED_INJECTIVE_LINEAR_IMAGE", 17717 ``!f:real->real. 17718 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17719 ==> !s. closed s ==> closed(IMAGE f s)``, 17720 REPEAT STRIP_TAC THEN 17721 MP_TAC(ISPEC ``f:real->real`` LINEAR_INJECTIVE_LEFT_INVERSE) THEN 17722 ASM_REWRITE_TAC[] THEN 17723 DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN 17724 MATCH_MP_TAC CLOSED_IN_CLOSED_TRANS THEN 17725 EXISTS_TAC ``IMAGE (f:real->real) univ(:real)`` THEN 17726 CONJ_TAC THENL 17727 [MP_TAC(ISPECL [``g:real->real``, ``IMAGE (f:real->real) univ(:real)``, 17728 ``IMAGE (g:real->real) (IMAGE (f:real->real) s)``] 17729 CONTINUOUS_CLOSED_IN_PREIMAGE) THEN 17730 ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON] THEN 17731 KNOW_TAC ``closed (IMAGE (g:real->real) (IMAGE (f:real->real) s))`` THENL 17732 [ASM_REWRITE_TAC[GSYM IMAGE_COMPOSE, IMAGE_ID], 17733 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 17734 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN 17735 FIRST_X_ASSUM(MP_TAC o SIMP_RULE std_ss [FUN_EQ_THM]) THEN 17736 SIMP_TAC std_ss [EXTENSION, o_THM, I_THM] THEN SET_TAC[], 17737 MATCH_MP_TAC CLOSED_INJECTIVE_IMAGE_SUBSPACE THEN 17738 ASM_REWRITE_TAC[IN_UNIV, SUBSPACE_UNIV, CLOSED_UNIV] THEN 17739 X_GEN_TAC ``x:real`` THEN 17740 DISCH_THEN(MP_TAC o AP_TERM ``g:real->real``) THEN 17741 RULE_ASSUM_TAC(SIMP_RULE std_ss [FUN_EQ_THM, I_THM, o_THM]) THEN 17742 ASM_MESON_TAC[LINEAR_0]]); 17743 17744val CLOSED_INJECTIVE_LINEAR_IMAGE_EQ = store_thm ("CLOSED_INJECTIVE_LINEAR_IMAGE_EQ", 17745 ``!f:real->real s. 17746 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17747 ==> (closed(IMAGE f s) <=> closed s)``, 17748 REPEAT STRIP_TAC THEN EQ_TAC THENL 17749 [DISCH_TAC, ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE]] THEN 17750 SUBGOAL_THEN ``s = {x | (f:real->real) x IN IMAGE f s}`` 17751 SUBST1_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN 17752 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN 17753 ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_AT]); 17754 17755val CLOSURE_LINEAR_IMAGE_SUBSET = store_thm ("CLOSURE_LINEAR_IMAGE_SUBSET", 17756 ``!f:real->real s. 17757 linear f ==> IMAGE f (closure s) SUBSET closure(IMAGE f s)``, 17758 REPEAT STRIP_TAC THEN 17759 MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN 17760 ASM_SIMP_TAC std_ss [CLOSED_CLOSURE, CLOSURE_SUBSET, LINEAR_CONTINUOUS_ON]); 17761 17762val CLOSURE_INJECTIVE_LINEAR_IMAGE = store_thm ("CLOSURE_INJECTIVE_LINEAR_IMAGE", 17763 ``!f:real->real s. 17764 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17765 ==> (closure(IMAGE f s) = IMAGE f (closure s))``, 17766 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 17767 ASM_SIMP_TAC std_ss [CLOSURE_LINEAR_IMAGE_SUBSET] THEN 17768 MATCH_MP_TAC CLOSURE_MINIMAL THEN 17769 SIMP_TAC std_ss [CLOSURE_SUBSET, IMAGE_SUBSET] THEN 17770 ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE, CLOSED_CLOSURE]); 17771 17772val CLOSURE_BOUNDED_LINEAR_IMAGE = store_thm ("CLOSURE_BOUNDED_LINEAR_IMAGE", 17773 ``!f:real->real s. 17774 linear f /\ bounded s 17775 ==> (closure(IMAGE f s) = IMAGE f (closure s))``, 17776 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN 17777 ASM_SIMP_TAC std_ss [CLOSURE_LINEAR_IMAGE_SUBSET] THEN 17778 MATCH_MP_TAC CLOSURE_MINIMAL THEN 17779 SIMP_TAC std_ss [CLOSURE_SUBSET, IMAGE_SUBSET] THEN 17780 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 17781 MATCH_MP_TAC COMPACT_LINEAR_IMAGE THEN 17782 ASM_REWRITE_TAC[COMPACT_CLOSURE]); 17783 17784val LINEAR_INTERIOR_IMAGE_SUBSET = store_thm ("LINEAR_INTERIOR_IMAGE_SUBSET", 17785 ``!f:real->real s. 17786 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17787 ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)``, 17788 MESON_TAC[INTERIOR_IMAGE_SUBSET, LINEAR_CONTINUOUS_AT]); 17789 17790val LINEAR_IMAGE_SUBSET_INTERIOR = store_thm ("LINEAR_IMAGE_SUBSET_INTERIOR", 17791 ``!f:real->real s. 17792 linear f /\ (!y. ?x. f x = y) 17793 ==> IMAGE f (interior s) SUBSET interior(IMAGE f s)``, 17794 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_MAXIMAL THEN 17795 ASM_SIMP_TAC std_ss [OPEN_SURJECTIVE_LINEAR_IMAGE, OPEN_INTERIOR, 17796 IMAGE_SUBSET, INTERIOR_SUBSET]); 17797 17798val INTERIOR_BIJECTIVE_LINEAR_IMAGE = store_thm ("INTERIOR_BIJECTIVE_LINEAR_IMAGE", 17799 ``!f:real->real s. 17800 linear f /\ (!x y. (f x = f y) ==> (x = y)) /\ (!y. ?x. f x = y) 17801 ==> (interior(IMAGE f s) = IMAGE f (interior s))``, 17802 ONCE_REWRITE_TAC [GSYM SURJECTIVE_IMAGE] THEN REPEAT STRIP_TAC THEN 17803 REWRITE_TAC [interior] THEN 17804 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN 17805 GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL 17806 [FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN 17807 STRIP_TAC THEN UNDISCH_TAC ``(t:real->bool) SUBSET IMAGE (f:real->real) s`` THEN 17808 DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SIMP_RULE std_ss [SUBSET_DEF, IN_IMAGE]) THEN 17809 DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN 17810 EXISTS_TAC ``x':real`` THEN ASM_REWRITE_TAC [] THEN EXISTS_TAC ``s':real->bool`` THEN 17811 REPEAT CONJ_TAC THENL 17812 [UNDISCH_TAC ``open t`` THEN MATCH_MP_TAC EQ_IMPLIES THEN 17813 EXPAND_TAC "t" THEN MATCH_MP_TAC OPEN_BIJECTIVE_LINEAR_IMAGE_EQ THEN 17814 METIS_TAC [SURJECTIVE_IMAGE], 17815 UNDISCH_TAC ``IMAGE (f:real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN 17816 DISCH_THEN (MP_TAC o SPEC ``(f:real->real) x'``) THEN SIMP_TAC std_ss [IN_IMAGE] THEN 17817 METIS_TAC [], 17818 REWRITE_TAC [SUBSET_DEF] THEN X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 17819 UNDISCH_TAC ``IMAGE (f:real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN 17820 DISCH_THEN (MP_TAC o SPEC ``(f:real->real) y``) THEN REWRITE_TAC [IN_IMAGE] THEN 17821 KNOW_TAC ``(?x. (f y = (f:real->real) x) /\ x IN s')`` THENL 17822 [METIS_TAC [], ALL_TAC] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 17823 DISCH_TAC THEN UNDISCH_TAC ``t SUBSET IMAGE (f:real->real) s`` THEN 17824 REWRITE_TAC [SUBSET_DEF] THEN DISCH_THEN (MP_TAC o SPEC ``(f:real->real) y``) THEN 17825 ASM_REWRITE_TAC [] THEN REWRITE_TAC [IN_IMAGE] THEN STRIP_TAC THEN 17826 METIS_TAC []], ALL_TAC] THEN 17827 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [GSPECIFICATION] THEN 17828 STRIP_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN 17829 STRIP_TAC THEN EXISTS_TAC ``IMAGE (f:real->real) t`` THEN 17830 REPEAT CONJ_TAC THENL 17831 [UNDISCH_TAC ``open t`` THEN MATCH_MP_TAC OPEN_SURJECTIVE_LINEAR_IMAGE THEN 17832 METIS_TAC [SURJECTIVE_IMAGE], 17833 REWRITE_TAC [IN_IMAGE] THEN EXISTS_TAC ``x':real`` THEN 17834 ASM_REWRITE_TAC [], 17835 MATCH_MP_TAC IMAGE_SUBSET THEN ASM_REWRITE_TAC []]); 17836 17837(* ------------------------------------------------------------------------- *) 17838(* Corollaries, reformulations and special cases for M = N. *) 17839(* ------------------------------------------------------------------------- *) 17840 17841val IN_INTERIOR_LINEAR_IMAGE = store_thm ("IN_INTERIOR_LINEAR_IMAGE", 17842 ``!f:real->real g s x. 17843 linear f /\ linear g /\ (f o g = I) /\ x IN interior s 17844 ==> (f x) IN interior (IMAGE f s)``, 17845 SIMP_TAC std_ss [FUN_EQ_THM, o_THM, I_THM] THEN REPEAT STRIP_TAC THEN 17846 MP_TAC(ISPECL [``f:real->real``, ``s:real->bool``] 17847 LINEAR_IMAGE_SUBSET_INTERIOR) THEN 17848 ASM_SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE] THEN 17849 ASM_MESON_TAC[]); 17850 17851val LINEAR_OPEN_MAPPING = store_thm ("LINEAR_OPEN_MAPPING", 17852 ``!f:real->real g. 17853 linear f /\ linear g /\ (f o g = I) 17854 ==> !s. open s ==> open(IMAGE f s)``, 17855 REPEAT GEN_TAC THEN SIMP_TAC std_ss [FUN_EQ_THM, o_THM, I_THM] THEN DISCH_TAC THEN 17856 MATCH_MP_TAC OPEN_SURJECTIVE_LINEAR_IMAGE THEN 17857 ASM_MESON_TAC[]); 17858 17859val INTERIOR_INJECTIVE_LINEAR_IMAGE = store_thm ("INTERIOR_INJECTIVE_LINEAR_IMAGE", 17860 ``!f:real->real s. 17861 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17862 ==> (interior(IMAGE f s) = IMAGE f (interior s))``, 17863 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_BIJECTIVE_LINEAR_IMAGE THEN 17864 METIS_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE]); 17865 17866val COMPLETE_INJECTIVE_LINEAR_IMAGE = store_thm ("COMPLETE_INJECTIVE_LINEAR_IMAGE", 17867 ``!f:real->real. 17868 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17869 ==> !s. complete s ==> complete(IMAGE f s)``, 17870 REWRITE_TAC[COMPLETE_EQ_CLOSED, CLOSED_INJECTIVE_LINEAR_IMAGE]); 17871 17872val COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ = store_thm ("COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ", 17873 ``!f:real->real s. 17874 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17875 ==> (complete(IMAGE f s) <=> complete s)``, 17876 REWRITE_TAC[COMPLETE_EQ_CLOSED, CLOSED_INJECTIVE_LINEAR_IMAGE_EQ]); 17877 17878val LIMPT_INJECTIVE_LINEAR_IMAGE_EQ = store_thm ("LIMPT_INJECTIVE_LINEAR_IMAGE_EQ", 17879 ``!f:real->real s. 17880 linear f /\ (!x y. (f x = f y) ==> (x = y)) 17881 ==> ((f x) limit_point_of (IMAGE f s) <=> x limit_point_of s)``, 17882 SIMP_TAC std_ss [LIMPT_APPROACHABLE, EXISTS_IN_IMAGE] THEN 17883 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN 17884 DISCH_TAC THENL 17885 [MP_TAC(ISPEC ``f:real->real`` LINEAR_INJECTIVE_BOUNDED_BELOW_POS), 17886 MP_TAC(ISPEC ``f:real->real`` LINEAR_BOUNDED_POS)] THEN 17887 ASM_REWRITE_TAC [] THEN 17888 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THENL 17889 [UNDISCH_TAC ``!(e :real). 17890 (0 :real) < e ==> 17891 ?(x' :real). 17892 x' IN (s :real -> bool) /\ 17893 (f :real -> real) x' <> f (x :real) /\ 17894 (dist (f x',f x) :real) < e`` THEN 17895 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e * B:real``), 17896 UNDISCH_TAC ``!(e :real). 17897 (0 :real) < e ==> 17898 ?(x' :real). 17899 x' IN (s :real -> bool) /\ x' <> (x :real) /\ 17900 (dist (x',x) :real) < e`` THEN DISCH_TAC THEN 17901 FIRST_X_ASSUM(MP_TAC o SPEC ``e / B:real``)] THEN 17902 ASM_SIMP_TAC real_ss [REAL_LT_DIV, REAL_LT_MUL, dist, GSYM LINEAR_SUB] THEN 17903 DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN 17904 POP_ASSUM MP_TAC THEN 17905 REPEAT(MATCH_MP_TAC MONO_AND THEN 17906 CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC]) THEN 17907 ASM_SIMP_TAC real_ss [GSYM REAL_LT_LDIV_EQ, REAL_LT_RDIV_EQ] THEN 17908 MATCH_MP_TAC(REAL_ARITH ``a <= b ==> b < x ==> a < x:real``) THEN 17909 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC real_ss [REAL_LE_RDIV_EQ]); 17910 17911(* ------------------------------------------------------------------------- *) 17912(* Even more special cases. *) 17913(* ------------------------------------------------------------------------- *) 17914 17915val INTERIOR_NEGATIONS = store_thm ("INTERIOR_NEGATIONS", 17916 ``!s. interior(IMAGE (\x. -x) s) = IMAGE (\x. -x) (interior s)``, 17917 GEN_TAC THEN MATCH_MP_TAC INTERIOR_INJECTIVE_LINEAR_IMAGE THEN 17918 SIMP_TAC std_ss [linear] THEN REPEAT CONJ_TAC THEN REAL_ARITH_TAC); 17919 17920val SYMMETRIC_INTERIOR = store_thm ("SYMMETRIC_INTERIOR", 17921 ``!s:real->bool. 17922 (!x. x IN s ==> -x IN s) 17923 ==> !x. x IN interior s ==> (-x) IN interior s``, 17924 REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN 17925 DISCH_THEN(MP_TAC o MATCH_MP(ISPEC ``(\x. -x):real->real`` FUN_IN_IMAGE)) THEN 17926 SIMP_TAC std_ss [GSYM INTERIOR_NEGATIONS] THEN 17927 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN AP_TERM_TAC THEN 17928 SIMP_TAC std_ss [EXTENSION, IN_IMAGE] THEN METIS_TAC[REAL_NEG_NEG]); 17929 17930val CLOSURE_NEGATIONS = store_thm ("CLOSURE_NEGATIONS", 17931 ``!s. closure(IMAGE (\x. -x) s) = IMAGE (\x. -x) (closure s)``, 17932 GEN_TAC THEN MATCH_MP_TAC CLOSURE_INJECTIVE_LINEAR_IMAGE THEN 17933 SIMP_TAC std_ss [linear] THEN REPEAT CONJ_TAC THEN REAL_ARITH_TAC); 17934 17935val SYMMETRIC_CLOSURE = store_thm ("SYMMETRIC_CLOSURE", 17936 ``!s:real->bool. 17937 (!x. x IN s ==> -x IN s) 17938 ==> !x. x IN closure s ==> (-x) IN closure s``, 17939 REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN 17940 DISCH_THEN(MP_TAC o MATCH_MP(ISPEC ``(\x. -x):real->real`` FUN_IN_IMAGE)) THEN 17941 SIMP_TAC std_ss [GSYM CLOSURE_NEGATIONS] THEN 17942 MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN AP_TERM_TAC THEN 17943 SIMP_TAC std_ss [EXTENSION, IN_IMAGE] THEN ASM_MESON_TAC[REAL_NEG_NEG]); 17944 17945(* ------------------------------------------------------------------------- *) 17946(* Some properties of a canonical subspace. *) 17947(* ------------------------------------------------------------------------- *) 17948 17949val SUBSPACE_SUBSTANDARD = store_thm ("SUBSPACE_SUBSTANDARD", 17950 ``subspace {x:real | (x = &0)}``, 17951 SIMP_TAC std_ss [subspace, GSPECIFICATION, REAL_MUL_RZERO, REAL_ADD_LID]); 17952 17953val CLOSED_SUBSTANDARD = store_thm ("CLOSED_SUBSTANDARD", 17954 ``closed {x:real | x = &0}``, 17955 REWRITE_TAC [GSPEC_EQ, CLOSED_SING]); 17956 17957val DIM_SUBSTANDARD = store_thm ("DIM_SUBSTANDARD", 17958 ``dim {x:real | x = &0} = 0``, 17959 REWRITE_TAC [dim, GSPEC_EQ] THEN MATCH_MP_TAC SELECT_UNIQUE THEN 17960 RW_TAC std_ss [] THEN EQ_TAC THENL 17961 [ONCE_REWRITE_TAC [MONO_NOT_EQ] THEN RW_TAC std_ss [] THEN 17962 ASM_CASES_TAC ``~(b SUBSET {0:real})`` THEN 17963 ASM_REWRITE_TAC [] THEN FULL_SIMP_TAC std_ss [SET_RULE 17964 ``b SUBSET {0:real} = (b = {}) \/ (b = {0})``] THENL 17965 [DISJ2_TAC THEN DISJ2_TAC THEN SIMP_TAC std_ss [HAS_SIZE] THEN 17966 DISJ2_TAC THEN REWRITE_TAC [CARD_EMPTY] THEN METIS_TAC [], 17967 REWRITE_TAC [INDEPENDENT_SING]], ALL_TAC] THEN 17968 DISCH_TAC THEN EXISTS_TAC ``{}:real->bool`` THEN 17969 ASM_SIMP_TAC std_ss [SPAN_EMPTY, SUBSET_REFL, EMPTY_SUBSET, INDEPENDENT_EMPTY] THEN 17970 ASM_REWRITE_TAC [HAS_SIZE_0]); 17971 17972(* ------------------------------------------------------------------------- *) 17973(* Affine transformations of intervals. *) 17974(* ------------------------------------------------------------------------- *) 17975 17976val AFFINITY_INVERSES = store_thm ("AFFINITY_INVERSES", 17977 ``!m c. ~(m = &0:real) 17978 ==> ((\x. m * x + c) o (\x. inv(m) * x + (-(inv(m) * c))) = (\x. x)) /\ 17979 ((\x. inv(m) * x + (-(inv(m) * c))) o (\x. m * x + c) = (\x. x))``, 17980 SIMP_TAC std_ss [FUN_EQ_THM, o_THM] THEN 17981 SIMP_TAC std_ss [REAL_ADD_LDISTRIB, REAL_MUL_RNEG] THEN 17982 SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_RINV] THEN 17983 REPEAT STRIP_TAC THEN REAL_ARITH_TAC); 17984 17985val REAL_AFFINITY_LE = store_thm ("REAL_AFFINITY_LE", 17986 ``!m c x y. &0:real < m ==> ((m * x + c <= y) <=> (x <= inv(m) * y + -(c / m)))``, 17987 REWRITE_TAC[REAL_ARITH ``(m * x + c <= y:real) <=> (x * m <= y - c)``] THEN 17988 SIMP_TAC std_ss [GSYM REAL_LE_RDIV_EQ] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 17989 REWRITE_TAC [real_div, GSYM real_sub, REAL_SUB_RDISTRIB]); 17990 17991val REAL_LE_AFFINITY = store_thm ("REAL_LE_AFFINITY", 17992 ``!m c x y. &0:real < m ==> ((y <= m * x + c) <=> (inv(m) * y + -(c / m) <= x))``, 17993 REWRITE_TAC[REAL_ARITH ``(y <= m * x + c:real) <=> (y - c <= x * m)``] THEN 17994 SIMP_TAC std_ss [GSYM REAL_LE_LDIV_EQ] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 17995 REWRITE_TAC [real_div, GSYM real_sub, REAL_SUB_RDISTRIB]); 17996 17997val REAL_AFFINITY_LT = store_thm ("REAL_AFFINITY_LT", 17998 ``!m c x y. &0:real < m ==> (m * x + c < y <=> x < inv(m) * y + -(c / m))``, 17999 SIMP_TAC std_ss [REAL_LE_AFFINITY, GSYM REAL_NOT_LE]); 18000 18001val REAL_LT_AFFINITY = store_thm ("REAL_LT_AFFINITY", 18002 ``!m c x y. &0:real < m ==> (y < m * x + c <=> inv(m) * y + -(c / m) < x)``, 18003 SIMP_TAC std_ss [REAL_AFFINITY_LE, GSYM REAL_NOT_LE]); 18004 18005val REAL_AFFINITY_EQ = store_thm ("REAL_AFFINITY_EQ", 18006 ``!m c x y. ~(m = &0:real) ==> ((m * x + c = y) <=> (x = inv(m) * y + -(c / m)))``, 18007 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 18008 REWRITE_TAC [real_div, GSYM real_sub, GSYM REAL_SUB_RDISTRIB] THEN 18009 REWRITE_TAC [GSYM REAL_EQ_SUB_LADD, GSYM real_div] THEN 18010 REPEAT STRIP_TAC THEN EQ_TAC THENL 18011 [GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN 18012 ASM_SIMP_TAC arith_ss [real_div, GSYM REAL_MUL_ASSOC, REAL_MUL_RINV, 18013 REAL_MUL_RID], DISCH_TAC THEN METIS_TAC [REAL_DIV_RMUL]]); 18014 18015val REAL_EQ_AFFINITY = store_thm ("REAL_EQ_AFFINITY", 18016 ``!m c x y. ~(m = &0:real) ==> ((y = m * x + c) <=> (inv(m) * y + -(c / m) = x))``, 18017 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 18018 REWRITE_TAC [real_div, GSYM real_sub, GSYM REAL_SUB_RDISTRIB] THEN 18019 REPEAT STRIP_TAC THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN 18020 REWRITE_TAC [GSYM REAL_EQ_SUB_LADD, GSYM real_div] THEN EQ_TAC THENL 18021 [GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN 18022 ASM_SIMP_TAC arith_ss [real_div, GSYM REAL_MUL_ASSOC, REAL_MUL_RINV, 18023 REAL_MUL_RID], DISCH_TAC THEN METIS_TAC [REAL_DIV_RMUL]]); 18024 18025val IMAGE_AFFINITY_INTERVAL = store_thm ("IMAGE_AFFINITY_INTERVAL", 18026 ``!a b:real m c. 18027 IMAGE (\x. m * x + c) (interval[a,b]) = 18028 if interval[a,b] = {} then {} 18029 else if &0 <= m then interval[m * a + c,m * b + c] 18030 else interval[m * b + c,m * a + c]``, 18031 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[IMAGE_EMPTY, IMAGE_INSERT] THEN 18032 ASM_CASES_TAC ``m = &0:real`` THEN ASM_REWRITE_TAC[REAL_LE_LT] THENL 18033 [ASM_REWRITE_TAC[REAL_MUL_LZERO, REAL_ADD_LID, COND_ID] THEN 18034 REWRITE_TAC[INTERVAL_SING] THEN ASM_SET_TAC[], 18035 ALL_TAC] THEN 18036 FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH 18037 ``~(x = &0:real) ==> &0 < x \/ &0 < -x``)) THEN 18038 ASM_SIMP_TAC std_ss [EXTENSION, IN_IMAGE, REAL_ARITH ``&0 < -x ==> ~(&0 < x:real)``] THENL 18039 [ALL_TAC, 18040 ONCE_REWRITE_TAC[REAL_ARITH ``(x = m * y + c:real) <=> (c = (-m) * y + x)``]] THEN 18041 (ASM_SIMP_TAC std_ss [REAL_EQ_AFFINITY, REAL_LT_IMP_NE, UNWIND_THM1] THEN 18042 SIMP_TAC std_ss [IN_INTERVAL] THEN 18043 POP_ASSUM(MP_TAC o ONCE_REWRITE_RULE [GSYM REAL_LT_INV_EQ]) THEN 18044 SIMP_TAC std_ss [REAL_AFFINITY_LE, REAL_LE_AFFINITY, real_div] THEN 18045 DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[REAL_INV_INV] THEN 18046 REWRITE_TAC[REAL_MUL_LNEG, REAL_NEGNEG] THEN 18047 KNOW_TAC ``-m <> 0:real`` THENL [ASM_REAL_ARITH_TAC, DISCH_TAC] THEN 18048 ASM_SIMP_TAC std_ss [METIS [REAL_MUL_RID, GSYM REAL_MUL_ASSOC, REAL_MUL_RINV, 18049 REAL_ARITH ``b * inv a * a = b * a * inv a:real``] 18050 ``m <> 0:real ==> (x * inv m * m = x)``] THEN 18051 GEN_TAC THEN ONCE_REWRITE_TAC [REAL_ADD_SYM] THEN REWRITE_TAC [GSYM real_sub] THEN 18052 REAL_ARITH_TAC)); 18053 18054(* ------------------------------------------------------------------------- *) 18055(* Infinite sums of vectors. Allow general starting point (and more). *) 18056(* ------------------------------------------------------------------------- *) 18057 18058val _ = set_fixity "sums" (Infix(NONASSOC, 450)); 18059 18060val _ = hide "sums"; 18061val _ = hide "summable"; 18062 18063val sums = new_definition ("sums", 18064 ``(f sums l) s = ((\n. sum (s INTER ((0:num)..n)) f) --> l) sequentially``); 18065 18066val infsum = new_definition ("infsum", 18067 ``infsum s f = @l. (f sums l) s``); 18068 18069val summable = new_definition ("summable", 18070 ``summable s f = ?l. (f sums l) s``); 18071 18072val SUMS_SUMMABLE = store_thm ("SUMS_SUMMABLE", 18073 ``!f l s. (f sums l) s ==> summable s f``, 18074 REWRITE_TAC[summable] THEN MESON_TAC[]); 18075 18076val SUMS_INFSUM = store_thm ("SUMS_INFSUM", 18077 ``!f s. (f sums (infsum s f)) s <=> summable s f``, 18078 REWRITE_TAC[infsum, summable] THEN METIS_TAC[]); 18079 18080val SUMS_LIM = store_thm ("SUMS_LIM", 18081 ``!f:num->real s. 18082 (f sums lim sequentially (\n. sum (s INTER ((0:num)..n)) f)) s 18083 <=> summable s f``, 18084 GEN_TAC THEN GEN_TAC THEN EQ_TAC THENL [MESON_TAC[summable], 18085 REWRITE_TAC[summable, sums] THEN STRIP_TAC THEN REWRITE_TAC[lim_def] THEN 18086 METIS_TAC[]]); 18087 18088val FINITE_INTER_NUMSEG = store_thm ("FINITE_INTER_NUMSEG", 18089 ``!s m n. FINITE(s INTER (m..n))``, 18090 MESON_TAC[SUBSET_FINITE_I, FINITE_NUMSEG, INTER_SUBSET]); 18091 18092val SERIES_FROM = store_thm ("SERIES_FROM", 18093 ``!f l k. (f sums l) (from k) = ((\n. sum(k..n) f) --> l) sequentially``, 18094 REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN 18095 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN 18096 AP_THM_TAC THEN AP_TERM_TAC THEN 18097 SIMP_TAC std_ss [EXTENSION, numseg, from, GSPECIFICATION, IN_INTER] THEN ARITH_TAC); 18098 18099val SERIES_UNIQUE = store_thm ("SERIES_UNIQUE", 18100 ``!f:num->real l l' s. (f sums l) s /\ (f sums l') s ==> (l = l')``, 18101 REWRITE_TAC[sums] THEN MESON_TAC[TRIVIAL_LIMIT_SEQUENTIALLY, LIM_UNIQUE]); 18102 18103val INFSUM_UNIQUE = store_thm ("INFSUM_UNIQUE", 18104 ``!f:num->real l s. (f sums l) s ==> (infsum s f = l)``, 18105 MESON_TAC[SERIES_UNIQUE, SUMS_INFSUM, summable]); 18106 18107val SERIES_TERMS_TOZERO = store_thm ("SERIES_TERMS_TOZERO", 18108 ``!f l n. (f sums l) (from n) ==> (f --> 0) sequentially``, 18109 REPEAT GEN_TAC THEN SIMP_TAC std_ss [sums, LIM_SEQUENTIALLY, FROM_INTER_NUMSEG] THEN 18110 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 18111 FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 18112 ASM_REWRITE_TAC[REAL_HALF] THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THEN 18113 EXISTS_TAC ``N + n + 1:num`` THEN X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN 18114 FIRST_X_ASSUM(fn th => 18115 MP_TAC(SPEC ``m - 1:num`` th) THEN MP_TAC(SPEC ``m:num`` th)) THEN 18116 SUBGOAL_THEN ``0 < m:num /\ n <= m`` (fn th => SIMP_TAC std_ss [SUM_CLAUSES_RIGHT, th]) 18117 THENL [CONJ_TAC THENL 18118 [MATCH_MP_TAC LESS_LESS_EQ_TRANS THEN EXISTS_TAC ``N + n + 1:num`` THEN 18119 ASM_REWRITE_TAC [] THEN ARITH_TAC, 18120 MATCH_MP_TAC LESS_EQ_TRANS THEN EXISTS_TAC ``N + n + 1:num`` THEN 18121 ASM_REWRITE_TAC [] THEN ARITH_TAC], ALL_TAC] THEN 18122 KNOW_TAC ``N <= m:num`` THENL [MATCH_MP_TAC LESS_EQ_TRANS THEN 18123 EXISTS_TAC ``N + n + 1:num`` THEN ASM_REWRITE_TAC [] THEN ARITH_TAC, 18124 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN 18125 KNOW_TAC ``N <= m:num - 1`` THENL [MATCH_MP_TAC LESS_EQ_TRANS THEN 18126 EXISTS_TAC ``N + n:num`` THEN CONJ_TAC THENL [ARITH_TAC, ALL_TAC] THEN 18127 ONCE_REWRITE_TAC [ARITH_PROVE ``(a <= b) = (a + 1 <= b + 1:num)``] THEN 18128 MATCH_MP_TAC LESS_EQ_TRANS THEN EXISTS_TAC ``m:num`` THEN 18129 ASM_REWRITE_TAC [] THEN ARITH_TAC, 18130 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN 18131 REWRITE_TAC [DIST_0] THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN 18132 FULL_SIMP_TAC std_ss [dist] THEN ASM_REAL_ARITH_TAC); 18133 18134val SERIES_FINITE = store_thm ("SERIES_FINITE", 18135 ``!f s. FINITE s ==> (f sums (sum s f)) s``, 18136 REPEAT GEN_TAC THEN SIMP_TAC std_ss [num_FINITE, LEFT_IMP_EXISTS_THM] THEN 18137 X_GEN_TAC ``n:num`` THEN SIMP_TAC std_ss [sums, LIM_SEQUENTIALLY] THEN 18138 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN EXISTS_TAC ``n:num`` THEN 18139 X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN 18140 SUBGOAL_THEN ``s INTER ((0:num)..m) = s`` 18141 (fn th => ASM_REWRITE_TAC[th, DIST_REFL]) THEN 18142 SIMP_TAC std_ss [EXTENSION, IN_INTER, IN_NUMSEG, ZERO_LESS_EQ] THEN 18143 METIS_TAC[LESS_EQ_TRANS]); 18144 18145val SERIES_LINEAR = store_thm ("SERIES_LINEAR", 18146 ``!f h l s. (f sums l) s /\ linear h ==> ((\n. h(f n)) sums h l) s``, 18147 SIMP_TAC std_ss [sums, LIM_LINEAR, FINITE_INTER, FINITE_NUMSEG, 18148 GSYM(REWRITE_RULE[o_DEF] LINEAR_SUM)]); 18149 18150val SERIES_0 = store_thm ("SERIES_0", 18151 ``!s. ((\n. 0) sums (0)) s``, 18152 REWRITE_TAC[sums, SUM_0, LIM_CONST]); 18153 18154val SERIES_ADD = store_thm ("SERIES_ADD", 18155 ``!x x0 y y0 s. 18156 (x sums x0) s /\ (y sums y0) s ==> ((\n. x n + y n) sums (x0 + y0)) s``, 18157 SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_ADD, LIM_ADD]); 18158 18159val SERIES_SUB = store_thm ("SERIES_SUB", 18160 ``!x x0 y y0 s. 18161 (x sums x0) s /\ (y sums y0) s ==> ((\n. x n - y n) sums (x0 - y0)) s``, 18162 SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_SUB, LIM_SUB]); 18163 18164val SERIES_CMUL = store_thm ("SERIES_CMUL", 18165 ``!x x0 c s. (x sums x0) s ==> ((\n. c * x n) sums (c * x0)) s``, 18166 SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_LMUL, LIM_CMUL]); 18167 18168val SERIES_NEG = store_thm ("SERIES_NEG", 18169 ``!x x0 s. (x sums x0) s ==> ((\n. -(x n)) sums (-x0)) s``, 18170 SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_NEG, LIM_NEG]); 18171 18172val SUMS_IFF = store_thm ("SUMS_IFF", 18173 ``!f g k. (!x. x IN k ==> (f x = g x)) ==> ((f sums l) k <=> (g sums l) k)``, 18174 REPEAT STRIP_TAC THEN REWRITE_TAC[sums] THEN 18175 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN 18176 MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC std_ss [IN_INTER]); 18177 18178val SUMS_EQ = store_thm ("SUMS_EQ", 18179 ``!f g k. (!x. x IN k ==> (f x = g x)) /\ (f sums l) k ==> (g sums l) k``, 18180 MESON_TAC[SUMS_IFF]); 18181 18182val SUMS_0 = store_thm ("SUMS_0", 18183 ``!f:num->real s. (!n. n IN s ==> (f n = 0)) ==> (f sums 0) s``, 18184 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMS_EQ THEN 18185 EXISTS_TAC ``\n:num. 0:real`` THEN ASM_SIMP_TAC std_ss [SERIES_0]); 18186 18187val SERIES_FINITE_SUPPORT = store_thm ("SERIES_FINITE_SUPPORT", 18188 ``!f:num->real s k. 18189 FINITE (s INTER k) /\ (!x. x IN k /\ ~(x IN s) ==> (f x = 0)) 18190 ==> (f sums sum (s INTER k) f) k``, 18191 REWRITE_TAC[sums, LIM_SEQUENTIALLY] THEN REPEAT STRIP_TAC THEN 18192 FIRST_ASSUM(MP_TAC o ISPEC ``\x:num. x`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN 18193 REWRITE_TAC[] THEN DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN 18194 EXISTS_TAC ``N:num`` THEN POP_ASSUM MP_TAC THEN 18195 STRIP_TAC THEN X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 18196 SIMP_TAC std_ss [] THEN 18197 SUBGOAL_THEN ``sum (k INTER ((0:num)..n)) (f:num->real) = sum(s INTER k) f`` 18198 (fn th => ASM_SIMP_TAC std_ss [DIST_REFL, th]) THEN 18199 MATCH_MP_TAC SUM_SUPERSET THEN 18200 ASM_SIMP_TAC std_ss [SUBSET_DEF, IN_INTER, IN_NUMSEG, ZERO_LESS_EQ] THEN 18201 METIS_TAC[IN_INTER, LESS_EQ_TRANS]); 18202 18203val SERIES_COMPONENT = store_thm ("SERIES_COMPONENT", 18204 ``!f s l:real. (f sums l) s 18205 ==> ((\i. f(i)) sums l) s``, 18206 METIS_TAC []); 18207 18208val SERIES_DIFFS = store_thm ("SERIES_DIFFS", 18209 ``!f:num->real k. (f --> 0) sequentially 18210 ==> ((\n. f(n) - f(n + 1)) sums f(k)) (from k)``, 18211 REWRITE_TAC[sums, FROM_INTER_NUMSEG, SUM_DIFFS] THEN 18212 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN 18213 EXISTS_TAC ``\n. (f:num->real) k - f(n + 1)`` THEN CONJ_TAC THENL 18214 [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC ``k:num`` THEN 18215 SIMP_TAC std_ss [], 18216 GEN_REWR_TAC LAND_CONV [GSYM REAL_SUB_RZERO] THEN 18217 KNOW_TAC ``((\n. (\n. f k) n - (\n. f (n + 1)) n) 18218 --> ((f:num->real) k - 0)) sequentially`` THENL 18219 [ALL_TAC, SIMP_TAC std_ss []] THEN 18220 MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN 18221 MATCH_MP_TAC SEQ_OFFSET THEN ASM_REWRITE_TAC[]]); 18222 18223val SERIES_TRIVIAL = store_thm ("SERIES_TRIVIAL", 18224 ``!f. (f sums 0) {}``, 18225 SIMP_TAC std_ss [sums, INTER_EMPTY, SUM_CLAUSES, LIM_CONST]); 18226 18227val SERIES_RESTRICT = store_thm ("SERIES_RESTRICT", 18228 ``!f k l:real. 18229 ((\n. if n IN k then f(n) else 0) sums l) univ(:num) <=> 18230 (f sums l) k``, 18231 REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN 18232 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN 18233 REWRITE_TAC[FUN_EQ_THM, INTER_UNIV] THEN GEN_TAC THEN 18234 SIMP_TAC std_ss [] THEN 18235 MATCH_MP_TAC(METIS [] ``(sum s f = sum t f) /\ (sum t f = sum t g) 18236 ==> (sum s f = sum t g)``) THEN 18237 CONJ_TAC THENL 18238 [MATCH_MP_TAC SUM_SUPERSET THEN SET_TAC[], 18239 MATCH_MP_TAC SUM_EQ THEN SIMP_TAC std_ss [IN_INTER]]); 18240 18241val SERIES_SUM = store_thm ("SERIES_SUM", 18242 ``!f l k s. FINITE s /\ s SUBSET k /\ (!x. ~(x IN s) ==> (f x = 0)) /\ 18243 (sum s f = l) ==> (f sums l) k``, 18244 REPEAT STRIP_TAC THEN EXPAND_TAC "l" THEN 18245 SUBGOAL_THEN ``s INTER k = s:num->bool`` ASSUME_TAC THENL 18246 [ASM_SET_TAC [], ASM_MESON_TAC [SERIES_FINITE_SUPPORT]]); 18247 18248val SUMS_REINDEX = store_thm ("SUMS_REINDEX", 18249 ``!k a l:real n. 18250 ((\x. a(x + k)) sums l) (from n) <=> (a sums l) (from(n + k))``, 18251 REPEAT GEN_TAC THEN REWRITE_TAC[sums, FROM_INTER_NUMSEG] THEN 18252 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUM_OFFSET] THEN 18253 REWRITE_TAC[LIM_SEQUENTIALLY] THEN 18254 ASM_MESON_TAC[ARITH_PROVE ``N + k:num <= n ==> (n = (n - k) + k) /\ N <= n - k``, 18255 ARITH_PROVE ``N + k:num <= n ==> N <= n + k``]); 18256 18257val SUMS_REINDEX_GEN = store_thm ("SUMS_REINDEX_GEN", 18258 ``!k a l:real s. 18259 ((\x. a(x + k)) sums l) s <=> (a sums l) (IMAGE (\i. i + k) s)``, 18260 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN 18261 MP_TAC(ISPECL 18262 [``k:num``, 18263 ``\i. if i IN IMAGE (\i. i + k) s then (a:num->real) i else 0``, 18264 ``l:real``, ``0:num``] SUMS_REINDEX) THEN 18265 REWRITE_TAC[FROM_0] THEN 18266 SIMP_TAC std_ss [EQ_ADD_RCANCEL, SET_RULE 18267 ``(!x y:num. (x + k = y + k) <=> (x = y)) 18268 ==> ((x + k) IN IMAGE (\i. i + k) s <=> x IN s)``] THEN 18269 DISCH_THEN SUBST1_TAC THEN 18270 GEN_REWR_TAC LAND_CONV [GSYM SERIES_RESTRICT] THEN 18271 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN 18272 REWRITE_TAC[FUN_EQ_THM, IN_FROM, ADD_CLAUSES] THEN 18273 SUBGOAL_THEN ``!x:num. x IN IMAGE (\i. i + k) s ==> k <= x`` MP_TAC THENL 18274 [SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN ARITH_TAC, SET_TAC[]]); 18275 18276(* ------------------------------------------------------------------------- *) 18277(* Similar combining theorems just for summability. *) 18278(* ------------------------------------------------------------------------- *) 18279 18280val SUMMABLE_LINEAR = store_thm ("SUMMABLE_LINEAR", 18281 ``!f h s. summable s f /\ linear h ==> summable s (\n. h(f n))``, 18282 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_LINEAR]); 18283 18284val SUMMABLE_0 = store_thm ("SUMMABLE_0", 18285 ``!s. summable s (\n. 0)``, 18286 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_0]); 18287 18288val SUMMABLE_ADD = store_thm ("SUMMABLE_ADD", 18289 ``!x y s. summable s x /\ summable s y ==> summable s (\n. x n + y n)``, 18290 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_ADD]); 18291 18292val SUMMABLE_SUB = store_thm ("SUMMABLE_SUB", 18293 ``!x y s. summable s x /\ summable s y ==> summable s (\n. x n - y n)``, 18294 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_SUB]); 18295 18296val SUMMABLE_CMUL = store_thm ("SUMMABLE_CMUL", 18297 ``!s x c. summable s x ==> summable s (\n. c * x n)``, 18298 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_CMUL]); 18299 18300val SUMMABLE_NEG = store_thm ("SUMMABLE_NEG", 18301 ``!x s. summable s x ==> summable s (\n. -(x n))``, 18302 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_NEG]); 18303 18304val SUMMABLE_IFF = store_thm ("SUMMABLE_IFF", 18305 ``!f g k. (!x. x IN k ==> (f x = g x)) ==> (summable k f <=> summable k g)``, 18306 REWRITE_TAC[summable] THEN METIS_TAC[SUMS_IFF]); 18307 18308val SUMMABLE_EQ = store_thm ("SUMMABLE_EQ", 18309 ``!f g k. (!x. x IN k ==> (f x = g x)) /\ summable k f ==> summable k g``, 18310 REWRITE_TAC[summable] THEN METIS_TAC[SUMS_EQ]); 18311 18312val SUMMABLE_COMPONENT = store_thm ("SUMMABLE_COMPONENT", 18313 ``!f:num->real s. 18314 summable s f ==> summable s (\i. f(i))``, 18315 METIS_TAC []); 18316 18317val SERIES_SUBSET = store_thm ("SERIES_SUBSET", 18318 ``!x s t l. 18319 s SUBSET t /\ 18320 ((\i. if i IN s then x i else 0) sums l) t 18321 ==> (x sums l) s``, 18322 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 18323 REWRITE_TAC[sums] THEN MATCH_MP_TAC EQ_IMPLIES THEN 18324 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN 18325 ASM_SIMP_TAC std_ss [GSYM SUM_RESTRICT_SET, FINITE_INTER_NUMSEG] THEN 18326 AP_THM_TAC THEN AP_TERM_TAC THEN POP_ASSUM MP_TAC THEN SET_TAC[]); 18327 18328val SUMMABLE_SUBSET = store_thm ("SUMMABLE_SUBSET", 18329 ``!x s t. 18330 s SUBSET t /\ 18331 summable t (\i. if i IN s then x i else 0) 18332 ==> summable s x``, 18333 REWRITE_TAC[summable] THEN METIS_TAC[SERIES_SUBSET]); 18334 18335val SUMMABLE_TRIVIAL = store_thm ("SUMMABLE_TRIVIAL", 18336 ``!f:num->real. summable {} f``, 18337 GEN_TAC THEN REWRITE_TAC[summable] THEN EXISTS_TAC ``0:real`` THEN 18338 REWRITE_TAC[SERIES_TRIVIAL]); 18339 18340val SUMMABLE_RESTRICT = store_thm ("SUMMABLE_RESTRICT", 18341 ``!f:num->real k. 18342 summable univ(:num) (\n. if n IN k then f(n) else 0) <=> 18343 summable k f``, 18344 SIMP_TAC std_ss [summable, SERIES_RESTRICT]); 18345 18346val SUMS_FINITE_DIFF = store_thm ("SUMS_FINITE_DIFF", 18347 ``!f:num->real t s l. 18348 t SUBSET s /\ FINITE t /\ (f sums l) s 18349 ==> (f sums (l - sum t f)) (s DIFF t)``, 18350 REPEAT GEN_TAC THEN 18351 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 18352 FIRST_ASSUM(MP_TAC o ISPEC ``f:num->real`` o MATCH_MP SERIES_FINITE) THEN 18353 ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN 18354 REWRITE_TAC[AND_IMP_INTRO] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN 18355 DISCH_THEN(MP_TAC o MATCH_MP SERIES_SUB) THEN 18356 MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN 18357 REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``x:num`` THEN REWRITE_TAC[IN_DIFF] THEN 18358 UNDISCH_TAC ``t SUBSET s:num->bool`` THEN DISCH_TAC THEN 18359 FIRST_ASSUM(MP_TAC o SPEC ``x:num`` o REWRITE_RULE [SUBSET_DEF]) THEN 18360 MAP_EVERY ASM_CASES_TAC [``(x:num) IN s``, ``(x:num) IN t``] THEN 18361 ASM_SIMP_TAC arith_ss [] THEN REAL_ARITH_TAC); 18362 18363val SUMS_FINITE_UNION = store_thm ("SUMS_FINITE_UNION", 18364 ``!f:num->real s t l. 18365 FINITE t /\ (f sums l) s 18366 ==> (f sums (l + sum (t DIFF s) f)) (s UNION t)``, 18367 REPEAT GEN_TAC THEN 18368 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 18369 FIRST_ASSUM(MP_TAC o SPEC ``s:num->bool`` o MATCH_MP FINITE_DIFF) THEN 18370 DISCH_THEN(MP_TAC o ISPEC ``f:num->real`` o MATCH_MP SERIES_FINITE) THEN 18371 ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN 18372 REWRITE_TAC[AND_IMP_INTRO] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN 18373 DISCH_THEN(MP_TAC o MATCH_MP SERIES_ADD) THEN 18374 MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN 18375 REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``x:num`` THEN 18376 REWRITE_TAC[IN_DIFF, IN_UNION] THEN 18377 MAP_EVERY ASM_CASES_TAC [``(x:num) IN s``, ``(x:num) IN t``] THEN 18378 ASM_SIMP_TAC arith_ss [] THEN REAL_ARITH_TAC); 18379 18380val SUMS_OFFSET = store_thm ("SUMS_OFFSET", 18381 ``!f l:real m n. 18382 (f sums l) (from m) /\ 0 < n /\ m <= n 18383 ==> (f sums l - sum (m..n - 1) f) (from n)``, 18384 REPEAT STRIP_TAC THEN 18385 SUBGOAL_THEN ``from n = from m DIFF (m..(n-1:num))`` SUBST1_TAC THENL 18386 [SIMP_TAC std_ss [EXTENSION, IN_FROM, IN_DIFF, IN_NUMSEG] THEN 18387 GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN CONJ_TAC THENL 18388 [MATCH_MP_TAC LESS_EQ_TRANS THEN EXISTS_TAC ``n:num`` THEN ASM_REWRITE_TAC [], 18389 REWRITE_TAC [NOT_LESS_EQUAL] THEN DISJ2_TAC THEN 18390 MATCH_MP_TAC LESS_LESS_EQ_TRANS THEN EXISTS_TAC ``n:num`` THEN ASM_REWRITE_TAC [] THEN 18391 MATCH_MP_TAC SUB_LESS THEN CONJ_TAC THENL [ARITH_TAC , ALL_TAC] THEN 18392 REWRITE_TAC [ONE] THEN ASM_REWRITE_TAC [GSYM LESS_EQ]], ARITH_TAC], 18393 MATCH_MP_TAC SUMS_FINITE_DIFF THEN ASM_REWRITE_TAC[FINITE_NUMSEG] THEN 18394 SIMP_TAC std_ss [SUBSET_DEF, IN_FROM, IN_NUMSEG]]); 18395 18396val SUMS_OFFSET_REV = store_thm ("SUMS_OFFSET_REV", 18397 ``!f:num->real l m n. 18398 (f sums l) (from m) /\ 0 < m /\ n <= m 18399 ==> (f sums (l + sum(n..m-1) f)) (from n)``, 18400 REPEAT STRIP_TAC THEN 18401 MP_TAC(ISPECL [``f:num->real``, ``from m``, ``n..m-1``, ``l:real``] 18402 SUMS_FINITE_UNION) THEN 18403 ASM_REWRITE_TAC[FINITE_NUMSEG] THEN MATCH_MP_TAC EQ_IMPLIES THEN 18404 BINOP_TAC THENL [AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC, ALL_TAC] THEN 18405 REWRITE_TAC[EXTENSION, IN_DIFF, IN_UNION, IN_FROM, IN_NUMSEG] THEN 18406 ASM_SIMP_TAC arith_ss []); 18407 18408val SUMMABLE_REINDEX = store_thm ("SUMMABLE_REINDEX", 18409 ``!k a n. summable (from n) (\x. a (x + k)) <=> summable (from(n + k)) a``, 18410 REWRITE_TAC[summable, GSYM SUMS_REINDEX]); 18411 18412val SERIES_DROP_LE = store_thm ("SERIES_DROP_LE", 18413 ``!f g s a b. 18414 (f sums a) s /\ (g sums b) s /\ 18415 (!x. x IN s ==> (f x <= g x)) 18416 ==> a <= b``, 18417 REWRITE_TAC[sums] THEN REPEAT STRIP_TAC THEN 18418 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_DROP_LE) THEN 18419 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY, TRIVIAL_LIMIT_SEQUENTIALLY] THEN 18420 EXISTS_TAC ``\n. sum (s INTER ((0:num)..n)) (f:num->real)`` THEN 18421 EXISTS_TAC ``\n. sum (s INTER ((0:num)..n)) (g:num->real)`` THEN 18422 ASM_REWRITE_TAC[] THEN EXISTS_TAC ``0:num`` THEN REPEAT STRIP_TAC THEN 18423 SIMP_TAC std_ss [] THEN MATCH_MP_TAC SUM_LE THEN 18424 ASM_SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG, IN_INTER, IN_NUMSEG]); 18425 18426val SERIES_DROP_POS = store_thm ("SERIES_DROP_POS", 18427 ``!f s a. 18428 (f sums a) s /\ (!x. x IN s ==> &0 <= f x) 18429 ==> &0 <= a``, 18430 REPEAT STRIP_TAC THEN 18431 MP_TAC(ISPECL [``(\n. 0):num->real``, ``f:num->real``, ``s:num->bool``, 18432 ``0:real``, ``a:real``] SERIES_DROP_LE) THEN 18433 ASM_SIMP_TAC std_ss [SUMS_0]); 18434 18435val SERIES_BOUND = store_thm ("SERIES_BOUND", 18436 ``!f:num->real g s a b. 18437 (f sums a) s /\ (g sums b) s /\ 18438 (!i. i IN s ==> abs(f i) <= g i) 18439 ==> abs (a) <= b``, 18440 REWRITE_TAC[sums] THEN REPEAT STRIP_TAC THEN 18441 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_ABS_UBOUND) THEN 18442 EXISTS_TAC ``\n. sum (s INTER ((0:num)..n)) (f:num->real)`` THEN 18443 ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN 18444 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC ``0:num`` THEN 18445 X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN 18446 SIMP_TAC std_ss [] THEN MATCH_MP_TAC REAL_LE_TRANS THEN 18447 EXISTS_TAC ``sum (s INTER ((0:num)..m)) g`` THEN CONJ_TAC THEN 18448 ASM_SIMP_TAC std_ss [SUM_ABS_LE, IN_INTER, FINITE_NUMSEG, FINITE_INTER] THEN 18449 RULE_ASSUM_TAC(REWRITE_RULE[GSYM sums]) THEN 18450 UNDISCH_TAC ``(g sums b) s`` THEN 18451 GEN_REWR_TAC LAND_CONV [GSYM SERIES_RESTRICT] THEN 18452 REWRITE_TAC[GSYM FROM_0] THEN DISCH_THEN(MP_TAC o SPEC ``m + 1:num`` o MATCH_MP 18453 (ONCE_REWRITE_RULE[CONJ_EQ_IMP] SUMS_OFFSET)) THEN 18454 KNOW_TAC ``0 < m + 1 /\ 0 <= m + 1:num`` THENL 18455 [ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 18456 REWRITE_TAC[ARITH_PROVE ``0 < m + 1:num``, o_DEF, ADD_SUB] THEN 18457 SIMP_TAC std_ss [GSYM SUM_RESTRICT_SET] THEN 18458 SIMP_TAC std_ss [ETA_AX] THEN 18459 DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] SERIES_DROP_POS)) THEN 18460 REWRITE_TAC[ONCE_REWRITE_RULE[INTER_COMM] (GSYM INTER_DEF), 18461 REAL_SUB_LE] THEN 18462 DISCH_THEN MATCH_MP_TAC THEN REPEAT STRIP_TAC THEN SIMP_TAC std_ss [] THEN 18463 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [REAL_LE_REFL] THEN 18464 ASM_MESON_TAC[REAL_ARITH ``abs(x:real) <= y ==> &0 <= y``]); 18465 18466(* ------------------------------------------------------------------------- *) 18467(* Similar combining theorems for infsum. *) 18468(* ------------------------------------------------------------------------- *) 18469 18470val INFSUM_LINEAR = store_thm ("INFSUM_LINEAR", 18471 ``!f h s. summable s f /\ linear h 18472 ==> (infsum s (\n. h(f n)) = h(infsum s f))``, 18473 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN 18474 MATCH_MP_TAC SERIES_LINEAR THEN ASM_REWRITE_TAC[SUMS_INFSUM]); 18475 18476val INFSUM_0 = store_thm ("INFSUM_0", 18477 ``infsum s (\i. 0) = 0``, 18478 MATCH_MP_TAC INFSUM_UNIQUE THEN REWRITE_TAC[SERIES_0]); 18479 18480val INFSUM_ADD = store_thm ("INFSUM_ADD", 18481 ``!x y s. summable s x /\ summable s y 18482 ==> (infsum s (\i. x i + y i) = infsum s x + infsum s y)``, 18483 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN 18484 MATCH_MP_TAC SERIES_ADD THEN ASM_REWRITE_TAC[SUMS_INFSUM]); 18485 18486val INFSUM_SUB = store_thm ("INFSUM_SUB", 18487 ``!x y s. summable s x /\ summable s y 18488 ==> (infsum s (\i. x i - y i) = infsum s x - infsum s y)``, 18489 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN 18490 MATCH_MP_TAC SERIES_SUB THEN ASM_REWRITE_TAC[SUMS_INFSUM]); 18491 18492val INFSUM_CMUL = store_thm ("INFSUM_CMUL", 18493 ``!s x c. summable s x ==> (infsum s (\n. c * x n) = c * infsum s x)``, 18494 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN 18495 MATCH_MP_TAC SERIES_CMUL THEN ASM_REWRITE_TAC[SUMS_INFSUM]); 18496 18497val INFSUM_NEG = store_thm ("INFSUM_NEG", 18498 ``!s x. summable s x ==> (infsum s (\n. -(x n)) = -(infsum s x))``, 18499 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN 18500 MATCH_MP_TAC SERIES_NEG THEN ASM_REWRITE_TAC[SUMS_INFSUM]); 18501 18502val INFSUM_EQ = store_thm ("INFSUM_EQ", 18503 ``!f g k. summable k f /\ summable k g /\ (!x. x IN k ==> (f x = g x)) 18504 ==> (infsum k f = infsum k g)``, 18505 REPEAT STRIP_TAC THEN REWRITE_TAC[infsum] THEN 18506 AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[SUMS_EQ, SUMS_INFSUM]); 18507 18508val INFSUM_RESTRICT = store_thm ("INFSUM_RESTRICT", 18509 ``!k a:num->real. 18510 infsum univ(:num) (\n. if n IN k then a n else 0) = infsum k a``, 18511 REPEAT GEN_TAC THEN 18512 MP_TAC(ISPECL [``a:num->real``, ``k:num->bool``] SUMMABLE_RESTRICT) THEN 18513 ASM_CASES_TAC ``summable k (a:num->real)`` THEN ASM_REWRITE_TAC[] THEN 18514 STRIP_TAC THENL 18515 [MATCH_MP_TAC INFSUM_UNIQUE THEN 18516 ASM_REWRITE_TAC[SERIES_RESTRICT, SUMS_INFSUM], 18517 FULL_SIMP_TAC std_ss [summable, NOT_EXISTS_THM] THEN 18518 ASM_REWRITE_TAC[infsum]]); 18519 18520val PARTIAL_SUMS_COMPONENT_LE_INFSUM = store_thm ("PARTIAL_SUMS_COMPONENT_LE_INFSUM", 18521 ``!f:num->real s n. 18522 (!i. i IN s ==> &0 <= f i) /\ summable s f 18523 ==> (sum (s INTER ((0:num)..n)) f) <= (infsum s f)``, 18524 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUMS_INFSUM] THEN 18525 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 18526 REWRITE_TAC[sums, LIM_SEQUENTIALLY] THEN DISCH_TAC THEN 18527 REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN 18528 FIRST_X_ASSUM(MP_TAC o SPEC 18529 ``sum (s INTER ((0:num)..n)) (f:num->real) - (infsum s f)``) THEN 18530 ASM_REWRITE_TAC[REAL_SUB_LT] THEN 18531 DISCH_THEN(X_CHOOSE_THEN ``N:num`` (MP_TAC o SPEC ``N + n:num``)) THEN 18532 REWRITE_TAC[LE_ADD, REAL_NOT_LT, dist] THEN 18533 MATCH_MP_TAC REAL_LE_TRANS THEN 18534 EXISTS_TAC ``abs((sum (s INTER ((0:num)..N + n)) f - infsum s f:real))`` THEN 18535 ASM_SIMP_TAC std_ss [REAL_LE_REFL] THEN 18536 MATCH_MP_TAC(REAL_ARITH ``s < a /\ a <= b ==> a - s <= abs(b - s:real)``) THEN 18537 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN 18538 KNOW_TAC ``sum (s INTER ((0:num)..n)) f <= 18539 sum (s INTER ((0:num)..n) UNION s INTER (n + (1:num)..n + N)) f`` THENL 18540 [ALL_TAC, SIMP_TAC std_ss [GSYM NUMSEG_ADD_SPLIT, ZERO_LESS_EQ, GSYM UNION_OVER_INTER]] THEN 18541 KNOW_TAC ``(sum (s INTER ((0:num)..n) UNION s INTER (n + (1:num)..n + N)) f = 18542 sum (s INTER ((0:num)..n)) f + sum (s INTER (n + (1:num)..n + N)) f)`` THENL 18543 [MATCH_MP_TAC SUM_UNION THEN 18544 SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG, DISJOINT_DEF, EXTENSION] THEN 18545 SIMP_TAC arith_ss [IN_INTER, NOT_IN_EMPTY, IN_NUMSEG] THEN CCONTR_TAC THEN 18546 FULL_SIMP_TAC arith_ss [], ALL_TAC] THEN 18547 DISCH_THEN SUBST1_TAC THEN 18548 REWRITE_TAC[REAL_LE_ADDR] THEN 18549 ASM_SIMP_TAC std_ss [] THEN MATCH_MP_TAC SUM_POS_LE THEN 18550 ASM_SIMP_TAC std_ss [FINITE_INTER, IN_INTER, FINITE_NUMSEG]); 18551 18552val PARTIAL_SUMS_DROP_LE_INFSUM = store_thm ("PARTIAL_SUMS_DROP_LE_INFSUM", 18553 ``!f s n. 18554 (!i. i IN s ==> &0 <= f i) /\ 18555 summable s f 18556 ==> sum (s INTER ((0:num)..n)) f <= (infsum s f)``, 18557 REPEAT STRIP_TAC THEN 18558 MATCH_MP_TAC PARTIAL_SUMS_COMPONENT_LE_INFSUM THEN 18559 ASM_REWRITE_TAC[LESS_EQ_REFL]); 18560 18561(* ------------------------------------------------------------------------- *) 18562(* Cauchy criterion for series. *) 18563(* ------------------------------------------------------------------------- *) 18564 18565val SEQUENCE_CAUCHY_WLOG = store_thm ("SEQUENCE_CAUCHY_WLOG", 18566 ``!P s. (!m n:num. P m /\ P n ==> dist(s m,s n) < e) <=> 18567 (!m n. P m /\ P n /\ m <= n ==> dist(s m,s n) < e)``, 18568 MESON_TAC[DIST_SYM, LE_CASES]); 18569 18570val SUM_DIFF_LEMMA = store_thm ("SUM_DIFF_LEMMA", 18571 ``!f:num->real k m n. 18572 m <= n 18573 ==> (sum (k INTER ((0:num) .. n)) f - sum (k INTER ((0:num)..m)) f = 18574 sum (k INTER ((m+1:num) .. n)) f)``, 18575 REPEAT STRIP_TAC THEN 18576 MP_TAC(ISPECL [``f:num->real``, ``k INTER ((0:num)..n)``, ``k INTER ((0:num)..m)``] 18577 SUM_DIFF) THEN 18578 KNOW_TAC ``FINITE (k INTER ((0:num) .. n)) /\ 18579 k INTER ((0:num) .. m) SUBSET k INTER ((0:num) .. n)`` THENL 18580 [SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN MATCH_MP_TAC 18581 (SET_RULE ``s SUBSET t ==> (u INTER s SUBSET u INTER t)``) THEN 18582 REWRITE_TAC[SUBSET_DEF, IN_NUMSEG] THEN POP_ASSUM MP_TAC THEN ARITH_TAC, 18583 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 18584 DISCH_THEN(SUBST1_TAC o SYM) THEN AP_THM_TAC THEN AP_TERM_TAC THEN 18585 REWRITE_TAC[SET_RULE 18586 ``(k INTER s) DIFF (k INTER t) = k INTER (s DIFF t)``] THEN 18587 AP_TERM_TAC THEN REWRITE_TAC[EXTENSION, IN_DIFF, IN_NUMSEG] THEN 18588 POP_ASSUM MP_TAC THEN ARITH_TAC]); 18589 18590val ABS_SUM_TRIVIAL_LEMMA = store_thm ("ABS_SUM_TRIVIAL_LEMMA", 18591 ``!e:real. &0 < e ==> (P ==> abs(sum(s INTER (m..n)) f) < e <=> 18592 P ==> n < m \/ abs(sum(s INTER (m..n)) f) < e)``, 18593 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``n:num < m`` THEN ASM_REWRITE_TAC[] THEN 18594 FIRST_X_ASSUM(SUBST1_TAC o REWRITE_RULE [GSYM NUMSEG_EMPTY]) THEN 18595 ASM_REWRITE_TAC[SUM_CLAUSES, ABS_0, INTER_EMPTY]); 18596 18597val SERIES_CAUCHY = store_thm ("SERIES_CAUCHY", 18598 ``!f s. (?l. (f sums l) s) = 18599 !e. &0 < e 18600 ==> ?N. !m n. m >= N 18601 ==> abs(sum(s INTER (m..n)) f) < e``, 18602 REPEAT GEN_TAC THEN REWRITE_TAC[sums, CONVERGENT_EQ_CAUCHY, cauchy] THEN 18603 SIMP_TAC std_ss [SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN 18604 SIMP_TAC std_ss [dist, SUM_DIFF_LEMMA, ABS_SUM_TRIVIAL_LEMMA] THEN 18605 REWRITE_TAC[GE, TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN 18606 REWRITE_TAC[NOT_LESS, ARITH_PROVE 18607 ``(N:num <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=> 18608 N + 1 <= m + 1 /\ m + 1 <= n``] THEN 18609 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN 18610 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN 18611 EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THENL 18612 [EXISTS_TAC ``N + 1:num``, EXISTS_TAC ``N:num``] THEN 18613 REPEAT STRIP_TAC THEN 18614 ASM_SIMP_TAC std_ss [ARITH_PROVE ``N + 1 <= m + 1 ==> N <= m + 1:num``] THEN 18615 FIRST_X_ASSUM(MP_TAC o SPECL [``m - 1:num``, ``n:num``]) THEN 18616 SUBGOAL_THEN ``m - 1 + 1 = m:num`` SUBST_ALL_TAC THENL 18617 [ALL_TAC, 18618 KNOW_TAC ``N <= m - 1 /\ m <= n:num`` THENL 18619 [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC []]] THEN 18620 ASM_ARITH_TAC); 18621 18622val SUMMABLE_CAUCHY = store_thm ("SUMMABLE_CAUCHY", 18623 ``!f s. summable s f <=> 18624 !e. &0 < e 18625 ==> ?N. !m n. m >= N ==> abs(sum(s INTER (m..n)) f) < e``, 18626 REWRITE_TAC[summable, GSYM SERIES_CAUCHY]); 18627 18628val SUMMABLE_IFF_EVENTUALLY = store_thm ("SUMMABLE_IFF_EVENTUALLY", 18629 ``!f g k. (?N. !n. N <= n /\ n IN k ==> (f n = g n)) 18630 ==> (summable k f <=> summable k g)``, 18631 REWRITE_TAC[summable, SERIES_CAUCHY] THEN REPEAT GEN_TAC THEN 18632 DISCH_THEN(X_CHOOSE_THEN ``N0:num`` STRIP_ASSUME_TAC) THEN 18633 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN 18634 BETA_TAC THEN AP_TERM_TAC THEN EQ_TAC THEN 18635 DISCH_THEN(X_CHOOSE_THEN ``N1:num`` 18636 (fn th => EXISTS_TAC ``N0 + N1:num`` THEN MP_TAC th)) THEN 18637 DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN 18638 POP_ASSUM (MP_TAC o Q.SPECL [`m:num`,`n:num`]) THEN 18639 DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN 18640 (KNOW_TAC ``m >= N1:num`` THENL [POP_ASSUM MP_TAC THEN ARITH_TAC, 18641 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC]) THEN 18642 MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN 18643 MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC std_ss [IN_INTER, IN_NUMSEG] THEN 18644 REPEAT STRIP_TAC THENL [ALL_TAC, CONV_TAC SYM_CONV] THEN 18645 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN 18646 ASM_ARITH_TAC); 18647 18648val SUMMABLE_EQ_EVENTUALLY = store_thm ("SUMMABLE_EQ_EVENTUALLY", 18649 ``!f g k. (?N. !n. N <= n /\ n IN k ==> (f n = g n)) /\ summable k f 18650 ==> summable k g``, 18651 MESON_TAC[SUMMABLE_IFF_EVENTUALLY]); 18652 18653val SUMMABLE_IFF_COFINITE = store_thm ("SUMMABLE_IFF_COFINITE", 18654 ``!f s t. FINITE((s DIFF t) UNION (t DIFF s)) 18655 ==> (summable s f <=> summable t f)``, 18656 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM SUMMABLE_RESTRICT] THEN 18657 MATCH_MP_TAC SUMMABLE_IFF_EVENTUALLY THEN 18658 FIRST_ASSUM(MP_TAC o ISPEC ``\x:num.x`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN 18659 DISCH_THEN(X_CHOOSE_THEN ``N:num`` MP_TAC) THEN REWRITE_TAC[IN_UNIV] THEN 18660 DISCH_TAC THEN EXISTS_TAC ``N + 1:num`` THEN 18661 REWRITE_TAC[ARITH_PROVE ``N + 1 <= n <=> ~(n <= N:num)``] THEN ASM_SET_TAC[]); 18662 18663val SUMMABLE_EQ_COFINITE = store_thm ("SUMMABLE_EQ_COFINITE", 18664 ``!f s t. FINITE((s DIFF t) UNION (t DIFF s)) /\ summable s f 18665 ==> summable t f``, 18666 MESON_TAC[SUMMABLE_IFF_COFINITE]); 18667 18668val SUMMABLE_FROM_ELSEWHERE = store_thm ("SUMMABLE_FROM_ELSEWHERE", 18669 ``!f m n. summable (from m) f ==> summable (from n) f``, 18670 REPEAT GEN_TAC THEN 18671 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] SUMMABLE_EQ_COFINITE) THEN 18672 MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``(0:num)..(m+n)`` THEN 18673 SIMP_TAC std_ss [FINITE_NUMSEG, SUBSET_DEF, IN_NUMSEG, IN_UNION, IN_DIFF, IN_FROM] THEN 18674 ARITH_TAC); 18675 18676(* ------------------------------------------------------------------------- *) 18677(* Uniform vesion of Cauchy criterion. *) 18678(* ------------------------------------------------------------------------- *) 18679 18680val SERIES_CAUCHY_UNIFORM = store_thm ("SERIES_CAUCHY_UNIFORM", 18681 ``!P f:'a->num->real k. 18682 (?l. !e. &0 < e 18683 ==> ?N. !n x. N <= n /\ P x 18684 ==> dist(sum(k INTER ((0:num)..n)) (f x), 18685 l x) < e) <=> 18686 (!e. &0 < e ==> ?N. !m n x. N <= m /\ P x 18687 ==> abs(sum(k INTER (m..n)) (f x)) < e)``, 18688 REPEAT GEN_TAC THEN 18689 SIMP_TAC std_ss [sums, UNIFORMLY_CONVERGENT_EQ_CAUCHY, cauchy] THEN 18690 ONCE_REWRITE_TAC [METIS [] ``(dist (sum (k INTER (0 .. n)) (f x), 18691 sum (k INTER (0 .. n')) (f x)) < e) = 18692 (\n n' x. dist (sum (k INTER (0 .. n)) (f x), 18693 sum (k INTER (0 .. n')) (f x)) < e) n n' x``] THEN 18694 ONCE_REWRITE_TAC[MESON[] 18695 ``(!m n:num y. N <= m /\ N <= n /\ P y ==> Q m n y) <=> 18696 (!y. P y ==> !m n. N <= m /\ N <= n ==> Q m n y)``] THEN 18697 SIMP_TAC std_ss [SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN 18698 SIMP_TAC std_ss [dist, SUM_DIFF_LEMMA, ABS_SUM_TRIVIAL_LEMMA] THEN 18699 REWRITE_TAC[GE, TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN 18700 REWRITE_TAC[NOT_LESS, ARITH_PROVE 18701 ``(N <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=> 18702 N + 1 <= m + 1 /\ m + 1 <= n:num``] THEN 18703 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN 18704 ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN 18705 EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THENL 18706 [EXISTS_TAC ``N + 1:num``, EXISTS_TAC ``N:num``] THEN 18707 REPEAT STRIP_TAC THEN 18708 ASM_SIMP_TAC std_ss [ARITH_PROVE ``N + 1 <= m + 1 ==> N <= m + 1:num``] THEN 18709 FIRST_X_ASSUM(MP_TAC o SPEC ``x:'a``) THEN ASM_REWRITE_TAC[] THEN 18710 DISCH_THEN(MP_TAC o SPECL [``m - 1:num``, ``n:num``]) THEN 18711 SUBGOAL_THEN ``m - 1 + 1 = m:num`` SUBST_ALL_TAC THENL 18712 [ASM_ARITH_TAC, ALL_TAC] THEN 18713 KNOW_TAC ``N <= m - 1 /\ m <= n:num`` THENL 18714 [ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC []]); 18715 18716(* ------------------------------------------------------------------------- *) 18717(* So trivially, terms of a convergent series go to zero. *) 18718(* ------------------------------------------------------------------------- *) 18719 18720val SERIES_GOESTOZERO = store_thm ("SERIES_GOESTOZERO", 18721 ``!s x. summable s x 18722 ==> !e. &0 < e 18723 ==> eventually (\n. n IN s ==> abs(x n) < e) sequentially``, 18724 REPEAT GEN_TAC THEN REWRITE_TAC[summable, SERIES_CAUCHY] THEN 18725 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN 18726 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN 18727 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 18728 X_GEN_TAC ``n:num`` THEN BETA_TAC THEN REPEAT STRIP_TAC THEN 18729 FIRST_X_ASSUM(MP_TAC o SPECL [``n:num``, ``n:num``]) THEN 18730 ASM_SIMP_TAC std_ss [NUMSEG_SING, GE, SET_RULE ``n IN s ==> (s INTER {n} = {n})``] THEN 18731 REWRITE_TAC[SUM_SING]); 18732 18733val SUMMABLE_IMP_TOZERO = store_thm ("SUMMABLE_IMP_TOZERO", 18734 ``!f:num->real k. 18735 summable k f 18736 ==> ((\n. if n IN k then f(n) else 0) --> 0) sequentially``, 18737 REPEAT GEN_TAC THEN GEN_REWR_TAC LAND_CONV [GSYM SUMMABLE_RESTRICT] THEN 18738 REWRITE_TAC[summable, LIM_SEQUENTIALLY, INTER_UNIV, sums] THEN 18739 DISCH_THEN(X_CHOOSE_TAC ``l:real``) THEN X_GEN_TAC ``e:real`` THEN 18740 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN 18741 ASM_SIMP_TAC std_ss [REAL_HALF, LEFT_IMP_EXISTS_THM] THEN 18742 X_GEN_TAC ``N:num`` THEN DISCH_TAC THEN EXISTS_TAC ``N + 1:num`` THEN 18743 X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN 18744 UNDISCH_TAC ``!n:num. N <= n ==> 18745 dist (sum ((0:num) .. n) (\n. if n IN k then f n else 0),l) < e / 2:real`` THEN 18746 DISCH_TAC THEN 18747 FIRST_X_ASSUM(fn th => 18748 MP_TAC(SPEC ``n - 1:num`` th) THEN MP_TAC(SPEC ``n:num`` th)) THEN 18749 ASM_SIMP_TAC std_ss [ARITH_PROVE ``N + 1 <= n ==> N <= n /\ N <= n - 1:num``] THEN 18750 ABBREV_TAC ``m = n - 1:num`` THEN 18751 SUBGOAL_THEN ``n = SUC m`` SUBST1_TAC THENL 18752 [ASM_ARITH_TAC, ALL_TAC] THEN 18753 SIMP_TAC std_ss [SUM_CLAUSES_NUMSEG, ZERO_LESS_EQ, dist] THEN 18754 SIMP_TAC std_ss [REAL_ARITH ``abs(x - 0) = abs x:real``] THEN 18755 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [ABS_0] THEN 18756 SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 18757 REAL_ARITH_TAC); 18758 18759val SUMMABLE_IMP_BOUNDED = store_thm ("SUMMABLE_IMP_BOUNDED", 18760 ``!f:num->real k. summable k f ==> bounded (IMAGE f k)``, 18761 REPEAT GEN_TAC THEN 18762 DISCH_THEN(MP_TAC o MATCH_MP SUMMABLE_IMP_TOZERO) THEN 18763 DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN 18764 SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE, IN_UNIV] THEN 18765 METIS_TAC[REAL_LT_IMP_LE, ABS_0]); 18766 18767val SUMMABLE_IMP_SUMS_BOUNDED = store_thm ("SUMMABLE_IMP_SUMS_BOUNDED", 18768 ``!f:num->real k. 18769 summable (from k) f ==> bounded { sum(k..n) f | n IN univ(:num) }``, 18770 SIMP_TAC std_ss [summable, sums, LEFT_IMP_EXISTS_THM] THEN REPEAT GEN_TAC THEN 18771 DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN 18772 SIMP_TAC std_ss [FROM_INTER_NUMSEG, GSYM IMAGE_DEF]); 18773 18774(* ------------------------------------------------------------------------- *) 18775(* Comparison test. *) 18776(* ------------------------------------------------------------------------- *) 18777 18778val SERIES_COMPARISON = store_thm ("SERIES_COMPARISON", 18779 ``!f g s. (?l. (g sums l) s) /\ 18780 (?N. !n. n >= N /\ n IN s ==> abs(f n) <= g n) 18781 ==> ?l:real. (f sums l) s``, 18782 REPEAT GEN_TAC THEN REWRITE_TAC[SERIES_CAUCHY] THEN 18783 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC ``N1:num``)) THEN 18784 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN 18785 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN 18786 DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN 18787 EXISTS_TAC ``N1 + N2:num`` THEN 18788 MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``] THEN DISCH_TAC THEN 18789 MATCH_MP_TAC REAL_LET_TRANS THEN 18790 EXISTS_TAC ``abs (sum (s INTER (m .. n)) g)`` THEN CONJ_TAC THENL 18791 [SIMP_TAC std_ss [FINITE_INTER_NUMSEG] THEN 18792 MATCH_MP_TAC(REAL_ARITH ``x <= a ==> x <= abs(a:real)``) THEN 18793 MATCH_MP_TAC SUM_ABS_LE THEN 18794 REWRITE_TAC[FINITE_INTER_NUMSEG, IN_INTER, IN_NUMSEG] THEN 18795 ASM_MESON_TAC[ARITH_PROVE ``m >= N1 + N2:num /\ m <= x ==> x >= N1``], 18796 ASM_MESON_TAC[ARITH_PROVE ``m >= N1 + N2:num ==> m >= N2``]]); 18797 18798val SUMMABLE_COMPARISON = store_thm ("SUMMABLE_COMPARISON", 18799 ``!f g s. summable s g /\ 18800 (?N. !n. n >= N /\ n IN s ==> abs(f n) <= g n) 18801 ==> summable s f``, 18802 REWRITE_TAC[summable, SERIES_COMPARISON]); 18803 18804val SERIES_ABSCONV_IMP_CONV = store_thm ("SERIES_ABSCONV_IMP_CONV", 18805 ``!x:num->real k. summable k (\n. (abs(x n))) ==> summable k x``, 18806 REWRITE_TAC[summable] THEN REPEAT STRIP_TAC THEN 18807 MATCH_MP_TAC SERIES_COMPARISON THEN 18808 EXISTS_TAC ``\n:num. abs(x n:real)`` THEN 18809 ASM_SIMP_TAC std_ss [o_DEF, REAL_LE_REFL] THEN ASM_MESON_TAC[]); 18810 18811val SUMMABLE_SUBSET_ABSCONV = store_thm ("SUMMABLE_SUBSET_ABSCONV", 18812 ``!x:num->real s t. 18813 summable s (\n. abs(x n)) /\ t SUBSET s 18814 ==> summable t (\n. abs(x n))``, 18815 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_SUBSET THEN 18816 EXISTS_TAC ``s:num->bool`` THEN ASM_REWRITE_TAC[] THEN 18817 REWRITE_TAC[summable] THEN MATCH_MP_TAC SERIES_COMPARISON THEN 18818 EXISTS_TAC ``\n:num. abs(x n:real)`` THEN 18819 ASM_SIMP_TAC std_ss [o_DEF, GSYM summable] THEN 18820 EXISTS_TAC ``0:num`` THEN REPEAT STRIP_TAC THEN COND_CASES_TAC THEN 18821 SIMP_TAC std_ss [REAL_LE_REFL, ABS_ABS, ABS_0, ABS_POS]); 18822 18823val SERIES_COMPARISON_BOUND = store_thm ("SERIES_COMPARISON_BOUND", 18824 ``!f:num->real g s a. 18825 (g sums a) s /\ (!i. i IN s ==> abs(f i) <= (g i)) 18826 ==> ?l. (f sums l) s /\ abs(l) <= a``, 18827 REPEAT STRIP_TAC THEN 18828 MP_TAC(ISPECL [``f:num->real``, ``g:num->real``, ``s:num->bool``] 18829 SUMMABLE_COMPARISON) THEN 18830 SIMP_TAC std_ss [o_DEF, GE, ETA_AX, summable] THEN 18831 KNOW_TAC ``(?l. ((g:num->real) sums l) s) /\ 18832 (?N:num. !n. N <= n /\ n IN s ==> abs (f n) <= g n)`` THENL 18833 [ASM_MESON_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 18834 STRIP_TAC THEN EXISTS_TAC ``l:real`` THEN ASM_REWRITE_TAC[] THEN 18835 RULE_ASSUM_TAC(REWRITE_RULE[FROM_0, INTER_UNIV, sums]) THEN 18836 MATCH_MP_TAC SERIES_BOUND THEN MAP_EVERY EXISTS_TAC 18837 [``f:num->real``, ``g:num->real``, ``s:num->bool``] THEN 18838 ASM_SIMP_TAC std_ss [sums, o_DEF, ETA_AX]); 18839 18840(* ------------------------------------------------------------------------- *) 18841(* Uniform version of comparison test. *) 18842(* ------------------------------------------------------------------------- *) 18843 18844val SERIES_COMPARISON_UNIFORM = store_thm ("SERIES_COMPARISON_UNIFORM", 18845 ``!f g P s. (?l. (g sums l) s) /\ 18846 (?N. !n x. N <= n /\ n IN s /\ P x ==> abs(f x n) <= g n) 18847 ==> ?l:'a->real. 18848 !e. &0 < e 18849 ==> ?N. !n x. N <= n /\ P x 18850 ==> dist(sum(s INTER ((0:num)..n)) (f x), 18851 l x) < e``, 18852 REPEAT GEN_TAC THEN SIMP_TAC std_ss [GE, SERIES_CAUCHY, SERIES_CAUCHY_UNIFORM] THEN 18853 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC ``N1:num``)) THEN 18854 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN 18855 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN 18856 DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN 18857 EXISTS_TAC ``N1 + N2:num`` THEN 18858 MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``, ``x:'a``] THEN DISCH_TAC THEN 18859 MATCH_MP_TAC REAL_LET_TRANS THEN 18860 EXISTS_TAC ``abs (sum (s INTER (m .. n)) g)`` THEN CONJ_TAC THENL 18861 [SIMP_TAC std_ss [FINITE_INTER_NUMSEG] THEN 18862 MATCH_MP_TAC(REAL_ARITH ``x <= a ==> x <= abs(a:real)``) THEN 18863 MATCH_MP_TAC SUM_ABS_LE THEN 18864 REWRITE_TAC[FINITE_INTER_NUMSEG, IN_INTER, IN_NUMSEG] THEN 18865 ASM_MESON_TAC[ARITH_PROVE ``N1 + N2:num <= m /\ m <= x ==> N1 <= x``], 18866 ASM_MESON_TAC[ARITH_PROVE ``N1 + N2:num <= m ==> N2 <= m``]]); 18867 18868(* ------------------------------------------------------------------------- *) 18869(* Ratio test. *) 18870(* ------------------------------------------------------------------------- *) 18871 18872val SERIES_RATIO = store_thm ("SERIES_RATIO", 18873 ``!c a s N. 18874 c < &1 /\ 18875 (!n. n >= N ==> abs(a(SUC n)) <= c * abs(a(n))) 18876 ==> ?l:real. (a sums l) s``, 18877 REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN 18878 MATCH_MP_TAC SERIES_COMPARISON THEN 18879 DISJ_CASES_TAC(REAL_ARITH ``c <= &0 \/ &0 < c:real``) THENL 18880 [EXISTS_TAC ``\n:num. &0:real`` THEN REWRITE_TAC[o_DEF] THEN 18881 CONJ_TAC THENL [MESON_TAC[SERIES_0], ALL_TAC] THEN 18882 EXISTS_TAC ``N + 1:num`` THEN REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN 18883 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``c * abs(a(n - 1:num):real)`` THEN 18884 CONJ_TAC THENL 18885 [ASM_MESON_TAC[ARITH_PROVE ``N + 1 <= n ==> (SUC(n - 1) = n) /\ N <= n - 1``], 18886 ALL_TAC] THEN 18887 MATCH_MP_TAC(REAL_ARITH ``&0 <= -c * x ==> c * x <= &0:real``) THEN 18888 MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[ABS_POS] THEN 18889 UNDISCH_TAC ``c <= &0:real`` THEN REAL_ARITH_TAC, 18890 ASSUME_TAC(MATCH_MP REAL_LT_IMP_LE (ASSUME ``&0 < c:real``))] THEN 18891 EXISTS_TAC ``\n:num. abs(a(N):real) * c pow (n - N)`` THEN 18892 REWRITE_TAC[] THEN CONJ_TAC THENL 18893 [ALL_TAC, 18894 EXISTS_TAC ``N:num`` THEN 18895 SIMP_TAC std_ss [GE, LESS_EQ_EXISTS, CONJ_EQ_IMP, ADD_SUB2, LEFT_IMP_EXISTS_THM] THEN 18896 SUBGOAL_THEN ``!d:num. abs(a(N + d):real) <= abs(a N) * c pow d`` 18897 (fn th => MESON_TAC[th]) THEN INDUCT_TAC THEN 18898 REWRITE_TAC[ADD_CLAUSES, pow, REAL_MUL_RID, REAL_LE_REFL] THEN 18899 MATCH_MP_TAC REAL_LE_TRANS THEN 18900 EXISTS_TAC ``c * abs((a:num->real) (N + d:num))`` THEN 18901 ASM_SIMP_TAC std_ss [LE_ADD] THEN 18902 ASM_MESON_TAC[REAL_LE_LMUL, REAL_MUL_ASSOC, REAL_MUL_COMM]] THEN 18903 GEN_REWR_TAC I [SERIES_CAUCHY] THEN X_GEN_TAC ``e:real`` THEN 18904 SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN 18905 DISCH_TAC THEN SIMP_TAC std_ss [SUM_LMUL, FINITE_INTER, FINITE_NUMSEG] THEN 18906 ASM_CASES_TAC ``(a:num->real) N = 0:real`` THENL 18907 [ASM_REWRITE_TAC[ABS_0, REAL_MUL_LZERO, ABS_N], ALL_TAC] THEN 18908 MP_TAC(SPECL [``c:real``, ``((&1 - c) * e) / abs((a:num->real) N)``] 18909 REAL_ARCH_POW_INV) THEN 18910 ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT_MUL, REAL_SUB_LT, GSYM ABS_NZ, GE] THEN 18911 DISCH_THEN(X_CHOOSE_TAC ``M:num``) THEN EXISTS_TAC ``N + M:num`` THEN 18912 MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``] THEN DISCH_TAC THEN 18913 MATCH_MP_TAC REAL_LET_TRANS THEN 18914 EXISTS_TAC ``abs(abs((a:num->real) N) * 18915 sum(m..n) (\i. c pow (i - N)))`` THEN 18916 CONJ_TAC THENL 18917 [REWRITE_TAC[ABS_MUL] THEN MATCH_MP_TAC REAL_LE_LMUL_IMP THEN 18918 REWRITE_TAC[ABS_POS] THEN 18919 MATCH_MP_TAC(REAL_ARITH ``&0 <= x /\ x <= y ==> abs x <= abs y:real``) THEN 18920 ASM_SIMP_TAC std_ss [SUM_POS_LE, FINITE_INTER_NUMSEG, POW_POS] THEN 18921 MATCH_MP_TAC SUM_SUBSET THEN ASM_SIMP_TAC std_ss [POW_POS] THEN 18922 REWRITE_TAC[FINITE_INTER_NUMSEG, FINITE_NUMSEG] THEN 18923 REWRITE_TAC[IN_INTER, IN_DIFF] THEN MESON_TAC[], 18924 ALL_TAC] THEN 18925 REWRITE_TAC[ABS_MUL, ABS_ABS] THEN 18926 DISJ_CASES_TAC(ARITH_PROVE ``n:num < m \/ m <= n``) THENL 18927 [ASM_SIMP_TAC std_ss [SUM_TRIV_NUMSEG, ABS_N, REAL_MUL_RZERO], ALL_TAC] THEN 18928 SUBGOAL_THEN ``(m = 0 + m) /\ (n = (n - m) + m:num)`` (CONJUNCTS_THEN SUBST1_TAC) THENL 18929 [UNDISCH_TAC ``m:num <= n`` THEN ARITH_TAC, ALL_TAC] THEN 18930 REWRITE_TAC[SUM_OFFSET] THEN UNDISCH_TAC ``N + M:num <= m`` THEN 18931 SIMP_TAC std_ss [LESS_EQ_EXISTS] THEN DISCH_THEN(X_CHOOSE_THEN ``d:num`` SUBST_ALL_TAC) THEN 18932 REWRITE_TAC[ARITH_PROVE ``(i + (N + M + d) - N:num) = (M + d) + i``] THEN 18933 ONCE_REWRITE_TAC[POW_ADD] THEN SIMP_TAC arith_ss [SUM_LMUL, SUM_GP] THEN 18934 ASM_SIMP_TAC std_ss [LT, REAL_LT_IMP_NE] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN 18935 FULL_SIMP_TAC std_ss [GSYM REAL_LT_RDIV_EQ, ABS_NZ, ABS_MUL] THEN 18936 REWRITE_TAC[GSYM POW_ABS] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN 18937 KNOW_TAC ``1 - c:real <> 0`` THENL 18938 [UNDISCH_TAC ``c < 1:real`` THEN REAL_ARITH_TAC, DISCH_TAC] THEN 18939 ASM_SIMP_TAC std_ss [GSYM REAL_LT_RDIV_EQ, ABS_DIV, REAL_POW_LT, ABS_NZ, REAL_ARITH 18940 ``&0 < c /\ c < &1 ==> &0 < abs c /\ &0 < abs(&1 - c:real)``, REAL_LT_LDIV_EQ] THEN 18941 ONCE_REWRITE_TAC [METIS [pow] ``x pow 0 = 1:real``] THEN 18942 MATCH_MP_TAC(REAL_ARITH 18943 ``&0 < x /\ x <= &1 /\ &1 <= e ==> abs(1 - x) < e:real``) THEN 18944 ASM_SIMP_TAC std_ss [REAL_POW_LT, REAL_POW_1_LE, REAL_LT_IMP_LE] THEN 18945 ASM_SIMP_TAC std_ss [REAL_ARITH ``c < &1 ==> (x * abs(&1 - c) = (&1 - c) * x:real)``] THEN 18946 KNOW_TAC ``(abs (c pow M) <> 0:real) /\ (abs (c pow d) <> 0:real)`` THENL 18947 [CONJ_TAC THEN ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN 18948 REWRITE_TAC [GSYM ABS_NZ] THEN ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN 18949 MATCH_MP_TAC REAL_LT_IMP_NE THEN METIS_TAC [REAL_POW_LT], STRIP_TAC] THEN 18950 FULL_SIMP_TAC real_ss [real_div, REAL_INV_MUL, ABS_NZ, REAL_POW_LT, REAL_POW_ADD, 18951 REAL_MUL_ASSOC, REAL_LT_IMP_NE, POW_ABS, ABS_MUL] THEN 18952 REWRITE_TAC[REAL_ARITH 18953 ``(a * b * c * d * e) = (e * ((a * b) * c)) * d:real``] THEN 18954 ASM_SIMP_TAC real_ss [GSYM real_div, REAL_LE_RDIV_EQ, REAL_POW_LT, REAL_MUL_LID, 18955 REAL_ARITH ``&0 < c ==> (abs c = c:real)``] THEN 18956 REWRITE_TAC [real_div] THEN 18957 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH 18958 ``xm < e ==> &0 <= (d - &1) * e ==> xm <= d * e:real``)) THEN 18959 MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THENL 18960 [REWRITE_TAC[REAL_SUB_LE, GSYM REAL_POW_INV] THEN 18961 MATCH_MP_TAC REAL_POW_LE_1 THEN 18962 MATCH_MP_TAC REAL_INV_1_LE THEN ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE], 18963 MATCH_MP_TAC REAL_LT_IMP_LE THEN 18964 ASM_SIMP_TAC std_ss [REAL_SUB_LT, REAL_LT_MUL, REAL_LT_DIV, ABS_NZ, GSYM real_div]]); 18965 18966(* ------------------------------------------------------------------------- *) 18967(* Ostensibly weaker versions of the boundedness of partial sums. *) 18968(* ------------------------------------------------------------------------- *) 18969 18970val BOUNDED_PARTIAL_SUMS = store_thm ("BOUNDED_PARTIAL_SUMS", 18971 ``!f:num->real k. 18972 bounded { sum(k..n) f | n IN univ(:num) } 18973 ==> bounded { sum(m..n) f | m IN univ(:num) /\ n IN univ(:num) }``, 18974 REPEAT STRIP_TAC THEN 18975 SUBGOAL_THEN ``bounded { sum((0:num)..n) f:real | n IN univ(:num) }`` MP_TAC THENL 18976 [FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [BOUNDED_POS]) THEN 18977 REWRITE_TAC[bounded_def] THEN 18978 SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, IN_UNIV] THEN 18979 DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN 18980 EXISTS_TAC ``sum { i:num | i < k} (\i. abs(f i:real)) + B`` THEN 18981 X_GEN_TAC ``i:num`` THEN ASM_CASES_TAC ``i:num < k`` THENL 18982 [MATCH_MP_TAC(REAL_ARITH 18983 ``!y. x <= y /\ y <= a /\ &0 < b ==> x <= a + b:real``) THEN 18984 EXISTS_TAC ``sum ((0:num)..i) (\i. abs(f i:real))`` THEN 18985 ASM_SIMP_TAC std_ss [SUM_ABS, FINITE_NUMSEG] THEN 18986 MATCH_MP_TAC SUM_SUBSET THEN 18987 REWRITE_TAC[FINITE_NUMSEG, FINITE_NUMSEG_LT, ABS_POS] THEN 18988 SIMP_TAC std_ss [IN_DIFF, IN_NUMSEG, GSPECIFICATION] THEN 18989 ASM_SIMP_TAC arith_ss [] THEN REAL_ARITH_TAC, 18990 ALL_TAC] THEN 18991 ASM_CASES_TAC ``k = 0:num`` THENL 18992 [FIRST_X_ASSUM SUBST_ALL_TAC THEN MATCH_MP_TAC(REAL_ARITH 18993 ``x <= B /\ &0 <= b ==> x <= b + B:real``) THEN 18994 ASM_SIMP_TAC std_ss [SUM_POS_LE, FINITE_NUMSEG_LT, ABS_POS], 18995 ALL_TAC] THEN 18996 MP_TAC(ISPECL [``f:num->real``, ``0:num``, ``k:num``, ``i:num``] 18997 SUM_COMBINE_L) THEN 18998 KNOW_TAC ``0 < k /\ 0 <= k /\ k <= i + 1:num`` THENL 18999 [ASM_SIMP_TAC arith_ss [], 19000 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 19001 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[NUMSEG_LT] THEN 19002 MATCH_MP_TAC(REAL_ARITH 19003 ``abs(x) <= a /\ abs(y) <= b ==> abs(x + y) <= a + b:real``) THEN 19004 ASM_SIMP_TAC std_ss [SUM_ABS, FINITE_NUMSEG], 19005 ALL_TAC] THEN 19006 DISCH_THEN(fn th => 19007 MP_TAC(MATCH_MP BOUNDED_DIFFS (W CONJ th)) THEN MP_TAC th) THEN 19008 REWRITE_TAC[AND_IMP_INTRO, GSYM BOUNDED_UNION] THEN 19009 MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b ==> c <=> b ==> a ==> c`] 19010 BOUNDED_SUBSET) THEN 19011 KNOW_TAC ``!x:real m n:num. 19012 (x = sum (m..n) f) 19013 ==> (?n. x = sum ((0:num)..n) f) \/ 19014 (?x' y. 19015 ((?n. x' = sum ((0:num)..n) f) /\ (?n. y = sum ((0:num)..n) f)) /\ 19016 (x = x' - y))`` THENL 19017 [ALL_TAC, SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNION, LEFT_IMP_EXISTS_THM, 19018 IN_UNIV, EXISTS_PROD] THEN METIS_TAC []] THEN 19019 MAP_EVERY X_GEN_TAC [``x:real``, ``m:num``, ``n:num``] THEN 19020 DISCH_THEN SUBST1_TAC THEN 19021 ASM_CASES_TAC ``m = 0:num`` THENL [ASM_MESON_TAC[], ALL_TAC] THEN 19022 ASM_CASES_TAC ``n:num < m`` THENL 19023 [DISJ2_TAC THEN REPEAT(EXISTS_TAC ``sum((0:num)..(0:num)) (f:num->real)``) THEN 19024 ASM_SIMP_TAC std_ss [SUM_TRIV_NUMSEG, REAL_SUB_REFL] THEN MESON_TAC[], 19025 ALL_TAC] THEN 19026 DISJ2_TAC THEN MAP_EVERY EXISTS_TAC 19027 [``sum((0:num)..n) (f:num->real)``, ``sum((0:num)..(m-1:num)) (f:num->real)``] THEN 19028 CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN 19029 MP_TAC(ISPECL [``f:num->real``, ``0:num``, ``m:num``, ``n:num``] 19030 SUM_COMBINE_L) THEN ASM_SIMP_TAC arith_ss [] THEN 19031 REAL_ARITH_TAC); 19032 19033(* ------------------------------------------------------------------------- *) 19034(* General Dirichlet convergence test (could make this uniform on a set). *) 19035(* ------------------------------------------------------------------------- *) 19036 19037val SUMMABLE_BILINEAR_PARTIAL_PRE = store_thm ("SUMMABLE_BILINEAR_PARTIAL_PRE", 19038 ``!f g h:real->real->real l k. 19039 bilinear h /\ 19040 ((\n. h (f(n + 1)) (g(n))) --> l) sequentially /\ 19041 summable (from k) (\n. h (f(n + 1) - f(n)) (g(n))) 19042 ==> summable (from k) (\n. h (f n) (g(n) - g(n - 1)))``, 19043 REPEAT GEN_TAC THEN 19044 SIMP_TAC std_ss [summable, sums, FROM_INTER_NUMSEG] THEN 19045 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 19046 FIRST_ASSUM(fn th => 19047 REWRITE_TAC[MATCH_MP BILINEAR_SUM_PARTIAL_PRE th]) THEN 19048 DISCH_THEN(X_CHOOSE_TAC ``l':real``) THEN 19049 EXISTS_TAC ``l - (h:real->real->real) ((f:num->real) k) (g(k - 1)) - l'`` THEN 19050 SIMP_TAC std_ss [LIM_CASES_SEQUENTIALLY] THEN 19051 KNOW_TAC ``(((\(n :num). 19052 (\n. (h :real -> real -> real) ((f :num -> real) (n + (1 :num))) 19053 ((g :num -> real) n) - h (f (k :num)) (g (k - (1 :num)))) n - 19054 (\n. sum (k .. n) (\(k :num). h (f (k + (1 :num)) - f k) (g k))) n) --> 19055 ((l :real) - h (f k) (g (k - (1 :num))) - (l' :real))) sequentially : 19056 bool)`` THENL 19057 [ALL_TAC, METIS_TAC []] THEN 19058 MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC std_ss [LIM_CONST] THEN 19059 KNOW_TAC ``(((\(n :num). 19060 (\n. (h :real -> real -> real) ((f :num -> real) (n + (1 :num))) 19061 ((g :num -> real) n)) n - (\n. h (f (k :num)) (g (k - (1 :num)))) n) --> 19062 ((l :real) - h (f k) (g (k - (1 :num))))) sequentially :bool)`` THENL 19063 [ALL_TAC, METIS_TAC []] THEN MATCH_MP_TAC LIM_SUB THEN 19064 ASM_SIMP_TAC std_ss [LIM_CONST]); 19065 19066val SERIES_DIRICHLET_BILINEAR = store_thm ("SERIES_DIRICHLET_BILINEAR", 19067 ``!f g h:real->real->real k m p l. 19068 bilinear h /\ 19069 bounded {sum (m..n) f | n IN univ(:num)} /\ 19070 summable (from p) (\n. abs(g(n + 1) - g(n))) /\ 19071 ((\n. h (g(n + 1)) (sum((1:num)..n) f)) --> l) sequentially 19072 ==> summable (from k) (\n. h (g n) (f n))``, 19073 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN 19074 EXISTS_TAC ``1:num`` THEN 19075 FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN 19076 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [BOUNDED_POS]) THEN 19077 SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, LEFT_IMP_EXISTS_THM, EXISTS_PROD] THEN 19078 X_GEN_TAC ``B:real`` THEN STRIP_TAC THEN 19079 FIRST_ASSUM(MP_TAC o MATCH_MP BILINEAR_BOUNDED_POS) THEN 19080 DISCH_THEN(X_CHOOSE_THEN ``C:real`` STRIP_ASSUME_TAC) THEN 19081 MATCH_MP_TAC SUMMABLE_EQ THEN 19082 EXISTS_TAC ``\n. (h:real->real->real) 19083 (g n) (sum ((1:num)..n) f - sum ((1:num)..n-1:num) f)`` THEN 19084 SIMP_TAC std_ss [IN_FROM, GSYM NUMSEG_RREC] THEN 19085 SIMP_TAC std_ss [SUM_CLAUSES, FINITE_NUMSEG, IN_NUMSEG, 19086 ARITH_PROVE ``1 <= n ==> ~(n <= n - 1:num)``] THEN 19087 CONJ_TAC THENL 19088 [REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [BILINEAR_RADD, BILINEAR_RSUB] THEN 19089 REAL_ARITH_TAC, 19090 ALL_TAC] THEN 19091 MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN EXISTS_TAC ``p:num`` THEN 19092 MP_TAC(ISPECL [``g:num->real``, ``\n. sum((1:num)..n) f:real``, 19093 ``h:real->real->real``, ``l:real``, ``p:num``] 19094 SUMMABLE_BILINEAR_PARTIAL_PRE) THEN 19095 SIMP_TAC std_ss [] THEN DISCH_THEN MATCH_MP_TAC THEN 19096 ASM_REWRITE_TAC[] THEN 19097 SUBGOAL_THEN 19098 ``summable (from p) ((\n. C * B * abs(g(n + 1) - g(n):real)))`` 19099 MP_TAC THENL [ASM_SIMP_TAC std_ss [o_DEF, SUMMABLE_CMUL], ALL_TAC] THEN 19100 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUMMABLE_COMPARISON) THEN 19101 EXISTS_TAC ``0:num`` THEN REWRITE_TAC[IN_FROM, GE, ZERO_LESS_EQ] THEN 19102 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC 19103 ``C * abs(g(n + 1:num) - g(n):real) * abs(sum ((1:num)..n) f:real)`` THEN 19104 ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN 19105 REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN 19106 ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN 19107 GEN_REWR_TAC RAND_CONV [REAL_MUL_SYM] THEN 19108 ASM_SIMP_TAC std_ss [REAL_LE_LMUL_IMP, ABS_POS]); 19109 19110val SERIES_DIRICHLET = store_thm ("SERIES_DIRICHLET", 19111 ``!f:num->real g N k m. 19112 bounded {sum (m..n) f | n IN univ(:num)} /\ 19113 (!n. N <= n ==> g(n + 1) <= g(n)) /\ 19114 (g --> 0) sequentially 19115 ==> summable (from k) (\n. g(n) * f(n))``, 19116 REPEAT STRIP_TAC THEN 19117 MP_TAC(ISPECL [``f:num->real``, ``g:num->real``, 19118 ``\x y:real. x * y``] SERIES_DIRICHLET_BILINEAR) THEN 19119 SIMP_TAC std_ss [o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN 19120 MAP_EVERY EXISTS_TAC [``m:num``, ``N:num``, ``0:real``] THEN CONJ_TAC THENL 19121 [SIMP_TAC std_ss [bilinear, linear] THEN 19122 REPEAT STRIP_TAC THEN REAL_ARITH_TAC, 19123 ALL_TAC] THEN 19124 ASM_REWRITE_TAC [] THEN 19125 FIRST_ASSUM(MP_TAC o SPEC ``1:num`` o MATCH_MP SEQ_OFFSET) THEN 19126 SIMP_TAC std_ss [o_THM] THEN DISCH_TAC THEN CONJ_TAC THENL 19127 [MATCH_MP_TAC SUMMABLE_EQ_EVENTUALLY THEN 19128 EXISTS_TAC ``(\n. (g:num->real)(n) - g(n + 1))`` THEN SIMP_TAC std_ss [] THEN 19129 CONJ_TAC THENL 19130 [EXISTS_TAC ``N:num`` THEN REPEAT STRIP_TAC THEN 19131 UNDISCH_TAC ``!n. N <= n ==> g (n + 1) <= (g:num->real) n`` THEN 19132 DISCH_THEN (MP_TAC o SPEC ``n:num``) THEN 19133 ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC, 19134 SIMP_TAC std_ss [summable, sums, FROM_INTER_NUMSEG, SUM_DIFFS] THEN 19135 SIMP_TAC std_ss [LIM_CASES_SEQUENTIALLY] THEN 19136 EXISTS_TAC ``(g(N:num)) - 0:real`` THEN 19137 ONCE_REWRITE_TAC [METIS [] ``((\n:num. g N - g (n + 1)) --> (g N - 0:real)) = 19138 ((\n. (\n. g N) n - (\n. g (n + 1)) n) --> (g N - 0))``] THEN 19139 MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[LIM_CONST]], 19140 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN 19141 ONCE_REWRITE_TAC [METIS [] 19142 ``((\n. sum (1 .. n) f * (g:num->real) (n + 1)) --> 0) = 19143 ((\n. (\n. sum (1 .. n) f) n * (\n. g (n + 1)) n) --> 0)``] THEN 19144 MATCH_MP_TAC LIM_NULL_CMUL_BOUNDED THEN ASM_SIMP_TAC std_ss [o_DEF] THEN 19145 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN 19146 FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN 19147 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [BOUNDED_POS]) THEN 19148 SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, EXISTS_PROD] THEN METIS_TAC[]]); 19149 19150(* ------------------------------------------------------------------------- *) 19151(* Rearranging absolutely convergent series. *) 19152(* ------------------------------------------------------------------------- *) 19153 19154val lemma = prove ( 19155 ``!f:'a->real s t. 19156 FINITE s /\ FINITE t 19157 ==> (sum s f - sum t f = sum (s DIFF t) f - sum (t DIFF s) f)``, 19158 REPEAT STRIP_TAC THEN 19159 ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s DIFF (s INTER t)``] THEN 19160 ASM_SIMP_TAC std_ss [SUM_DIFF, INTER_SUBSET] THEN 19161 GEN_REWR_TAC (RAND_CONV o RAND_CONV o ONCE_DEPTH_CONV) [INTER_COMM] THEN 19162 REAL_ARITH_TAC); 19163 19164val SERIES_INJECTIVE_IMAGE_STRONG = store_thm ("SERIES_INJECTIVE_IMAGE_STRONG", 19165 ``!x:num->real s f. 19166 summable (IMAGE f s) (\n. abs(x n)) /\ 19167 (!m n. m IN s /\ n IN s /\ (f m = f n) ==> (m = n)) 19168 ==> ((\n. sum (IMAGE f s INTER ((0:num)..n)) x - 19169 sum (s INTER ((0:num)..n)) (x o f)) --> 0) 19170 sequentially``, 19171 REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN 19172 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 19173 UNDISCH_TAC ``(summable (IMAGE (f :num -> num) (s :num -> bool)) 19174 (\(n :num). abs ((x :num -> real) n)) :bool)`` THEN DISCH_TAC THEN 19175 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUMMABLE_CAUCHY]) THEN 19176 SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN 19177 GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [o_DEF] THEN 19178 SIMP_TAC std_ss [SUM_POS_LE, ABS_POS, FINITE_INTER, FINITE_NUMSEG] THEN 19179 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN 19180 ASM_REWRITE_TAC[dist, GE, REAL_SUB_RZERO, REAL_HALF] THEN 19181 DISCH_THEN(X_CHOOSE_THEN ``N:num`` STRIP_ASSUME_TAC) THEN 19182 UNDISCH_TAC ``!(m :num) (n :num). 19183 m IN (s :num -> bool) /\ n IN s /\ ((f :num -> num) m = f n) ==> 19184 (m = n)`` THEN DISCH_TAC THEN 19185 FIRST_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_ON_LEFT_INVERSE]) THEN 19186 DISCH_THEN(X_CHOOSE_TAC ``g:num->num``) THEN 19187 MP_TAC(ISPECL [``g:num->num``, ``((0:num)..N)``] UPPER_BOUND_FINITE_SET) THEN 19188 REWRITE_TAC[FINITE_NUMSEG, IN_NUMSEG, ZERO_LESS_EQ] THEN 19189 DISCH_THEN(X_CHOOSE_TAC ``P:num``) THEN 19190 EXISTS_TAC ``MAX N P:num`` THEN X_GEN_TAC ``n:num`` THEN 19191 REWRITE_TAC [MAX_DEF] THEN 19192 SIMP_TAC std_ss [ARITH_PROVE ``(if a < b then b else a) <= c <=> a <= c /\ b <= c:num``] THEN 19193 DISCH_TAC THEN 19194 W(MP_TAC o PART_MATCH (rand o rand) SUM_IMAGE o rand o 19195 rand o lhand o snd) THEN 19196 KNOW_TAC ``(!(x :num) (y :num). 19197 x IN (s :num -> bool) INTER ((0 :num) .. (n :num)) /\ 19198 y IN s INTER ((0 :num) .. n) /\ ((f :num -> num) x = f y) ==> 19199 (x = y))`` THENL 19200 [ASM_MESON_TAC[FINITE_INTER, FINITE_NUMSEG, IN_INTER], 19201 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 19202 DISCH_THEN(SUBST1_TAC o SYM)] THEN 19203 W(MP_TAC o PART_MATCH (lhand o rand) lemma o rand o lhand o snd) THEN 19204 SIMP_TAC std_ss [FINITE_INTER, IMAGE_FINITE, FINITE_NUMSEG] THEN 19205 DISCH_THEN SUBST1_TAC THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN 19206 MATCH_MP_TAC(REAL_ARITH 19207 ``abs a < x /\ abs b < y ==> abs(a - b:real) < x + y:real``) THEN 19208 CONJ_TAC THEN 19209 W(MP_TAC o PART_MATCH (lhand o rand) SUM_ABS o lhand o snd) THEN 19210 SIMP_TAC std_ss [FINITE_DIFF, IMAGE_FINITE, FINITE_INTER, FINITE_NUMSEG] THEN 19211 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN 19212 MATCH_MP_TAC REAL_LET_TRANS THENL 19213 [EXISTS_TAC 19214 ``sum((IMAGE (f:num->num) s) INTER (N..n)) (\i. abs(x i :real))`` THEN 19215 CONJ_TAC THENL [ALL_TAC, 19216 MATCH_MP_TAC (REAL_ARITH ``abs x < y ==> x < y:real``) THEN 19217 ASM_SIMP_TAC real_ss []] THEN 19218 MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN 19219 SIMP_TAC std_ss [ABS_POS, FINITE_INTER, FINITE_NUMSEG] THEN 19220 MATCH_MP_TAC(SET_RULE 19221 ``(!x. x IN s /\ f(x) IN n /\ ~(x IN m) ==> f x IN t) 19222 ==> (IMAGE f s INTER n) DIFF (IMAGE f (s INTER m)) SUBSET 19223 IMAGE f s INTER t``) THEN 19224 ASM_SIMP_TAC std_ss [IN_NUMSEG, ZERO_LESS_EQ, NOT_LESS_EQUAL] THEN 19225 X_GEN_TAC ``i:num`` THEN STRIP_TAC THEN 19226 MATCH_MP_TAC LESS_IMP_LESS_OR_EQ THEN ONCE_REWRITE_TAC[GSYM NOT_LESS_EQUAL] THEN 19227 UNDISCH_TAC ``!(x :num). x <= (N :num) ==> (g :num -> num) x <= (P :num)`` THEN 19228 DISCH_TAC THEN POP_ASSUM(MATCH_MP_TAC o ONCE_REWRITE_RULE [MONO_NOT_EQ]) THEN 19229 ASM_SIMP_TAC arith_ss [], 19230 MP_TAC(ISPECL [``f:num->num``, ``((0:num)..n)``] UPPER_BOUND_FINITE_SET) THEN 19231 REWRITE_TAC[FINITE_NUMSEG, IN_NUMSEG, ZERO_LESS_EQ] THEN 19232 DISCH_THEN(X_CHOOSE_TAC ``p:num``) THEN 19233 EXISTS_TAC 19234 ``sum(IMAGE (f:num->num) s INTER (N..p)) (\i. abs(x i :real))`` THEN 19235 CONJ_TAC THENL [ALL_TAC, 19236 MATCH_MP_TAC (REAL_ARITH ``abs x < y ==> x < y:real``) THEN 19237 ASM_SIMP_TAC real_ss []] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN 19238 SIMP_TAC std_ss [ABS_POS, FINITE_INTER, FINITE_NUMSEG] THEN 19239 MATCH_MP_TAC(SET_RULE 19240 ``(!x. x IN s /\ x IN n /\ ~(f x IN m) ==> f x IN t) 19241 ==> (IMAGE f (s INTER n) DIFF (IMAGE f s) INTER m) SUBSET 19242 (IMAGE f s INTER t)``) THEN 19243 ASM_SIMP_TAC arith_ss [IN_NUMSEG, ZERO_LESS_EQ]]); 19244 19245val SERIES_INJECTIVE_IMAGE = store_thm ("SERIES_INJECTIVE_IMAGE", 19246 ``!x:num->real s f l. 19247 summable (IMAGE f s) (\n. abs(x n)) /\ 19248 (!m n. m IN s /\ n IN s /\ (f m = f n) ==> (m = n)) 19249 ==> (((x o f) sums l) s <=> (x sums l) (IMAGE f s))``, 19250 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN REWRITE_TAC[sums] THEN 19251 MATCH_MP_TAC LIM_TRANSFORM_EQ THEN SIMP_TAC std_ss [] THEN 19252 MATCH_MP_TAC SERIES_INJECTIVE_IMAGE_STRONG THEN 19253 ASM_REWRITE_TAC[]); 19254 19255val SERIES_REARRANGE_EQ = store_thm ("SERIES_REARRANGE_EQ", 19256 ``!x:num->real s p l. 19257 (summable s (\n. abs(x n))) /\ (p permutes s) 19258 ==> (((x o p) sums l) s <=> (x sums l) s)``, 19259 REPEAT STRIP_TAC THEN 19260 MP_TAC(ISPECL [``x:num->real``, ``s:num->bool``, ``p:num->num``, ``l:real``] 19261 SERIES_INJECTIVE_IMAGE) THEN 19262 ASM_SIMP_TAC std_ss [PERMUTES_IMAGE] THEN 19263 ASM_MESON_TAC[PERMUTES_INJECTIVE]); 19264 19265val SERIES_REARRANGE = store_thm ("SERIES_REARRANGE", 19266 ``!x:num->real s p l. 19267 summable s (\n. abs(x n)) /\ p permutes s /\ (x sums l) s 19268 ==> ((x o p) sums l) s``, 19269 METIS_TAC[SERIES_REARRANGE_EQ]); 19270 19271val SUMMABLE_REARRANGE = store_thm ("SUMMABLE_REARRANGE", 19272 ``!x s p. 19273 summable s (\n. abs(x n)) /\ p permutes s 19274 ==> summable s (x o p)``, 19275 METIS_TAC[SERIES_ABSCONV_IMP_CONV, summable, SERIES_REARRANGE]); 19276 19277(* ------------------------------------------------------------------------- *) 19278(* Banach fixed point theorem (not really topological...) *) 19279(* ------------------------------------------------------------------------- *) 19280 19281val BANACH_FIX = store_thm ("BANACH_FIX", 19282 ``!f s c. complete s /\ ~(s = {}) /\ 19283 &0 <= c /\ c < &1 /\ 19284 (IMAGE f s) SUBSET s /\ 19285 (!x y. x IN s /\ y IN s ==> dist(f(x),f(y)) <= c * dist(x,y)) 19286 ==> ?!x:real. x IN s /\ (f x = x)``, 19287 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [EXISTS_UNIQUE_THM] THEN CONJ_TAC THENL 19288 [ALL_TAC, 19289 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 19290 SUBGOAL_THEN ``dist((f:real->real) x,f y) <= c * dist(x,y)`` MP_TAC THENL 19291 [ASM_MESON_TAC[], ALL_TAC] THEN 19292 ASM_REWRITE_TAC[REAL_ARITH ``a <= c * a <=> &0 <= -a * (&1 - c:real)``] THEN 19293 ASM_SIMP_TAC std_ss [GSYM REAL_LE_LDIV_EQ, REAL_SUB_LT, real_div] THEN 19294 REWRITE_TAC[REAL_MUL_LZERO, REAL_ARITH ``&0:real <= -x <=> ~(&0 < x)``] THEN 19295 MESON_TAC[DIST_POS_LT]] THEN 19296 KNOW_TAC ``?z. (z 0 = @x:real. x IN s) /\ (!n. z(SUC n) = f(z n))`` THENL 19297 [RW_TAC std_ss [num_Axiom], STRIP_TAC] THEN 19298 SUBGOAL_THEN ``!n. (z:num->real) n IN s`` ASSUME_TAC THENL 19299 [INDUCT_TAC THEN ASM_SIMP_TAC std_ss [] THEN 19300 METIS_TAC[MEMBER_NOT_EMPTY, SUBSET_DEF, IN_IMAGE], 19301 ALL_TAC] THEN 19302 UNDISCH_THEN ``z (0:num) = @x:real. x IN s`` (K ALL_TAC) THEN 19303 SUBGOAL_THEN ``?x:real. x IN s /\ (z --> x) sequentially`` MP_TAC THENL 19304 [ALL_TAC, 19305 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 19306 POP_ASSUM MP_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 19307 ABBREV_TAC ``e = dist(f(a:real),a)`` THEN 19308 SUBGOAL_THEN ``~(&0 < e:real)`` (fn th => METIS_TAC[th, DIST_POS_LT]) THEN 19309 DISCH_TAC THEN UNDISCH_TAC ``(z --> a) sequentially`` THEN DISCH_TAC THEN 19310 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LIM_SEQUENTIALLY]) THEN 19311 DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN 19312 ASM_REWRITE_TAC[REAL_HALF] THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THEN 19313 SUBGOAL_THEN 19314 ``dist(f(z N),a:real) < e / &2 /\ dist(f(z(N:num)),f(a)) < e / &2`` 19315 (fn th => ASM_MESON_TAC[th, DIST_TRIANGLE_HALF_R, REAL_LT_REFL]) THEN 19316 CONJ_TAC THENL [ASM_MESON_TAC[ARITH_PROVE ``N <= SUC N``], ALL_TAC] THEN 19317 MATCH_MP_TAC REAL_LET_TRANS THEN 19318 EXISTS_TAC ``c * dist((z:num->real) N,a)`` THEN ASM_SIMP_TAC std_ss [] THEN 19319 MATCH_MP_TAC(REAL_ARITH ``x < y /\ c * x <= &1 * x ==> c * x < y:real``) THEN 19320 ASM_SIMP_TAC std_ss [LESS_EQ_REFL, REAL_LE_RMUL_IMP, DIST_POS_LE, REAL_LT_IMP_LE]] THEN 19321 UNDISCH_TAC ``complete s`` THEN DISCH_TAC THEN 19322 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE [complete]) THEN 19323 ASM_REWRITE_TAC[CAUCHY] THEN 19324 SUBGOAL_THEN ``!n. dist(z(n):real,z(SUC n)) <= c pow n * dist(z(0),z(1))`` 19325 ASSUME_TAC THENL 19326 [INDUCT_TAC THEN 19327 SIMP_TAC arith_ss [pow, REAL_MUL_LID, REAL_LE_REFL] THEN 19328 MATCH_MP_TAC REAL_LE_TRANS THEN 19329 EXISTS_TAC ``c * dist(z(n):real,z(SUC n))`` THEN 19330 CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC] THEN 19331 REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC std_ss [REAL_LE_LMUL_IMP], 19332 ALL_TAC] THEN 19333 SUBGOAL_THEN 19334 ``!m n:num. (&1 - c) * dist(z(m):real,z(m+n)) 19335 <= c pow m * dist(z(0),z(1:num)) * (&1 - c pow n)`` 19336 ASSUME_TAC THENL 19337 [GEN_TAC THEN INDUCT_TAC THENL 19338 [REWRITE_TAC[ADD_CLAUSES, DIST_REFL, REAL_MUL_RZERO, GSYM REAL_MUL_ASSOC] THEN 19339 MATCH_MP_TAC REAL_LE_MUL THEN 19340 ASM_SIMP_TAC std_ss [REAL_LE_MUL, POW_POS, DIST_POS_LE, REAL_SUB_LE, 19341 REAL_POW_1_LE, REAL_LT_IMP_LE], 19342 ALL_TAC] THEN 19343 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC 19344 ``(&1 - c) * (dist(z m:real,z(m + n)) + dist(z(m + n),z(m + SUC n)))`` THEN 19345 ASM_SIMP_TAC std_ss [REAL_LE_LMUL_IMP, REAL_SUB_LE, REAL_LT_IMP_LE, DIST_TRIANGLE] THEN 19346 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH 19347 ``c * x <= y ==> c * x' + y <= y' ==> c * (x + x') <= y':real``)) THEN 19348 REWRITE_TAC[REAL_ARITH 19349 ``q + a * b * (&1 - x) <= a * b * (&1 - y) <=> q <= a * b * (x - y:real)``] THEN 19350 REWRITE_TAC[ADD_CLAUSES, pow] THEN 19351 REWRITE_TAC[REAL_ARITH ``a * b * (d - c * d) = (&1 - c) * a * d * b:real``] THEN 19352 REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN MATCH_MP_TAC REAL_LE_LMUL_IMP THEN 19353 ASM_SIMP_TAC std_ss [REAL_SUB_LE, REAL_LT_IMP_LE] THEN 19354 REWRITE_TAC[GSYM REAL_POW_ADD, REAL_MUL_ASSOC] THEN ASM_MESON_TAC[], 19355 ALL_TAC] THEN 19356 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 19357 ASM_CASES_TAC ``(z:num->real) 0 = z 1`` THENL 19358 [FIRST_X_ASSUM SUBST_ALL_TAC THEN EXISTS_TAC ``0:num`` THEN 19359 REWRITE_TAC[GE, ZERO_LESS_EQ] THEN X_GEN_TAC ``n:num`` THEN 19360 FIRST_X_ASSUM(MP_TAC o SPECL [``0:num``, ``n:num``]) THEN 19361 REWRITE_TAC[ADD_CLAUSES, DIST_REFL, REAL_MUL_LZERO, REAL_MUL_RZERO] THEN 19362 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN 19363 ASM_CASES_TAC ``(z:num->real) 0 = z n`` THEN 19364 ASM_REWRITE_TAC[DIST_REFL, REAL_NOT_LE] THEN 19365 ASM_SIMP_TAC std_ss [REAL_LT_MUL, DIST_POS_LT, REAL_SUB_LT], 19366 ALL_TAC] THEN 19367 MP_TAC(SPECL [``c:real``, ``e * (&1 - c) / dist((z:num->real) 0,z 1)``] 19368 REAL_ARCH_POW_INV) THEN 19369 ASM_SIMP_TAC std_ss [REAL_LT_MUL, REAL_LT_DIV, REAL_SUB_LT, DIST_POS_LT] THEN 19370 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 19371 POP_ASSUM MP_TAC THEN REWRITE_TAC[real_div, GE, REAL_MUL_ASSOC] THEN 19372 ASM_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, GSYM real_div, DIST_POS_LT] THEN 19373 ASM_SIMP_TAC std_ss [GSYM REAL_LT_LDIV_EQ, REAL_SUB_LT] THEN DISCH_TAC THEN 19374 SIMP_TAC std_ss [LESS_EQ_EXISTS, LEFT_IMP_EXISTS_THM] THEN 19375 X_GEN_TAC ``d:num`` THEN ONCE_REWRITE_TAC[DIST_SYM] THEN 19376 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(REAL_ARITH 19377 ``d < e ==> x <= d ==> x < e:real``)) THEN 19378 ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_SUB_LT] THEN 19379 FIRST_X_ASSUM(MP_TAC o SPECL [``N:num``, ``d:num``]) THEN 19380 MATCH_MP_TAC(REAL_ARITH 19381 ``(c * d) * e <= (c * d) * &1 ==> x * y <= c * d * e ==> y * x <= c * d:real``) THEN 19382 MATCH_MP_TAC REAL_LE_LMUL_IMP THEN 19383 ASM_SIMP_TAC std_ss [REAL_LE_MUL, POW_POS, DIST_POS_LE, REAL_ARITH 19384 ``&0 <= x ==> &1 - x <= &1:real``]); 19385 19386(* ------------------------------------------------------------------------- *) 19387(* Dini's theorem. *) 19388(* ------------------------------------------------------------------------- *) 19389 19390val DINI = store_thm ("DINI", 19391 ``!f:num->real->real g s. 19392 compact s /\ (!n. (f n) continuous_on s) /\ g continuous_on s /\ 19393 (!x. x IN s ==> ((\n. (f n x)) --> g x) sequentially) /\ 19394 (!n x. x IN s ==> (f n x) <= (f (n + 1) x)) 19395 ==> !e. &0 < e 19396 ==> eventually (\n. !x. x IN s ==> abs(f n x - g x) < e) 19397 sequentially``, 19398 REPEAT STRIP_TAC THEN 19399 SUBGOAL_THEN 19400 ``!x:real m n:num. x IN s /\ m <= n ==> (f m x):real <= (f n x)`` 19401 ASSUME_TAC THENL 19402 [GEN_TAC THEN ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_REWRITE_TAC[] THEN 19403 ONCE_REWRITE_TAC [METIS [] ``!m n. (f:num->real->real) m x <= f n x = 19404 (\m n. f m x <= f n x) m n``] THEN 19405 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SIMP_TAC std_ss [ADD1] THEN 19406 REAL_ARITH_TAC, ALL_TAC] THEN 19407 SUBGOAL_THEN ``!n:num x:real. x IN s ==> (f n x):real <= (g x)`` 19408 ASSUME_TAC THENL 19409 [REPEAT STRIP_TAC THEN 19410 MATCH_MP_TAC(ISPEC ``sequentially`` LIM_DROP_LE) THEN 19411 EXISTS_TAC ``\m:num. (f:num->real->real) n x`` THEN 19412 EXISTS_TAC ``\m:num. (f:num->real->real) m x`` THEN 19413 ASM_SIMP_TAC std_ss [LIM_CONST, TRIVIAL_LIMIT_SEQUENTIALLY] THEN 19414 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN ASM_MESON_TAC[], 19415 ALL_TAC] THEN 19416 RULE_ASSUM_TAC(REWRITE_RULE[LIM_SEQUENTIALLY, dist]) THEN 19417 UNDISCH_TAC ``compact s`` THEN DISCH_TAC THEN 19418 FIRST_ASSUM(MP_TAC o REWRITE_RULE 19419 [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN 19420 DISCH_THEN(MP_TAC o SPEC 19421 ``IMAGE (\n. { x | x IN s /\ abs((f:num->real->real) n x - g x) < e}) 19422 univ(:num)``) THEN 19423 SIMP_TAC std_ss [FORALL_IN_IMAGE, IN_UNIV] THEN 19424 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN 19425 SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE, SUBSET_UNION, BIGUNION_IMAGE] THEN 19426 SIMP_TAC std_ss [IN_UNIV, GSPECIFICATION, EVENTUALLY_SEQUENTIALLY] THEN 19427 SIMP_TAC std_ss [SUBSET_DEF, IN_UNIV, GSPECIFICATION] THEN 19428 KNOW_TAC ``(!(n :num). 19429 open_in (subtopology euclidean (s :real -> bool)) 19430 {x | 19431 x IN s /\ 19432 abs ((f :num -> real -> real) n x - (g :real -> real) x) < 19433 (e :real)}) /\ 19434 (!(x :real). x IN s ==> ?(n :num). abs (f n x - g x) < e)`` THENL 19435 [CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[LESS_EQ_REFL]] THEN 19436 X_GEN_TAC ``n:num`` THEN REWRITE_TAC[GSYM IN_BALL_0] THEN 19437 ONCE_REWRITE_TAC [METIS [] ``f n x - g x = 19438 (\x. (f:num->real->real) n x - g x) x``] THEN 19439 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN 19440 METIS_TAC [OPEN_BALL, CONTINUOUS_ON_SUB, ETA_AX], 19441 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 19442 DISCH_THEN(X_CHOOSE_THEN ``k:num->bool`` (CONJUNCTS_THEN2 19443 (MP_TAC o SPEC ``\n:num. n`` o MATCH_MP UPPER_BOUND_FINITE_SET) 19444 ASSUME_TAC)) THEN 19445 DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN 19446 POP_ASSUM MP_TAC THEN 19447 SIMP_TAC std_ss [] THEN STRIP_TAC THEN X_GEN_TAC ``n:num`` THEN 19448 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 19449 UNDISCH_TAC ``!x. x IN s ==> ?n. n IN k /\ 19450 abs ((f:num->real->real) n x - g x) < e`` THEN 19451 DISCH_TAC THEN 19452 FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 19453 DISCH_THEN(X_CHOOSE_THEN ``m:num`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 19454 MATCH_MP_TAC(REAL_ARITH 19455 ``m <= n /\ n <= g ==> abs(m - g) < e ==> abs(n - g) < e:real``) THEN 19456 METIS_TAC[LESS_EQ_TRANS]]); 19457 19458(* ------------------------------------------------------------------------- *) 19459(* Closest point of a (closed) set to a point. *) 19460(* ------------------------------------------------------------------------- *) 19461 19462val closest_point = new_definition ("closest_point", 19463 ``closest_point s a = @x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)``); 19464 19465val CLOSEST_POINT_EXISTS = store_thm ("CLOSEST_POINT_EXISTS", 19466 ``!s a. closed s /\ ~(s = {}) 19467 ==> (closest_point s a) IN s /\ 19468 !y. y IN s ==> dist(a,closest_point s a) <= dist(a,y)``, 19469 REWRITE_TAC[closest_point] THEN CONV_TAC(ONCE_DEPTH_CONV SELECT_CONV) THEN 19470 REWRITE_TAC[DISTANCE_ATTAINS_INF]); 19471 19472val CLOSEST_POINT_IN_SET = store_thm ("CLOSEST_POINT_IN_SET", 19473 ``!s a. closed s /\ ~(s = {}) ==> (closest_point s a) IN s``, 19474 MESON_TAC[CLOSEST_POINT_EXISTS]); 19475 19476val CLOSEST_POINT_LE = store_thm ("CLOSEST_POINT_LE", 19477 ``!s a x. closed s /\ x IN s ==> dist(a,closest_point s a) <= dist(a,x)``, 19478 MESON_TAC[CLOSEST_POINT_EXISTS, MEMBER_NOT_EMPTY]); 19479 19480val CLOSEST_POINT_SELF = store_thm ("CLOSEST_POINT_SELF", 19481 ``!s x:real. x IN s ==> (closest_point s x = x)``, 19482 REPEAT STRIP_TAC THEN REWRITE_TAC[closest_point] THEN 19483 MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN GEN_TAC THEN EQ_TAC THENL 19484 [BETA_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN 19485 ASM_SIMP_TAC std_ss [DIST_LE_0, DIST_REFL], 19486 BETA_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[DIST_REFL, DIST_POS_LE]]); 19487 19488val CLOSEST_POINT_REFL = store_thm ("CLOSEST_POINT_REFL", 19489 ``!s x:real. closed s /\ ~(s = {}) ==> ((closest_point s x = x) <=> x IN s)``, 19490 MESON_TAC[CLOSEST_POINT_IN_SET, CLOSEST_POINT_SELF]); 19491 19492val DIST_CLOSEST_POINT_LIPSCHITZ = store_thm ("DIST_CLOSEST_POINT_LIPSCHITZ", 19493 ``!s x y:real. 19494 closed s /\ ~(s = {}) 19495 ==> abs(dist(x,closest_point s x) - dist(y,closest_point s y)) 19496 <= dist(x,y)``, 19497 REPEAT GEN_TAC THEN DISCH_TAC THEN 19498 FIRST_ASSUM(MP_TAC o MATCH_MP CLOSEST_POINT_EXISTS) THEN 19499 DISCH_THEN(fn th => 19500 CONJUNCTS_THEN2 ASSUME_TAC 19501 (MP_TAC o SPEC ``closest_point s (y:real)``) (SPEC ``x:real`` th) THEN 19502 CONJUNCTS_THEN2 ASSUME_TAC 19503 (MP_TAC o SPEC ``closest_point s (x:real)``) (SPEC ``y:real`` th)) THEN 19504 ASM_SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC); 19505 19506val CONTINUOUS_AT_DIST_CLOSEST_POINT = store_thm ("CONTINUOUS_AT_DIST_CLOSEST_POINT", 19507 ``!s x:real. 19508 closed s /\ ~(s = {}) 19509 ==> (\x. (dist(x,closest_point s x))) continuous (at x)``, 19510 REPEAT STRIP_TAC THEN SIMP_TAC std_ss [continuous_at] THEN REWRITE_TAC [dist] THEN 19511 METIS_TAC[REWRITE_RULE [dist] DIST_CLOSEST_POINT_LIPSCHITZ, REAL_LET_TRANS]); 19512 19513val CONTINUOUS_ON_DIST_CLOSEST_POINT = store_thm ("CONTINUOUS_ON_DIST_CLOSEST_POINT", 19514 ``!s t. closed s /\ ~(s = {}) 19515 ==> (\x. (dist(x,closest_point s x))) continuous_on t``, 19516 METIS_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON, 19517 CONTINUOUS_AT_DIST_CLOSEST_POINT]); 19518 19519val UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT = store_thm ("UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT", 19520 ``!s t:real->bool. 19521 closed s /\ ~(s = {}) 19522 ==> (\x. (dist(x,closest_point s x))) uniformly_continuous_on t``, 19523 REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN 19524 REWRITE_TAC [dist] THEN 19525 METIS_TAC[REWRITE_RULE [dist] DIST_CLOSEST_POINT_LIPSCHITZ, REAL_LET_TRANS]); 19526 19527val SEGMENT_TO_CLOSEST_POINT = store_thm ("SEGMENT_TO_CLOSEST_POINT", 19528 ``!s a:real. 19529 closed s /\ ~(s = {}) 19530 ==> (segment(a,closest_point s a) INTER s = {})``, 19531 REPEAT STRIP_TAC THEN 19532 REWRITE_TAC[SET_RULE ``(s INTER t = {}) <=> !x. x IN s ==> ~(x IN t)``] THEN 19533 GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP DIST_IN_OPEN_SEGMENT) THEN 19534 MATCH_MP_TAC(TAUT `(r ==> ~p) ==> p /\ q ==> ~r`) THEN 19535 METIS_TAC [CLOSEST_POINT_EXISTS, REAL_NOT_LT, DIST_SYM]); 19536 19537val SEGMENT_TO_POINT_EXISTS = store_thm ("SEGMENT_TO_POINT_EXISTS", 19538 ``!s a:real. 19539 closed s /\ ~(s = {}) ==> ?b. b IN s /\ (segment(a,b) INTER s = {})``, 19540 MESON_TAC[SEGMENT_TO_CLOSEST_POINT, CLOSEST_POINT_EXISTS]); 19541 19542val CLOSEST_POINT_IN_INTERIOR = store_thm 19543 ("CLOSEST_POINT_IN_INTERIOR", 19544 ``!s x:real. 19545 closed s /\ ~(s = {}) 19546 ==> ((closest_point s x) IN interior s <=> x IN interior s)``, 19547 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``(x:real) IN s`` THEN 19548 ASM_SIMP_TAC std_ss [CLOSEST_POINT_SELF] THEN 19549 MATCH_MP_TAC(TAUT `~q /\ ~p ==> (p <=> q)`) THEN 19550 CONJ_TAC THENL [METIS_TAC[INTERIOR_SUBSET, SUBSET_DEF], STRIP_TAC] THEN 19551 FIRST_ASSUM(MP_TAC o REWRITE_RULE [IN_INTERIOR_CBALL]) THEN 19552 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 19553 SUBGOAL_THEN ``closest_point s (x:real) IN s`` ASSUME_TAC THENL 19554 [METIS_TAC[INTERIOR_SUBSET, SUBSET_DEF], ALL_TAC] THEN 19555 SUBGOAL_THEN ``~(closest_point s (x:real) = x)`` ASSUME_TAC THENL 19556 [ASM_MESON_TAC[], ALL_TAC] THEN 19557 MP_TAC(ISPECL [``s:real->bool``, ``x:real``, 19558 ``closest_point s x - 19559 (min (&1) (e / abs(closest_point s x - x))) * 19560 (closest_point s x - x):real``] 19561 CLOSEST_POINT_LE) THEN 19562 ASM_REWRITE_TAC[dist, NOT_IMP, REAL_ARITH 19563 ``x - (y - e * (y - x)):real = (&1 - e) * (x - y:real)``] THEN 19564 CONJ_TAC THENL 19565 [ (* goal 1 (of 2) *) 19566 UNDISCH_TAC ``cball (closest_point s x,e) SUBSET s`` THEN DISCH_TAC THEN 19567 FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 19568 REWRITE_TAC[dist, IN_CBALL, REAL_ARITH ``abs(a:real - a - x) = abs x``] THEN 19569 SIMP_TAC real_ss [ABS_MUL, ABS_DIV, ABS_ABS] THEN 19570 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM REAL_SUB_0]) THEN 19571 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [ABS_NZ]) THEN 19572 19573 ASM_SIMP_TAC std_ss [GSYM REAL_LE_RDIV_EQ, min_def] THEN 19574 KNOW_TAC ``!a:real. &0 <= a ==> abs (if 1 <= a then 1 else a) <= a`` 19575 >- ( RW_TAC real_ss [] >> PROVE_TAC [abs, REAL_LE_REFL] ) THEN 19576 DISCH_THEN MATCH_MP_TAC THEN 19577 ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE, REAL_LE_DIV, ABS_POS], 19578 (* goal 2 (of 2) *) 19579 REWRITE_TAC[ABS_MUL, REAL_ARITH 19580 ``~(n <= a * n) <=> &0 < (&1 - a) * n:real``] THEN 19581 MATCH_MP_TAC REAL_LT_MUL THEN 19582 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``(a <> b) = (b - a <> 0:real)``]) THEN 19583 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [ABS_NZ]) THEN ASM_SIMP_TAC std_ss [] THEN 19584 KNOW_TAC ``!e:real. &0 < e /\ e <= &1 ==> &0 < &1 - abs(&1 - e)`` 19585 >- ( RW_TAC real_ss [] \\ 19586 `0 <= 1 - e'` by ASM_REAL_ARITH_TAC \\ 19587 ASM_SIMP_TAC real_ss [abs] ) THEN 19588 DISCH_THEN MATCH_MP_TAC THEN 19589 REWRITE_TAC[REAL_MIN_LE, REAL_LT_MIN, REAL_LT_01, REAL_LE_REFL] THEN 19590 METIS_TAC [REAL_LT_DIV, ABS_SUB] ]); 19591 19592val CLOSEST_POINT_IN_FRONTIER = store_thm ("CLOSEST_POINT_IN_FRONTIER", 19593 ``!s x:real. 19594 closed s /\ ~(s = {}) /\ ~(x IN interior s) 19595 ==> (closest_point s x) IN frontier s``, 19596 SIMP_TAC std_ss [frontier, IN_DIFF, CLOSEST_POINT_IN_INTERIOR] THEN 19597 SIMP_TAC std_ss [CLOSEST_POINT_IN_SET, CLOSURE_CLOSED]); 19598 19599(* ------------------------------------------------------------------------- *) 19600(* More general infimum of distance between two sets. *) 19601(* ------------------------------------------------------------------------- *) 19602 19603val setdist = new_definition ("setdist", 19604 ``setdist(s,t) = 19605 if (s = {}) \/ (t = {}) then &0 19606 else inf {dist(x,y) | x IN s /\ y IN t}``); 19607 19608val SETDIST_EMPTY = store_thm ("SETDIST_EMPTY", 19609 ``(!t. setdist({},t) = &0) /\ (!s. setdist(s,{}) = &0)``, 19610 REWRITE_TAC[setdist]); 19611 19612val SETDIST_POS_LE = store_thm ("SETDIST_POS_LE", 19613 ``!s t. &0 <= setdist(s,t)``, 19614 REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN 19615 COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN 19616 MATCH_MP_TAC REAL_LE_INF THEN 19617 SIMP_TAC std_ss [FORALL_IN_GSPEC, DIST_POS_LE] THEN 19618 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[]); 19619 19620val SETDIST_SUBSETS_EQ = store_thm ("SETDIST_SUBSETS_EQ", 19621 ``!s t s' t':real->bool. 19622 s' SUBSET s /\ t' SUBSET t /\ 19623 (!x y. x IN s /\ y IN t 19624 ==> ?x' y'. x' IN s' /\ y' IN t' /\ dist(x',y') <= dist(x,y)) 19625 ==> (setdist(s',t') = setdist(s,t))``, 19626 REPEAT STRIP_TAC THEN 19627 ASM_CASES_TAC ``s:real->bool = {}`` THENL 19628 [ASM_CASES_TAC ``s':real->bool = {}`` THEN 19629 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN ASM_SET_TAC[], 19630 ALL_TAC] THEN 19631 ASM_CASES_TAC ``t:real->bool = {}`` THENL 19632 [ASM_CASES_TAC ``t':real->bool = {}`` THEN 19633 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN ASM_SET_TAC[], 19634 ALL_TAC] THEN 19635 ASM_CASES_TAC ``s':real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN 19636 ASM_CASES_TAC ``t':real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN 19637 ASM_REWRITE_TAC[setdist] THEN MATCH_MP_TAC INF_EQ THEN 19638 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN ASM_MESON_TAC[SUBSET_DEF, REAL_LE_TRANS]); 19639 19640val REAL_LE_SETDIST = store_thm ("REAL_LE_SETDIST", 19641 ``!s t:real->bool d. 19642 ~(s = {}) /\ ~(t = {}) /\ 19643 (!x y. x IN s /\ y IN t ==> d <= dist(x,y)) 19644 ==> d <= setdist(s,t)``, 19645 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[setdist] THEN 19646 MP_TAC(ISPEC ``{dist(x:real,y) | x IN s /\ y IN t}`` INF) THEN 19647 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 19648 KNOW_TAC ``{dist (x,y) | x IN s /\ y IN t} <> {} /\ 19649 (?b. !x y. x IN s /\ y IN t ==> b <= dist (x,y))`` THENL 19650 [CONJ_TAC THENL 19651 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 19652 ASM_SET_TAC[], MESON_TAC[DIST_POS_LE]], 19653 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 19654 ASM_MESON_TAC[]); 19655 19656val SETDIST_LE_DIST = store_thm ("SETDIST_LE_DIST", 19657 ``!s t x y:real. x IN s /\ y IN t ==> setdist(s,t) <= dist(x,y)``, 19658 REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN 19659 COND_CASES_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 19660 MP_TAC(ISPEC ``{dist(x:real,y) | x IN s /\ y IN t}`` INF) THEN 19661 SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN 19662 KNOW_TAC ``{dist (x,y) | x IN s /\ y IN t} <> {} /\ 19663 (?b. !x y. x IN s /\ y IN t ==> b <= dist (x,y))`` THENL 19664 [CONJ_TAC THENL 19665 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 19666 ASM_SET_TAC[], MESON_TAC[DIST_POS_LE]], 19667 DISCH_TAC THEN ASM_REWRITE_TAC []] THEN 19668 ASM_MESON_TAC[]); 19669 19670val REAL_LE_SETDIST_EQ = store_thm ("REAL_LE_SETDIST_EQ", 19671 ``!d s t:real->bool. 19672 d <= setdist(s,t) <=> 19673 (!x y. x IN s /\ y IN t ==> d <= dist(x,y)) /\ 19674 ((s = {}) \/ (t = {}) ==> d <= &0)``, 19675 REPEAT GEN_TAC THEN MAP_EVERY ASM_CASES_TAC 19676 [``s:real->bool = {}``, ``t:real->bool = {}``] THEN 19677 ASM_REWRITE_TAC[SETDIST_EMPTY, NOT_IN_EMPTY] THEN 19678 ASM_MESON_TAC[REAL_LE_SETDIST, SETDIST_LE_DIST, REAL_LE_TRANS]); 19679 19680val REAL_SETDIST_LT_EXISTS = store_thm ("REAL_SETDIST_LT_EXISTS", 19681 ``!s t:real->bool b. 19682 ~(s = {}) /\ ~(t = {}) /\ setdist(s,t) < b 19683 ==> ?x y. x IN s /\ y IN t /\ dist(x,y) < b``, 19684 REWRITE_TAC[GSYM REAL_NOT_LE, REAL_LE_SETDIST_EQ] THEN MESON_TAC[]); 19685 19686val SETDIST_REFL = store_thm ("SETDIST_REFL", 19687 ``!s:real->bool. setdist(s,s) = &0``, 19688 GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM, SETDIST_POS_LE] THEN 19689 ASM_CASES_TAC ``s:real->bool = {}`` THENL 19690 [ASM_REWRITE_TAC[setdist, REAL_LE_REFL], ALL_TAC] THEN 19691 ASM_MESON_TAC[SETDIST_LE_DIST, MEMBER_NOT_EMPTY, DIST_REFL]); 19692 19693val SETDIST_SYM = store_thm ("SETDIST_SYM", 19694 ``!s t. setdist(s,t) = setdist(t,s)``, 19695 REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN ONCE_REWRITE_TAC [DISJ_SYM] THEN 19696 COND_CASES_TAC THEN ONCE_REWRITE_TAC [DISJ_SYM] THEN ASM_SIMP_TAC std_ss [] THEN 19697 AP_TERM_TAC THEN SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 19698 METIS_TAC[DIST_SYM]); 19699 19700val SETDIST_TRIANGLE = store_thm ("SETDIST_TRIANGLE", 19701 ``!s a t:real->bool. 19702 setdist(s,t) <= setdist(s,{a}) + setdist({a},t)``, 19703 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 19704 ASM_REWRITE_TAC[SETDIST_EMPTY, REAL_ADD_LID, SETDIST_POS_LE] THEN 19705 ASM_CASES_TAC ``t:real->bool = {}`` THEN 19706 ASM_REWRITE_TAC[SETDIST_EMPTY, REAL_ADD_RID, SETDIST_POS_LE] THEN 19707 ONCE_REWRITE_TAC[GSYM REAL_LE_SUB_RADD] THEN 19708 MATCH_MP_TAC REAL_LE_SETDIST THEN 19709 ASM_SIMP_TAC std_ss [NOT_INSERT_EMPTY, IN_SING, CONJ_EQ_IMP, 19710 RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2] THEN 19711 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 19712 ONCE_REWRITE_TAC[REAL_ARITH ``x - y <= z <=> x - z <= y:real``] THEN 19713 MATCH_MP_TAC REAL_LE_SETDIST THEN 19714 ASM_REWRITE_TAC[NOT_INSERT_EMPTY, IN_SING, CONJ_EQ_IMP, 19715 RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2] THEN 19716 X_GEN_TAC ``y:real`` THEN REPEAT STRIP_TAC THEN 19717 REWRITE_TAC[REAL_LE_SUB_RADD] THEN MATCH_MP_TAC REAL_LE_TRANS THEN 19718 EXISTS_TAC ``dist(x:real,y')`` THEN 19719 ASM_SIMP_TAC std_ss [SETDIST_LE_DIST, dist] THEN REAL_ARITH_TAC); 19720 19721val SETDIST_SINGS = store_thm ("SETDIST_SINGS", 19722 ``!x y. setdist({x},{y}) = dist(x,y)``, 19723 REWRITE_TAC[setdist, NOT_INSERT_EMPTY] THEN 19724 ONCE_REWRITE_TAC [METIS [] ``dist (x,y) = (\x y. dist (x,y)) x y``] THEN 19725 KNOW_TAC ``!f:real->real->real x y a b. {f x y | x IN {a} /\ y IN {b}} = {f a b}`` THENL 19726 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN SET_TAC [], 19727 DISCH_TAC] THEN ASM_REWRITE_TAC [] THEN 19728 SIMP_TAC std_ss [INF_INSERT_FINITE, FINITE_EMPTY]); 19729 19730val SETDIST_LIPSCHITZ = store_thm ("SETDIST_LIPSCHITZ", 19731 ``!s t x y:real. abs(setdist({x},s) - setdist({y},s)) <= dist(x,y)``, 19732 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SETDIST_SINGS] THEN 19733 REWRITE_TAC[REAL_ARITH 19734 ``abs(x - y) <= z <=> x <= z + y /\ y <= z + x:real``] THEN 19735 MESON_TAC[SETDIST_TRIANGLE, SETDIST_SYM]); 19736 19737val CONTINUOUS_AT_SETDIST = store_thm ("CONTINUOUS_AT_SETDIST", 19738 ``!s x:real. (\y. setdist({y},s)) continuous (at x)``, 19739 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at] THEN 19740 SIMP_TAC std_ss [dist] THEN 19741 METIS_TAC[REWRITE_RULE [dist] SETDIST_LIPSCHITZ, REAL_LET_TRANS]); 19742 19743val CONTINUOUS_ON_SETDIST = store_thm ("CONTINUOUS_ON_SETDIST", 19744 ``!s t:real->bool. (\y. setdist({y},s)) continuous_on t``, 19745 METIS_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON, 19746 CONTINUOUS_AT_SETDIST]); 19747 19748val UNIFORMLY_CONTINUOUS_ON_SETDIST = store_thm ("UNIFORMLY_CONTINUOUS_ON_SETDIST", 19749 ``!s t:real->bool. 19750 (\y. setdist({y},s)) uniformly_continuous_on t``, 19751 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN 19752 BETA_TAC THEN METIS_TAC[dist, SETDIST_LIPSCHITZ, REAL_LET_TRANS]); 19753 19754val SETDIST_DIFFERENCES = store_thm ("SETDIST_DIFFERENCES", 19755 ``!s t. setdist(s,t) = setdist({0},{x - y:real | x IN s /\ y IN t})``, 19756 REPEAT GEN_TAC THEN 19757 KNOW_TAC ``!f:real->real->real x y s t. 19758 ({f x y | x IN s /\ y IN t} = {}) <=> (s = {}) \/ (t = {})`` THENL 19759 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN SET_TAC [], 19760 DISCH_TAC] THEN 19761 ONCE_REWRITE_TAC [METIS [] ``x - y = (\x y. x - y) x y:real``] THEN 19762 ASM_REWRITE_TAC[setdist, NOT_INSERT_EMPTY] THEN 19763 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [] THEN AP_TERM_TAC THEN 19764 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_SING, EXISTS_PROD] THEN 19765 SIMP_TAC std_ss [GSYM CONJ_ASSOC, RIGHT_EXISTS_AND_THM, UNWIND_THM2, DIST_0] THEN 19766 REWRITE_TAC[dist] THEN MESON_TAC[]); 19767 19768val SETDIST_SUBSET_RIGHT = store_thm ("SETDIST_SUBSET_RIGHT", 19769 ``!s t u:real->bool. 19770 ~(t = {}) /\ t SUBSET u ==> setdist(s,u) <= setdist(s,t)``, 19771 REPEAT STRIP_TAC THEN 19772 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``u:real->bool = {}``] THEN 19773 ASM_SIMP_TAC std_ss [SETDIST_EMPTY, SETDIST_POS_LE, REAL_LE_REFL] THEN 19774 ASM_REWRITE_TAC[setdist] THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN 19775 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, SUBSET_DEF, EXISTS_PROD, GSPECIFICATION] THEN 19776 REPEAT(CONJ_TAC THENL 19777 [ASM_SIMP_TAC std_ss [EXTENSION, EXISTS_PROD, GSPECIFICATION] THEN ASM_SET_TAC[], 19778 ALL_TAC]) THEN METIS_TAC[DIST_POS_LE]); 19779 19780val SETDIST_SUBSET_LEFT = store_thm ("SETDIST_SUBSET_LEFT", 19781 ``!s t u:real->bool. 19782 ~(s = {}) /\ s SUBSET t ==> setdist(t,u) <= setdist(s,u)``, 19783 MESON_TAC[SETDIST_SUBSET_RIGHT, SETDIST_SYM]); 19784 19785val SETDIST_CLOSURE = store_thm ("SETDIST_CLOSURE", 19786 ``(!s t:real->bool. setdist(closure s,t) = setdist(s,t)) /\ 19787 (!s t:real->bool. setdist(s,closure t) = setdist(s,t))``, 19788 REWRITE_TAC [METIS [SWAP_FORALL_THM] 19789 ``(!s t. setdist (s,closure t) = setdist (s,t)) = 19790 (!t s. setdist (s,closure t) = setdist (s,t))``] THEN 19791 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SETDIST_SYM] THEN 19792 SIMP_TAC std_ss [] THEN 19793 REWRITE_TAC[MESON[REAL_LE_ANTISYM] 19794 ``(x:real = y) <=> !d. d <= x <=> d <= y``] THEN 19795 REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN 19796 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN 19797 ASM_REWRITE_TAC[CLOSURE_EQ_EMPTY, CLOSURE_EMPTY, NOT_IN_EMPTY] THEN 19798 ONCE_REWRITE_TAC [METIS [] ``d <= dist (x,y) = (\x y. d <= dist (x,y)) x y``] THEN 19799 ONCE_REWRITE_TAC [METIS [] ``x IN s /\ y IN t = x IN s /\ (\y. y IN t) y``] THEN 19800 MATCH_MP_TAC(SET_RULE 19801 ``s SUBSET c /\ 19802 (!y. Q y /\ (!x. x IN s ==> P x y) ==> (!x. x IN c ==> P x y)) 19803 ==> ((!x y. x IN c /\ Q y ==> P x y) <=> 19804 (!x y. x IN s /\ Q y ==> P x y))``) THEN 19805 SIMP_TAC std_ss [CLOSURE_SUBSET] THEN GEN_TAC THEN STRIP_TAC THEN 19806 ONCE_REWRITE_TAC [METIS [] ``dist (x,y) = (\x. dist (x, y)) x``] THEN 19807 MATCH_MP_TAC CONTINUOUS_GE_ON_CLOSURE THEN ASM_SIMP_TAC std_ss [] THEN 19808 ASM_SIMP_TAC std_ss [o_DEF, dist] THEN 19809 ONCE_REWRITE_TAC [METIS [] ``abs (x - y) = abs ((\x. x - y) x:real)``] THEN 19810 MATCH_MP_TAC CONTINUOUS_ON_ABS_COMPOSE THEN 19811 SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID]); 19812 19813val SETDIST_FRONTIER = store_thm ("SETDIST_FRONTIER", 19814 ``(!s t:real->bool. 19815 DISJOINT s t ==> (setdist(frontier s,t) = setdist(s,t))) /\ 19816 (!s t:real->bool. 19817 DISJOINT s t ==> (setdist(s,frontier t) = setdist(s,t)))``, 19818 MATCH_MP_TAC(TAUT `(p ==> q) /\ p ==> p /\ q`) THEN 19819 CONJ_TAC THENL [MESON_TAC[SETDIST_SYM, DISJOINT_SYM], ALL_TAC] THEN 19820 REPEAT STRIP_TAC THEN 19821 GEN_REWR_TAC RAND_CONV [GSYM(CONJUNCT1 SETDIST_CLOSURE)] THEN 19822 MATCH_MP_TAC SETDIST_SUBSETS_EQ THEN 19823 SIMP_TAC std_ss [frontier, IN_DIFF, DIFF_SUBSET, SUBSET_REFL] THEN 19824 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 19825 ASM_CASES_TAC ``(x:real) IN interior s`` THENL 19826 [ALL_TAC, ASM_MESON_TAC[REAL_LE_REFL]] THEN 19827 KNOW_TAC ``?y' x'. (x' IN closure s /\ x' NOTIN interior s) /\ 19828 y' IN t /\ dist (x',y') <= dist (x,y)`` THENL 19829 [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN 19830 EXISTS_TAC ``y:real`` THEN ASM_REWRITE_TAC[] THEN 19831 MP_TAC(ISPECL [``segment[x:real,y]``, ``s:real->bool``] 19832 CONNECTED_INTER_FRONTIER) THEN 19833 REWRITE_TAC[CONNECTED_SEGMENT, GSYM MEMBER_NOT_EMPTY] THEN 19834 KNOW_TAC ``(?x'. x' IN segment [(x,y)] INTER s) /\ 19835 (?x'. x' IN segment [(x,y)] DIFF s)`` THENL 19836 [CONJ_TAC THENL [EXISTS_TAC ``x:real``, EXISTS_TAC ``y:real``] THEN 19837 ASM_SIMP_TAC std_ss [IN_INTER, IN_DIFF, ENDS_IN_SEGMENT] THEN 19838 MP_TAC(ISPEC ``s:real->bool`` INTERIOR_SUBSET) THEN ASM_SET_TAC[], 19839 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 19840 DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN 19841 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [IN_INTER, frontier, IN_DIFF] THEN 19842 MESON_TAC[DIST_IN_CLOSED_SEGMENT]]); 19843 19844val SETDIST_COMPACT_CLOSED = store_thm ("SETDIST_COMPACT_CLOSED", 19845 ``!s t:real->bool. 19846 compact s /\ closed t /\ ~(s = {}) /\ ~(t = {}) 19847 ==> ?x y. x IN s /\ y IN t /\ (dist(x,y) = setdist(s,t))``, 19848 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN 19849 KNOW_TAC ``?x y. (\x. x IN s) x /\ (\y. y IN t) y /\ 19850 (\x y. dist (x,y) <= setdist (s,t)) x y /\ 19851 (\x y. setdist (s,t) <= dist (x,y)) x y`` THENL 19852 [ALL_TAC, METIS_TAC []] THEN 19853 MATCH_MP_TAC(METIS [] 19854 ``(!x y. P x /\ Q y ==> R' x y) /\ (?x y. (P x /\ Q y /\ R x y)) 19855 ==> (?x y. P x /\ Q y /\ R x y /\ R' x y)``) THEN 19856 SIMP_TAC std_ss [SETDIST_LE_DIST] THEN 19857 ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN 19858 MP_TAC(ISPECL [``{x - y:real | x IN s /\ y IN t}``, ``0:real``] 19859 DISTANCE_ATTAINS_INF) THEN 19860 ASM_SIMP_TAC std_ss [COMPACT_CLOSED_DIFFERENCES, EXISTS_IN_GSPEC, FORALL_IN_GSPEC, 19861 DIST_0, GSYM CONJ_ASSOC, GSPECIFICATION, EXISTS_PROD] THEN 19862 REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN 19863 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[]); 19864 19865val SETDIST_CLOSED_COMPACT = store_thm ("SETDIST_CLOSED_COMPACT", 19866 ``!s t:real->bool. 19867 closed s /\ compact t /\ ~(s = {}) /\ ~(t = {}) 19868 ==> ?x y. x IN s /\ y IN t /\ (dist(x,y) = setdist(s,t))``, 19869 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN 19870 KNOW_TAC ``?x y. (\x. x IN s) x /\ (\y. y IN t) y /\ 19871 (\x y. dist (x,y) <= setdist (s,t)) x y /\ 19872 (\x y. setdist (s,t) <= dist (x,y)) x y`` THENL 19873 [ALL_TAC, METIS_TAC []] THEN 19874 MATCH_MP_TAC(METIS[] 19875 ``(!x y. P x /\ Q y ==> R' x y) /\ (?x y. P x /\ Q y /\ R x y) 19876 ==> ?x y. P x /\ Q y /\ R x y /\ R' x y``) THEN 19877 SIMP_TAC std_ss [SETDIST_LE_DIST] THEN 19878 ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN 19879 MP_TAC(ISPECL [``{x - y:real | x IN s /\ y IN t}``, ``0:real``] 19880 DISTANCE_ATTAINS_INF) THEN 19881 ASM_SIMP_TAC std_ss [CLOSED_COMPACT_DIFFERENCES, EXISTS_IN_GSPEC, FORALL_IN_GSPEC, 19882 DIST_0, GSYM CONJ_ASSOC, GSPECIFICATION, EXISTS_PROD] THEN 19883 REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN 19884 SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[]); 19885 19886val SETDIST_EQ_0_COMPACT_CLOSED = store_thm ("SETDIST_EQ_0_COMPACT_CLOSED", 19887 ``!s t:real->bool. 19888 compact s /\ closed t 19889 ==> ((setdist(s,t) = &0) <=> (s = {}) \/ (t = {}) \/ ~(s INTER t = {}))``, 19890 REPEAT STRIP_TAC THEN 19891 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN 19892 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN EQ_TAC THENL 19893 [MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] 19894 SETDIST_COMPACT_CLOSED) THEN ASM_REWRITE_TAC[] THEN 19895 REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN MESON_TAC[DIST_EQ_0], 19896 REWRITE_TAC[GSYM REAL_LE_ANTISYM, SETDIST_POS_LE] THEN 19897 REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN 19898 MESON_TAC[SETDIST_LE_DIST, DIST_EQ_0]]); 19899 19900val SETDIST_EQ_0_CLOSED_COMPACT = store_thm ("SETDIST_EQ_0_CLOSED_COMPACT", 19901 ``!s t:real->bool. 19902 closed s /\ compact t 19903 ==> ((setdist(s,t) = &0) <=> (s = {}) \/ (t = {}) \/ ~(s INTER t = {}))``, 19904 ONCE_REWRITE_TAC[SETDIST_SYM] THEN 19905 SIMP_TAC std_ss [SETDIST_EQ_0_COMPACT_CLOSED] THEN SET_TAC[]); 19906 19907val SETDIST_EQ_0_BOUNDED = store_thm ("SETDIST_EQ_0_BOUNDED", 19908 ``!s t:real->bool. 19909 (bounded s \/ bounded t) 19910 ==> ((setdist(s,t) = &0) <=> 19911 (s = {}) \/ (t = {}) \/ ~(closure(s) INTER closure(t) = {}))``, 19912 REPEAT GEN_TAC THEN 19913 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN 19914 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN STRIP_TAC THEN 19915 ONCE_REWRITE_TAC[MESON[SETDIST_CLOSURE] 19916 ``setdist(s,t) = setdist(closure s,closure t)``] THEN 19917 ASM_SIMP_TAC std_ss [SETDIST_EQ_0_COMPACT_CLOSED, SETDIST_EQ_0_CLOSED_COMPACT, 19918 COMPACT_CLOSURE, CLOSED_CLOSURE, CLOSURE_EQ_EMPTY]); 19919 19920val SETDIST_TRANSLATION = store_thm ("SETDIST_TRANSLATION", 19921 ``!a:real s t. 19922 setdist(IMAGE (\x. a + x) s,IMAGE (\x. a + x) t) = setdist(s,t)``, 19923 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[SETDIST_DIFFERENCES] THEN 19924 AP_TERM_TAC THEN AP_TERM_TAC THEN 19925 KNOW_TAC ``!f:real->real->real x:real y:real g:real->real s:real->bool t:real->bool. 19926 {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 19927 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 19928 ASM_SET_TAC[], DISCH_TAC] THEN 19929 ONCE_REWRITE_TAC [METIS [] ``x - y = (\x y. x - y) x y:real``] THEN 19930 ASM_REWRITE_TAC [] THEN 19931 SIMP_TAC std_ss [REAL_ARITH ``(a + x) - (a + y):real = x - y``]); 19932 19933val SETDIST_LINEAR_IMAGE = store_thm ("SETDIST_LINEAR_IMAGE", 19934 ``!f:real->real s t. 19935 linear f /\ (!x. abs(f x) = abs x) 19936 ==> (setdist(IMAGE f s,IMAGE f t) = setdist(s,t))``, 19937 REPEAT STRIP_TAC THEN REWRITE_TAC[setdist, IMAGE_EQ_EMPTY] THEN 19938 COND_CASES_TAC THEN ASM_REWRITE_TAC[dist] THEN AP_TERM_TAC THEN 19939 ONCE_REWRITE_TAC [METIS [] ``abs (x - y) = (\x y. abs (x - y)) x y:real``] THEN 19940 KNOW_TAC ``!f:real->real->real x:real y:real g:real->real s:real->bool t:real->bool. 19941 {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 19942 [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN 19943 ASM_SET_TAC[], DISCH_TAC] THEN ASM_REWRITE_TAC [] THEN BETA_TAC THEN 19944 FIRST_X_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN 19945 ASM_SIMP_TAC std_ss []); 19946 19947val SETDIST_UNIQUE = store_thm ("SETDIST_UNIQUE", 19948 ``!s t a b:real d. 19949 a IN s /\ b IN t /\ (dist(a,b) = d) /\ 19950 (!x y. x IN s /\ y IN t ==> dist(a,b) <= dist(x,y)) 19951 ==> (setdist(s,t) = d)``, 19952 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL 19953 [ASM_MESON_TAC[SETDIST_LE_DIST], 19954 MATCH_MP_TAC REAL_LE_SETDIST THEN ASM_SET_TAC[]]); 19955 19956val SETDIST_UNIV = store_thm ("SETDIST_UNIV", 19957 ``(!s. setdist(s,univ(:real)) = &0) /\ 19958 (!t. setdist(univ(:real),t) = &0)``, 19959 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SETDIST_SYM] THEN 19960 REWRITE_TAC[] THEN X_GEN_TAC ``s:real->bool`` THEN 19961 ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[SETDIST_EMPTY] THEN 19962 MATCH_MP_TAC SETDIST_UNIQUE THEN 19963 SIMP_TAC std_ss [IN_UNIV, DIST_EQ_0, RIGHT_EXISTS_AND_THM] THEN 19964 ASM_REWRITE_TAC[UNWIND_THM1, DIST_REFL, DIST_POS_LE, MEMBER_NOT_EMPTY]); 19965 19966val SETDIST_ZERO = store_thm ("SETDIST_ZERO", 19967 ``!s t:real->bool. ~(DISJOINT s t) ==> (setdist(s,t) = &0)``, 19968 REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_UNIQUE THEN 19969 KNOW_TAC ``?a. a IN s /\ a IN t /\ (dist (a,a) = 0) /\ 19970 !x y. x IN s /\ y IN t ==> dist (a,a) <= dist (x,y)`` THENL 19971 [ALL_TAC, METIS_TAC []] THEN 19972 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r /\ s <=> r /\ p /\ q /\ s`] THEN 19973 REWRITE_TAC[DIST_EQ_0, UNWIND_THM2, DIST_REFL, DIST_POS_LE] THEN 19974 ASM_SET_TAC[]); 19975 19976val SETDIST_ZERO_STRONG = store_thm ("SETDIST_ZERO_STRONG", 19977 ``!s t:real->bool. 19978 ~(DISJOINT (closure s) (closure t)) ==> (setdist(s,t) = &0)``, 19979 MESON_TAC[SETDIST_CLOSURE, SETDIST_ZERO]); 19980 19981val SETDIST_FRONTIERS = store_thm ("SETDIST_FRONTIERS", 19982 ``!s t:real->bool. 19983 setdist(s,t) = 19984 if DISJOINT s t then setdist(frontier s,frontier t) else &0``, 19985 REPEAT STRIP_TAC THEN 19986 COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [SETDIST_ZERO] THEN 19987 ASSUME_TAC SETDIST_FRONTIER THEN POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN 19988 DISCH_THEN (CONJUNCTS_THEN2 K_TAC ASSUME_TAC) THEN ASM_SIMP_TAC std_ss [] THEN 19989 POP_ASSUM K_TAC THEN 19990 ASM_CASES_TAC ``DISJOINT s (frontier t:real->bool)`` THENL 19991 [ASM_MESON_TAC[SETDIST_FRONTIER], ALL_TAC] THEN 19992 GEN_REWR_TAC LAND_CONV [GSYM(CONJUNCT1 SETDIST_CLOSURE)] THEN 19993 CONV_TAC SYM_CONV THEN MATCH_MP_TAC SETDIST_SUBSETS_EQ THEN 19994 SIMP_TAC std_ss [frontier, DIFF_SUBSET, SUBSET_REFL, IN_DIFF] THEN 19995 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 19996 KNOW_TAC ``?y' x'. 19997 (x' IN closure s /\ x' NOTIN interior s) /\ 19998 (y' IN closure t /\ y' NOTIN interior t) /\ dist (x',y') <= dist (x,y)`` THENL 19999 [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN EXISTS_TAC ``y:real`` THEN 20000 ASM_REWRITE_TAC[] THEN 20001 ASM_CASES_TAC ``(x:real) IN interior s`` THENL 20002 [ALL_TAC, ASM_MESON_TAC[REAL_LE_REFL]] THEN 20003 MP_TAC(ISPECL [``segment[x:real,y]``, ``interior s:real->bool``] 20004 CONNECTED_INTER_FRONTIER) THEN 20005 REWRITE_TAC[CONNECTED_SEGMENT, GSYM MEMBER_NOT_EMPTY] THEN 20006 KNOW_TAC ``(?x'. x' IN segment [(x,y)] INTER interior s) /\ 20007 (?x'. x' IN segment [(x,y)] DIFF interior s)`` THENL 20008 [CONJ_TAC THENL [EXISTS_TAC ``x:real``, EXISTS_TAC ``y:real``] THEN 20009 ASM_SIMP_TAC std_ss [IN_INTER, IN_DIFF, ENDS_IN_SEGMENT] THEN 20010 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE 20011 ``y IN u ==> (u INTER v = {}) ==> ~(y IN v)``)) THEN 20012 REWRITE_TAC[INTERIOR_CLOSURE, SET_RULE 20013 ``(s INTER (UNIV DIFF t) = {}) <=> s SUBSET t``] THEN 20014 MATCH_MP_TAC SUBSET_CLOSURE THEN ASM_SET_TAC[], 20015 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 20016 DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN 20017 POP_ASSUM MP_TAC THEN 20018 SIMP_TAC std_ss [IN_INTER, GSYM frontier, GSYM IN_DIFF] THEN 20019 MESON_TAC[FRONTIER_INTERIOR_SUBSET, SUBSET_DEF, DIST_IN_CLOSED_SEGMENT]]); 20020 20021val SETDIST_SING_FRONTIER = store_thm ("SETDIST_SING_FRONTIER", 20022 ``!s x:real. ~(x IN s) ==> (setdist({x},frontier s) = setdist({x},s))``, 20023 MESON_TAC[SET_RULE ``DISJOINT {x} s <=> ~(x IN s)``, SETDIST_FRONTIER]); 20024 20025val SETDIST_CLOSEST_POINT = store_thm ("SETDIST_CLOSEST_POINT", 20026 ``!a:real s. 20027 closed s /\ ~(s = {}) ==> (setdist({a},s) = dist(a,closest_point s a))``, 20028 REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_UNIQUE THEN 20029 SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM, IN_SING, UNWIND_THM2] THEN 20030 EXISTS_TAC ``closest_point s (a:real)`` THEN 20031 ASM_MESON_TAC[CLOSEST_POINT_EXISTS, DIST_SYM]); 20032 20033val SETDIST_EQ_0_SING = store_thm ("SETDIST_EQ_0_SING", 20034 ``(!s x:real. (setdist({x},s) = &0) <=> (s = {}) \/ x IN closure s) /\ 20035 (!s x:real. (setdist(s,{x}) = &0) <=> (s = {}) \/ x IN closure s)``, 20036 SIMP_TAC std_ss [SETDIST_EQ_0_BOUNDED, BOUNDED_SING, CLOSURE_SING] THEN SET_TAC[]); 20037 20038val SETDIST_EQ_0_CLOSED = store_thm ("SETDIST_EQ_0_CLOSED", 20039 ``!s x. closed s ==> ((setdist({x},s) = &0) <=> (s = {}) \/ x IN s)``, 20040 SIMP_TAC std_ss [SETDIST_EQ_0_COMPACT_CLOSED, COMPACT_SING] THEN SET_TAC[]); 20041 20042val SETDIST_EQ_0_CLOSED_IN = store_thm ("SETDIST_EQ_0_CLOSED_IN", 20043 ``!u s x. closed_in (subtopology euclidean u) s /\ x IN u 20044 ==> ((setdist({x},s) = &0) <=> (s = {}) \/ x IN s)``, 20045 REWRITE_TAC[SETDIST_EQ_0_SING, CLOSED_IN_INTER_CLOSURE] THEN SET_TAC[]); 20046 20047val SETDIST_SING_IN_SET = store_thm ("SETDIST_SING_IN_SET", 20048 ``!x s. x IN s ==> (setdist({x},s) = &0)``, 20049 SIMP_TAC std_ss [SETDIST_EQ_0_SING, REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET]); 20050 20051val SETDIST_SING_FRONTIER_CASES = store_thm ("SETDIST_SING_FRONTIER_CASES", 20052 ``!s x:real. 20053 setdist({x},s) = if x IN s then &0 else setdist({x},frontier s)``, 20054 REPEAT GEN_TAC THEN COND_CASES_TAC THEN 20055 ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, SETDIST_SING_FRONTIER]); 20056 20057val SETDIST_SING_TRIANGLE = store_thm ("SETDIST_SING_TRIANGLE", 20058 ``!s x y:real. abs(setdist({x},s) - setdist({y},s)) <= dist(x,y)``, 20059 REPEAT GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 20060 ASM_REWRITE_TAC[SETDIST_EMPTY, REAL_SUB_REFL, ABS_N, DIST_POS_LE] THEN 20061 REWRITE_TAC[ABS_BOUNDS, REAL_NEG_SUB] THEN REPEAT STRIP_TAC THEN 20062 ONCE_REWRITE_TAC[REAL_ARITH ``a - b <= c <=> a - c <= b:real``, 20063 REAL_ARITH ``-a <= b - c <=> c - a <= b:real``] THEN 20064 MATCH_MP_TAC REAL_LE_SETDIST THEN ASM_REWRITE_TAC[NOT_INSERT_EMPTY] THEN 20065 SIMP_TAC std_ss [IN_SING, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2] THEN 20066 X_GEN_TAC ``z:real`` THEN DISCH_TAC THEN REWRITE_TAC [dist] THENL 20067 [MATCH_MP_TAC(REAL_ARITH 20068 ``a <= abs(y:real - z) ==> a - abs(x - y) <= abs(x - z:real)``), 20069 MATCH_MP_TAC(REAL_ARITH 20070 ``a <= abs(x:real - z) ==> a - abs(x - y) <= abs(y - z)``)] THEN 20071 REWRITE_TAC [GSYM dist] THEN 20072 MATCH_MP_TAC SETDIST_LE_DIST THEN ASM_REWRITE_TAC[IN_SING]); 20073 20074val SETDIST_LE_SING = store_thm ("SETDIST_LE_SING", 20075 ``!s t x:real. x IN s ==> setdist(s,t) <= setdist({x},t)``, 20076 REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_SUBSET_LEFT THEN ASM_SET_TAC[]); 20077 20078val SETDIST_BALLS = store_thm ("SETDIST_BALLS", 20079 ``(!a b:real r s. 20080 setdist(ball(a,r),ball(b,s)) = 20081 if r <= &0 \/ s <= &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\ 20082 (!a b:real r s. 20083 setdist(ball(a,r),cball(b,s)) = 20084 if r <= &0 \/ s < &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\ 20085 (!a b:real r s. 20086 setdist(cball(a,r),ball(b,s)) = 20087 if r < &0 \/ s <= &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\ 20088 (!a b:real r s. 20089 setdist(cball(a,r),cball(b,s)) = 20090 if r < &0 \/ s < &0 then &0 else max (&0) (dist(a,b) - (r + s)))``, 20091 REWRITE_TAC[METIS[] 20092 ``(x = if p then y else z) <=> (p ==> (x = y)) /\ (~p ==> (x = z))``] THEN 20093 SIMP_TAC std_ss [TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN 20094 SIMP_TAC std_ss [BALL_EMPTY, CBALL_EMPTY, SETDIST_EMPTY, DE_MORGAN_THM] THEN 20095 ONCE_REWRITE_TAC[METIS[SETDIST_CLOSURE] 20096 ``setdist(s,t) = setdist(closure s,closure t)``] THEN 20097 SIMP_TAC std_ss [REAL_NOT_LE, REAL_NOT_LT, CLOSURE_BALL] THEN 20098 REWRITE_TAC[SETDIST_CLOSURE] THEN 20099 MATCH_MP_TAC(TAUT `(s ==> p /\ q /\ r) /\ s ==> p /\ q /\ r /\ s`) THEN 20100 CONJ_TAC THENL [METIS_TAC[REAL_LT_IMP_LE], REPEAT GEN_TAC] THEN 20101 REWRITE_TAC[max_def, REAL_SUB_LE] THEN COND_CASES_TAC THEN 20102 SIMP_TAC std_ss [SETDIST_EQ_0_BOUNDED, BOUNDED_CBALL, CLOSED_CBALL, CLOSURE_CLOSED, 20103 CBALL_EQ_EMPTY, INTER_BALLS_EQ_EMPTY] 20104 THENL [ALL_TAC, ASM_REAL_ARITH_TAC] THEN 20105 ASM_CASES_TAC ``b:real = a`` THENL 20106 [FIRST_X_ASSUM SUBST_ALL_TAC THEN 20107 RULE_ASSUM_TAC(REWRITE_RULE[DIST_REFL]) THEN 20108 ASM_CASES_TAC ``(r = &0:real) /\ (s = &0:real)`` THENL [ALL_TAC, ASM_REAL_ARITH_TAC] THEN 20109 ASM_SIMP_TAC std_ss [CBALL_SING, SETDIST_SINGS, dist] THEN REAL_ARITH_TAC, 20110 STRIP_TAC] THEN 20111 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL 20112 [ALL_TAC, 20113 MATCH_MP_TAC REAL_LE_SETDIST THEN 20114 ASM_REWRITE_TAC[CBALL_EQ_EMPTY, REAL_NOT_LT, IN_CBALL, dist] THEN 20115 REAL_ARITH_TAC] THEN 20116 MATCH_MP_TAC REAL_LE_TRANS THEN 20117 EXISTS_TAC ``dist(a + r / dist(a,b) * (b - a):real, 20118 b - s / dist(a,b) * (b - a))`` THEN 20119 CONJ_TAC THENL 20120 [MATCH_MP_TAC SETDIST_LE_DIST THEN 20121 REWRITE_TAC[dist, IN_CBALL, REAL_ARITH ``abs(a - (a + x)) = abs x:real``, 20122 REAL_ARITH ``abs(a - (a - x)) = abs x:real``] THEN 20123 REWRITE_TAC [GSYM dist] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN 20124 FULL_SIMP_TAC real_ss [dist, ABS_MUL, ABS_DIV, ABS_ABS, ABS_NZ, 20125 REAL_LT_IMP_NE, REAL_ARITH ``(b <> a) = (b - a <> 0:real)``] THEN 20126 KNOW_TAC ``abs (b - a:real) <> 0`` THENL [METIS_TAC [REAL_LT_IMP_NE], DISCH_TAC] THEN 20127 ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_SUB_0, ABS_ZERO] THEN 20128 ASM_REAL_ARITH_TAC, 20129 REWRITE_TAC[dist, REAL_ARITH 20130 ``(a + d * (b - a)) - (b - e * (b - a)):real = 20131 (&1 - d - e) * (a - b:real)``] THEN 20132 REWRITE_TAC[ABS_MUL, real_div, REAL_ARITH 20133 ``&1 - r * y - s * y = &1 - (r + s) * y:real``] THEN REWRITE_TAC [GSYM real_div] THEN 20134 REWRITE_TAC [METIS [GSYM ABS_ABS] ``d * abs (a - b) = d * abs(abs (a - b:real))``] THEN 20135 REWRITE_TAC[GSYM ABS_MUL] THEN 20136 KNOW_TAC ``!n x:real. ~(n = &0) ==> ((&1 - x / n) * n = n - x)`` THENL 20137 [REPEAT GEN_TAC THEN DISCH_TAC THEN 20138 ASM_SIMP_TAC std_ss [REAL_SUB_RDISTRIB, REAL_DIV_RMUL] THEN 20139 REAL_ARITH_TAC, DISCH_TAC] THEN 20140 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``(b <> a) = (abs (a - b) <> 0:real)``]) THEN 20141 ASM_SIMP_TAC real_ss [REAL_SUB_0, ABS_ZERO] THEN 20142 FULL_SIMP_TAC std_ss [dist] THEN SIMP_TAC std_ss [REAL_LE_LT] THEN 20143 DISJ2_TAC THEN REWRITE_TAC [ABS_REFL, REAL_SUB_LE] THEN ASM_REWRITE_TAC []]); 20144 20145(* ------------------------------------------------------------------------- *) 20146(* Use set distance for an easy proof of separation properties etc. *) 20147(* ------------------------------------------------------------------------- *) 20148 20149val SEPARATION_CLOSURES = store_thm ("SEPARATION_CLOSURES", 20150 ``!s t:real->bool. 20151 (s INTER closure(t) = {}) /\ (t INTER closure(s) = {}) 20152 ==> ?u v. DISJOINT u v /\ open u /\ open v /\ 20153 s SUBSET u /\ t SUBSET v``, 20154 REPEAT STRIP_TAC THEN 20155 ASM_CASES_TAC ``s:real->bool = {}`` THENL 20156 [MAP_EVERY EXISTS_TAC [``{}:real->bool``, ``univ(:real)``] THEN 20157 ASM_REWRITE_TAC[OPEN_EMPTY, OPEN_UNIV] THEN ASM_SET_TAC[], 20158 ALL_TAC] THEN 20159 ASM_CASES_TAC ``t:real->bool = {}`` THENL 20160 [MAP_EVERY EXISTS_TAC [``univ(:real)``, ``{}:real->bool``] THEN 20161 ASM_REWRITE_TAC[OPEN_EMPTY, OPEN_UNIV] THEN ASM_SET_TAC[], 20162 ALL_TAC] THEN 20163 EXISTS_TAC ``{x | x IN univ(:real) /\ 20164 (setdist({x},t) - setdist({x},s)) IN 20165 {x | &0 < x}}`` THEN 20166 EXISTS_TAC ``{x | x IN univ(:real) /\ 20167 (setdist({x},t) - setdist({x},s)) IN 20168 {x | x < &0}}`` THEN 20169 REPEAT CONJ_TAC THENL 20170 [REWRITE_TAC[SET_RULE ``DISJOINT s t <=> !x. x IN s /\ x IN t ==> F``] THEN 20171 SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV] THEN REAL_ARITH_TAC, 20172 ONCE_REWRITE_TAC [METIS [] ``(setdist ({x},t) - setdist ({x},s)) = 20173 (\x. setdist ({x},t) - setdist ({x},s)) x``] THEN 20174 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN 20175 SIMP_TAC std_ss [REWRITE_RULE[real_gt] OPEN_HALFSPACE_COMPONENT_GT, OPEN_UNIV] THEN 20176 SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_SETDIST], 20177 ONCE_REWRITE_TAC [METIS [] ``(setdist ({x},t) - setdist ({x},s)) = 20178 (\x. setdist ({x},t) - setdist ({x},s)) x``] THEN 20179 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN 20180 SIMP_TAC std_ss [OPEN_HALFSPACE_COMPONENT_LT, OPEN_UNIV] THEN 20181 SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_SETDIST], 20182 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNIV] THEN 20183 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH 20184 ``&0 <= x /\ (y = &0) /\ ~(x = &0) ==> &0 < x - y:real``), 20185 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNIV] THEN 20186 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH 20187 ``&0 <= y /\ (x = &0) /\ ~(y = &0) ==> x - y < &0:real``)] THEN 20188 ASM_SIMP_TAC std_ss [SETDIST_POS_LE, SETDIST_EQ_0_BOUNDED, BOUNDED_SING] THEN 20189 ASM_SIMP_TAC std_ss [CLOSED_SING, CLOSURE_CLOSED, NOT_INSERT_EMPTY, 20190 REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET, 20191 SET_RULE ``({a} INTER s = {}) <=> ~(a IN s)``] THEN 20192 ASM_SET_TAC[]); 20193 20194val SEPARATION_NORMAL = store_thm ("SEPARATION_NORMAL", 20195 ``!s t:real->bool. 20196 closed s /\ closed t /\ (s INTER t = {}) 20197 ==> ?u v. open u /\ open v /\ 20198 s SUBSET u /\ t SUBSET v /\ (u INTER v = {})``, 20199 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM DISJOINT_DEF] THEN 20200 ONCE_REWRITE_TAC[TAUT 20201 `a /\ b /\ c /\ d /\ e <=> e /\ a /\ b /\ c /\ d`] THEN 20202 MATCH_MP_TAC SEPARATION_CLOSURES THEN 20203 ASM_SIMP_TAC std_ss [CLOSURE_CLOSED] THEN ASM_SET_TAC[]); 20204 20205val SEPARATION_NORMAL_LOCAL = store_thm ("SEPARATION_NORMAL_LOCAL", 20206 ``!s t u:real->bool. 20207 closed_in (subtopology euclidean u) s /\ 20208 closed_in (subtopology euclidean u) t /\ 20209 (s INTER t = {}) 20210 ==> ?s' t'. open_in (subtopology euclidean u) s' /\ 20211 open_in (subtopology euclidean u) t' /\ 20212 s SUBSET s' /\ t SUBSET t' /\ (s' INTER t' = {})``, 20213 REPEAT STRIP_TAC THEN 20214 ASM_CASES_TAC ``s:real->bool = {}`` THENL 20215 [MAP_EVERY EXISTS_TAC [``{}:real->bool``, ``u:real->bool``] THEN 20216 ASM_SIMP_TAC std_ss [OPEN_IN_REFL, OPEN_IN_EMPTY, INTER_EMPTY, EMPTY_SUBSET] THEN 20217 ASM_MESON_TAC[CLOSED_IN_IMP_SUBSET], 20218 ALL_TAC] THEN 20219 ASM_CASES_TAC ``t:real->bool = {}`` THENL 20220 [MAP_EVERY EXISTS_TAC [``u:real->bool``, ``{}:real->bool``] THEN 20221 ASM_SIMP_TAC std_ss [OPEN_IN_REFL, OPEN_IN_EMPTY, INTER_EMPTY, EMPTY_SUBSET] THEN 20222 ASM_MESON_TAC[CLOSED_IN_IMP_SUBSET], 20223 ALL_TAC] THEN 20224 EXISTS_TAC ``{x:real | x IN u /\ setdist({x},s) < setdist({x},t)}`` THEN 20225 EXISTS_TAC ``{x:real | x IN u /\ setdist({x},t) < setdist({x},s)}`` THEN 20226 SIMP_TAC std_ss [EXTENSION, SUBSET_DEF, GSPECIFICATION, SETDIST_SING_IN_SET, IN_INTER, 20227 NOT_IN_EMPTY, SETDIST_POS_LE, CONJ_ASSOC, 20228 REAL_ARITH ``&0 < x <=> &0 <= x /\ ~(x = &0:real)``] THEN 20229 CONJ_TAC THENL [ALL_TAC, METIS_TAC[REAL_LT_ANTISYM]] THEN 20230 ONCE_REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL 20231 [ALL_TAC, 20232 ASM_MESON_TAC[SETDIST_EQ_0_CLOSED_IN, CLOSED_IN_IMP_SUBSET, SUBSET_DEF, 20233 MEMBER_NOT_EMPTY, IN_INTER]] THEN 20234 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN 20235 ONCE_REWRITE_TAC [METIS [] ``(setdist ({x},t) - setdist ({x},s)) = 20236 (\x. setdist ({x},t) - setdist ({x},s)) x``] THEN 20237 REWRITE_TAC[SET_RULE 20238 ``{x:real | x IN u /\ &0 < (f:real->real) x} = 20239 {x:real | x IN u /\ f x IN {x | &0 < x}}``] THEN 20240 CONJ_TAC THEN 20241 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN 20242 REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT, 20243 REWRITE_RULE[real_gt] OPEN_HALFSPACE_COMPONENT_GT, OPEN_UNIV] THEN 20244 SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_SETDIST]); 20245 20246val SEPARATION_NORMAL_COMPACT = store_thm ("SEPARATION_NORMAL_COMPACT", 20247 ``!s t:real->bool. 20248 compact s /\ closed t /\ (s INTER t = {}) 20249 ==> ?u v. open u /\ compact(closure u) /\ open v /\ 20250 s SUBSET u /\ t SUBSET v /\ (u INTER v = {})``, 20251 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE] THEN 20252 REPEAT STRIP_TAC THEN FIRST_ASSUM 20253 (MP_TAC o SPEC ``0:real`` o MATCH_MP BOUNDED_SUBSET_BALL) THEN 20254 DISCH_THEN(X_CHOOSE_THEN ``r:real`` STRIP_ASSUME_TAC) THEN 20255 MP_TAC(ISPECL [``s:real->bool``, ``t UNION (univ(:real) DIFF ball(0,r))``] 20256 SEPARATION_NORMAL) THEN 20257 ASM_SIMP_TAC std_ss [CLOSED_UNION, GSYM OPEN_CLOSED, OPEN_BALL] THEN 20258 KNOW_TAC ``((s :real -> bool) INTER 20259 ((t :real -> bool) UNION 20260 (univ(:real) DIFF ball ((0 :real),(r :real)))) = 20261 ({} :real -> bool))`` THENL [ASM_SET_TAC[], DISCH_TAC THEN 20262 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 20263 STRIP_TAC THEN EXISTS_TAC ``u:real->bool`` THEN 20264 EXISTS_TAC ``v:real->bool`` THEN ASM_REWRITE_TAC[] THEN 20265 CONJ_TAC THENL [MATCH_MP_TAC BOUNDED_CLOSURE, ASM_SET_TAC[]] THEN 20266 MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC ``ball(0:real,r)`` THEN 20267 REWRITE_TAC[BOUNDED_BALL] THEN ASM_SET_TAC[]); 20268 20269val SEPARATION_HAUSDORFF = store_thm ("SEPARATION_HAUSDORFF", 20270 ``!x:real y. 20271 ~(x = y) 20272 ==> ?u v. open u /\ open v /\ x IN u /\ y IN v /\ (u INTER v = {})``, 20273 REPEAT STRIP_TAC THEN 20274 MP_TAC(SPECL [``{x:real}``, ``{y:real}``] SEPARATION_NORMAL) THEN 20275 REWRITE_TAC[SING_SUBSET, CLOSED_SING] THEN 20276 DISCH_THEN MATCH_MP_TAC THEN ASM_SET_TAC[]); 20277 20278val SEPARATION_T2 = store_thm ("SEPARATION_T2", 20279 ``!x:real y. 20280 ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ y IN v /\ 20281 (u INTER v = {})``, 20282 REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC std_ss [SEPARATION_HAUSDORFF] THEN 20283 REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN MESON_TAC[]); 20284 20285val SEPARATION_T1 = store_thm ("SEPARATION_T1", 20286 ``!x:real y. 20287 ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ ~(y IN u) /\ 20288 ~(x IN v) /\ y IN v``, 20289 REPEAT STRIP_TAC THEN EQ_TAC THENL 20290 [ASM_SIMP_TAC std_ss [SEPARATION_T2, EXTENSION, NOT_IN_EMPTY, IN_INTER], 20291 ALL_TAC] THEN MESON_TAC[]); 20292 20293val SEPARATION_T0 = store_thm ("SEPARATION_T0", 20294 ``!x:real y. ~(x = y) <=> ?u. open u /\ ~(x IN u <=> y IN u)``, 20295 MESON_TAC[SEPARATION_T1]); 20296 20297(* ------------------------------------------------------------------------- *) 20298(* Connectedness of the intersection of a chain. *) 20299(* ------------------------------------------------------------------------- *) 20300 20301val CONNECTED_CHAIN = store_thm ("CONNECTED_CHAIN", 20302 ``!f:(real->bool)->bool. 20303 (!s. s IN f ==> compact s /\ connected s) /\ 20304 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) 20305 ==> connected(BIGINTER f)``, 20306 REPEAT STRIP_TAC THEN 20307 ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN 20308 ASM_REWRITE_TAC[BIGINTER_EMPTY, CONNECTED_UNIV] THEN 20309 ABBREV_TAC ``c:real->bool = BIGINTER f`` THEN 20310 SUBGOAL_THEN ``compact(c:real->bool)`` ASSUME_TAC THENL 20311 [EXPAND_TAC "c" THEN MATCH_MP_TAC COMPACT_BIGINTER THEN ASM_SET_TAC[], 20312 ALL_TAC] THEN 20313 ASM_SIMP_TAC std_ss [CONNECTED_CLOSED_SET, COMPACT_IMP_CLOSED, NOT_EXISTS_THM] THEN 20314 MAP_EVERY X_GEN_TAC [``a:real->bool``, ``b:real->bool``] THEN CCONTR_TAC THEN 20315 FULL_SIMP_TAC std_ss [] THEN 20316 MP_TAC(ISPECL [``a:real->bool``, ``b:real->bool``] SEPARATION_NORMAL) THEN 20317 ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN 20318 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 20319 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 20320 SUBGOAL_THEN ``?k:real->bool. k IN f`` STRIP_ASSUME_TAC THENL 20321 [ASM_SET_TAC[], ALL_TAC] THEN 20322 SUBGOAL_THEN ``?n:real->bool. open n /\ k SUBSET n`` MP_TAC THENL 20323 [ASM_MESON_TAC[BOUNDED_SUBSET_BALL, COMPACT_IMP_BOUNDED, OPEN_BALL], 20324 REWRITE_TAC[BIGUNION_SUBSET] THEN STRIP_TAC] THEN 20325 MP_TAC(ISPEC ``k:real->bool`` COMPACT_IMP_HEINE_BOREL) THEN 20326 ASM_SIMP_TAC std_ss [] THEN 20327 KNOW_TAC ``~(!(f' :(real -> bool) -> bool). 20328 ((!(t :real -> bool). t IN f' ==> (open t :bool)) /\ 20329 (k :real -> bool) SUBSET BIGUNION f') ==> 20330 ?(f'' :(real -> bool) -> bool). 20331 (f'' SUBSET f') /\ FINITE f'' /\ (k SUBSET BIGUNION f''))`` THENL 20332 [ALL_TAC, METIS_TAC []] THEN DISCH_THEN (MP_TAC o SPEC 20333 ``(u UNION v:real->bool) INSERT {n DIFF s | s IN f}``) THEN 20334 SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_INSERT, FORALL_IN_IMAGE] THEN 20335 ASM_SIMP_TAC std_ss [OPEN_UNION, OPEN_DIFF, COMPACT_IMP_CLOSED, NOT_IMP] THEN 20336 CONJ_TAC THENL 20337 [REWRITE_TAC[BIGUNION_INSERT] THEN REWRITE_TAC[SUBSET_DEF] THEN 20338 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN ONCE_REWRITE_TAC[IN_UNION] THEN 20339 ASM_CASES_TAC ``(x:real) IN c`` THENL [ASM_SET_TAC[], DISJ2_TAC] THEN 20340 SIMP_TAC std_ss [BIGUNION_IMAGE, GSPECIFICATION] THEN 20341 UNDISCH_TAC ``~((x:real) IN c)`` THEN 20342 SUBST1_TAC(SYM(ASSUME ``BIGINTER f:real->bool = c``)) THEN 20343 SIMP_TAC std_ss [IN_BIGINTER, NOT_FORALL_THM] THEN 20344 STRIP_TAC THEN EXISTS_TAC ``P:real->bool`` THEN ASM_SET_TAC[], 20345 ALL_TAC] THEN 20346 X_GEN_TAC ``g:(real->bool)->bool`` THEN 20347 REWRITE_TAC [GSYM DE_MORGAN_THM] THEN 20348 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN 20349 REWRITE_TAC[SUBSET_INSERT_DELETE] THEN 20350 SUBGOAL_THEN ``FINITE(g DELETE (u UNION v:real->bool))`` MP_TAC THENL 20351 [ASM_REWRITE_TAC[FINITE_DELETE], 20352 REWRITE_TAC[TAUT `p ==> ~q <=> ~(p /\ q)`]] THEN 20353 REWRITE_TAC[FINITE_SUBSET_IMAGE] THEN 20354 DISCH_THEN(X_CHOOSE_THEN ``f':(real->bool)->bool`` STRIP_ASSUME_TAC) THEN 20355 SUBGOAL_THEN 20356 ``?j:real->bool. j IN f /\ 20357 BIGUNION(IMAGE (\s. n DIFF s) f') SUBSET (n DIFF j)`` 20358 STRIP_ASSUME_TAC THENL 20359 [ASM_CASES_TAC ``f':(real->bool)->bool = {}`` THEN 20360 ASM_REWRITE_TAC[IMAGE_EMPTY, IMAGE_INSERT, BIGUNION_EMPTY, EMPTY_SUBSET] THENL 20361 [ASM_SET_TAC[], ALL_TAC] THEN 20362 SUBGOAL_THEN 20363 ``?j:real->bool. j IN f' /\ 20364 BIGUNION(IMAGE (\s. n DIFF s) f') SUBSET (n DIFF j)`` 20365 MP_TAC THENL [ALL_TAC, ASM_MESON_TAC[SUBSET_DEF]] THEN 20366 SUBGOAL_THEN 20367 ``!s t:real->bool. s IN f' /\ t IN f' ==> s SUBSET t \/ t SUBSET s`` 20368 MP_TAC THENL [ASM_MESON_TAC[SUBSET_DEF], ALL_TAC] THEN 20369 UNDISCH_TAC ``~(f':(real->bool)->bool = {})`` THEN 20370 UNDISCH_TAC ``FINITE(f':(real->bool)->bool)`` THEN 20371 SPEC_TAC(``f':(real->bool)->bool``,``f':(real->bool)->bool``) THEN 20372 KNOW_TAC ``!(f' :(real -> bool) -> bool). (f' <> {} ==> 20373 (!s t. s IN f' /\ t IN f' ==> s SUBSET t \/ t SUBSET s) ==> 20374 ?j. j IN f' /\ BIGUNION (IMAGE (\s. n DIFF s) f') SUBSET n DIFF j) = 20375 (\f'. f' <> {} ==> 20376 (!s t. s IN f' /\ t IN f' ==> s SUBSET t \/ t SUBSET s) ==> 20377 ?j. j IN f' /\ BIGUNION (IMAGE (\s. n DIFF s) f') SUBSET n DIFF j) f'`` 20378 THENL [METIS_TAC [], DISC_RW_KILL] THEN 20379 MATCH_MP_TAC FINITE_INDUCT THEN SIMP_TAC std_ss [] THEN 20380 SIMP_TAC std_ss [EXISTS_IN_INSERT, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 20381 SIMP_TAC std_ss [FORALL_IN_INSERT] THEN POP_ASSUM_LIST(K ALL_TAC) THEN 20382 SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN 20383 MAP_EVERY X_GEN_TAC [``f:(real->bool)->bool``, ``i:real->bool``] THEN 20384 ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN 20385 ASM_SIMP_TAC std_ss [IMAGE_EMPTY, IMAGE_INSERT, BIGUNION_INSERT, NOT_IN_EMPTY, 20386 BIGUNION_EMPTY, UNION_EMPTY, SUBSET_REFL] THEN 20387 REWRITE_TAC [AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN 20388 REWRITE_TAC [GSYM CONJ_ASSOC] THEN REWRITE_TAC [GSYM AND_IMP_INTRO] THEN 20389 DISCH_THEN(fn th => REPEAT DISCH_TAC THEN MP_TAC th) THEN 20390 KNOW_TAC ``(!(s' :real -> bool) (t :real -> bool). 20391 s' IN (f :(real -> bool) -> bool) ==> t IN f ==> 20392 s' SUBSET t \/ t SUBSET s')`` THENL 20393 [ASM_MESON_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 20394 DISCH_THEN(X_CHOOSE_THEN ``j:real->bool`` STRIP_ASSUME_TAC) THEN 20395 SUBGOAL_THEN ``(n DIFF j) SUBSET (n DIFF i) \/ 20396 (n DIFF i:real->bool) SUBSET (n DIFF j)`` 20397 STRIP_ASSUME_TAC THENL 20398 [ASM_SET_TAC[], 20399 DISJ1_TAC THEN ASM_SET_TAC[], 20400 DISJ2_TAC THEN EXISTS_TAC ``j:real->bool`` THEN ASM_SET_TAC[]], 20401 ALL_TAC] THEN 20402 SUBGOAL_THEN ``(j INTER k:real->bool) SUBSET (u UNION v)`` ASSUME_TAC THENL 20403 [MATCH_MP_TAC(SET_RULE 20404 ``k SUBSET (u UNION v) UNION (n DIFF j) 20405 ==> (j INTER k) SUBSET (u UNION v)``) THEN 20406 MATCH_MP_TAC SUBSET_TRANS THEN 20407 EXISTS_TAC ``BIGUNION g :real->bool`` THEN ASM_SIMP_TAC std_ss [] THEN 20408 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC 20409 ``BIGUNION((u UNION v:real->bool) INSERT (g DELETE (u UNION v)))`` THEN 20410 CONJ_TAC THENL [MATCH_MP_TAC SUBSET_BIGUNION THEN SET_TAC[], ALL_TAC] THEN 20411 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[BIGUNION_INSERT] THEN 20412 ASM_SET_TAC[], 20413 ALL_TAC] THEN 20414 SUBGOAL_THEN ``connected(j INTER k:real->bool)`` MP_TAC THENL 20415 [ASM_MESON_TAC[SET_RULE ``s SUBSET t ==> (s INTER t = s)``, INTER_COMM], 20416 REWRITE_TAC[connected] THEN 20417 MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN 20418 ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]]); 20419 20420val CONNECTED_CHAIN_GEN = store_thm ("CONNECTED_CHAIN_GEN", 20421 ``!f:(real->bool)->bool. 20422 (!s. s IN f ==> closed s /\ connected s) /\ 20423 (?s. s IN f /\ compact s) /\ 20424 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) 20425 ==> connected(BIGINTER f)``, 20426 GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 20427 FIRST_X_ASSUM(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN 20428 SUBGOAL_THEN 20429 ``BIGINTER f = BIGINTER(IMAGE (\t:real->bool. s INTER t) f)`` 20430 SUBST1_TAC THENL 20431 [SIMP_TAC std_ss [EXTENSION, BIGINTER_IMAGE] THEN ASM_SET_TAC[], 20432 MATCH_MP_TAC CONNECTED_CHAIN THEN 20433 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, FORALL_IN_IMAGE] THEN 20434 ASM_SIMP_TAC std_ss [COMPACT_INTER_CLOSED] THEN 20435 CONJ_TAC THENL [X_GEN_TAC ``t:real->bool``, ASM_SET_TAC[]] THEN 20436 DISCH_TAC THEN 20437 SUBGOAL_THEN ``(s INTER t:real->bool = s) \/ (s INTER t = t)`` 20438 (DISJ_CASES_THEN SUBST1_TAC) THEN 20439 ASM_SET_TAC[]]); 20440 20441val CONNECTED_NEST = store_thm ("CONNECTED_NEST", 20442 ``!s. (!n. compact(s n) /\ connected(s n)) /\ 20443 (!m n. m <= n ==> s n SUBSET s m) 20444 ==> connected(BIGINTER {s n | n IN univ(:num)})``, 20445 GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC CONNECTED_CHAIN THEN 20446 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN 20447 ONCE_REWRITE_TAC [METIS [] ``(s n SUBSET s n' \/ s n' SUBSET s n) = 20448 (\n n'. s n SUBSET s n' \/ s n' SUBSET s n) n n'``] THEN 20449 MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]); 20450 20451val CONNECTED_NEST_GEN = store_thm ("CONNECTED_NEST_GEN", 20452 ``!s. (!n. closed(s n) /\ connected(s n)) /\ (?n. compact(s n)) /\ 20453 (!m n. m <= n ==> s n SUBSET s m) 20454 ==> connected(BIGINTER {s n | n IN univ(:num)})``, 20455 GEN_TAC THEN 20456 DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN 20457 MATCH_MP_TAC CONNECTED_CHAIN_GEN THEN 20458 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, 20459 EXISTS_IN_GSPEC] THEN 20460 ONCE_REWRITE_TAC [METIS [] ``(s n SUBSET s n' \/ s n' SUBSET s n) = 20461 (\n n'. s n SUBSET s n' \/ s n' SUBSET s n) n n'``] THEN 20462 MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]); 20463 20464(* ------------------------------------------------------------------------- *) 20465(* Hausdorff distance between sets. *) 20466(* ------------------------------------------------------------------------- *) 20467 20468val hausdist = new_definition ("hausdist", 20469 ``hausdist(s:real->bool,t:real->bool) = 20470 if (({setdist({x},t) | x IN s} UNION {setdist({y},s) | y IN t} <> {}) /\ 20471 (?b. !d. d IN {setdist({x},t) | x IN s} UNION {setdist({y},s) | y IN t} ==> d <= b)) 20472 then sup ({setdist({x},t) | x IN s} UNION {setdist({y},s) | y IN t}) else &0``); 20473 20474val HAUSDIST_POS_LE = store_thm ("HAUSDIST_POS_LE", 20475 ``!s t:real->bool. &0 <= hausdist(s,t)``, 20476 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN 20477 SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION] THEN 20478 COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN 20479 MATCH_MP_TAC REAL_LE_SUP THEN 20480 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION, SETDIST_POS_LE] THEN 20481 KNOW_TAC ``?(y :real) (b :real). 20482 y IN {setdist ({x},(t :real -> bool)) | x IN (s :real -> bool)} UNION 20483 {setdist ({y},s) | y IN t} /\ (0 :real) <= y /\ 20484 (!(x :real). x IN s ==> setdist ({x},t) <= b) /\ 20485 !(y :real). y IN t ==> setdist ({y},s) <= b`` THENL 20486 [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN 20487 ASM_SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM] THEN 20488 ONCE_REWRITE_TAC [METIS [] ``(0 <= y:real) = (\y. 0 <= y) y``] THEN 20489 MATCH_MP_TAC(SET_RULE 20490 ``~(s = {}) /\ (!x. x IN s ==> P x) ==> ?y. y IN s /\ P y``) THEN 20491 ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION, SETDIST_POS_LE]); 20492 20493val HAUSDIST_REFL = store_thm ("HAUSDIST_REFL", 20494 ``!s:real->bool. hausdist(s,s) = &0``, 20495 GEN_TAC THEN SIMP_TAC std_ss [GSYM REAL_LE_ANTISYM, HAUSDIST_POS_LE] THEN 20496 REWRITE_TAC[hausdist] THEN 20497 COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN 20498 MATCH_MP_TAC REAL_SUP_LE_S THEN 20499 SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION] THEN 20500 ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, REAL_LE_REFL]); 20501 20502val HAUSDIST_SYM = store_thm ("HAUSDIST_SYM", 20503 ``!s t:real->bool. hausdist(s,t) = hausdist(t,s)``, 20504 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN 20505 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [UNION_COMM] THEN 20506 REWRITE_TAC[]); 20507 20508val HAUSDIST_EMPTY = store_thm ("HAUSDIST_EMPTY", 20509 ``(!t:real->bool. hausdist ({},t) = &0) /\ 20510 (!s:real->bool. hausdist (s,{}) = &0)``, 20511 REWRITE_TAC[hausdist, SETDIST_EMPTY] THEN 20512 REWRITE_TAC[SET_RULE ``{setdist ({x},t) | x IN {}} = {}``, UNION_EMPTY] THEN 20513 REWRITE_TAC[SET_RULE ``({c |x| x IN s} = {}) <=> (s = {})``] THEN 20514 X_GEN_TAC ``s:real->bool`` THEN 20515 ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[] THEN 20516 ASM_SIMP_TAC std_ss [SET_RULE ``~(s = {}) ==> ({c |x| x IN s} = {c})``] THEN 20517 REWRITE_TAC[SUP_SING, COND_ID]); 20518 20519val HAUSDIST_SINGS = store_thm ("HAUSDIST_SINGS", 20520 ``!x y:real. hausdist({x},{y}) = dist(x,y)``, 20521 REWRITE_TAC[hausdist, SETDIST_SINGS] THEN 20522 REWRITE_TAC[SET_RULE ``{dist (x,y) | x IN {a}} = {dist (a,y)}``] THEN 20523 ONCE_REWRITE_TAC [METIS [DIST_SYM] ``{dist (x,y)} UNION {dist (y,x)} = 20524 {dist (x,y)} UNION {dist (x,y)}``] THEN 20525 SIMP_TAC std_ss [UNION_IDEMPOT, SUP_SING, NOT_INSERT_EMPTY] THEN 20526 SIMP_TAC std_ss [IN_SING, UNWIND_FORALL_THM2] THEN 20527 METIS_TAC[REAL_LE_REFL]); 20528 20529val HAUSDIST_EQ = store_thm ("HAUSDIST_EQ", 20530 ``!s t:real->bool s' t':real->bool. 20531 (!b. (!x. x IN s ==> setdist({x},t) <= b) /\ 20532 (!y. y IN t ==> setdist({y},s) <= b) <=> 20533 (!x. x IN s' ==> setdist({x},t') <= b) /\ 20534 (!y. y IN t' ==> setdist({y},s') <= b)) 20535 ==> (hausdist(s,t) = hausdist(s',t'))``, 20536 REPEAT STRIP_TAC THEN REWRITE_TAC[hausdist] THEN 20537 MATCH_MP_TAC(METIS[] 20538 ``(p <=> p') /\ (s = s') 20539 ==> ((if p then s else &0:real) = (if p' then s' else &0:real))``) THEN 20540 CONJ_TAC THENL 20541 [BINOP_TAC THENL 20542 [PURE_REWRITE_TAC[SET_RULE ``(s = {}) <=> !x. x IN s ==> F``], 20543 AP_TERM_TAC THEN ABS_TAC], 20544 MATCH_MP_TAC SUP_EQ] THEN 20545 SIMP_TAC std_ss [FORALL_IN_UNION, FORALL_IN_GSPEC] THEN 20546 ASM_REWRITE_TAC[] THEN 20547 ONCE_REWRITE_TAC [METIS [] ``(a = b) = (~a = ~b:bool)``] THEN 20548 REWRITE_TAC [DE_MORGAN_THM] THEN 20549 SIMP_TAC std_ss [NOT_FORALL_THM, MEMBER_NOT_EMPTY] THEN 20550 REWRITE_TAC[GSYM DE_MORGAN_THM] THEN AP_TERM_TAC THEN EQ_TAC THEN 20551 DISCH_THEN(fn th => POP_ASSUM MP_TAC THEN ASSUME_TAC th) THEN 20552 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN 20553 DISCH_THEN(MP_TAC o SPEC ``-(&1):real``) THEN 20554 SIMP_TAC std_ss [SETDIST_POS_LE, REAL_ARITH ``&0 <= x ==> ~(x <= -(&1:real))``] THEN 20555 SET_TAC[]); 20556 20557val HAUSDIST_TRANSLATION = store_thm ("HAUSDIST_TRANSLATION", 20558 ``!a s t:real->bool. 20559 hausdist(IMAGE (\x. a + x) s,IMAGE (\x. a + x) t) = hausdist(s,t)``, 20560 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN 20561 SIMP_TAC real_ss [SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN 20562 SIMP_TAC real_ss [SET_RULE ``{a + x:real} = IMAGE (\x. a + x) {x}``] THEN 20563 REWRITE_TAC[SETDIST_TRANSLATION]); 20564 20565val HAUSDIST_LINEAR_IMAGE = store_thm ("HAUSDIST_LINEAR_IMAGE", 20566 ``!f:real->real s t. 20567 linear f /\ (!x. abs(f x) = abs x) 20568 ==> (hausdist(IMAGE f s,IMAGE f t) = hausdist(s,t))``, 20569 REPEAT STRIP_TAC THEN 20570 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN 20571 SIMP_TAC real_ss [SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN 20572 ONCE_REWRITE_TAC[SET_RULE ``{(f:real->real) x} = IMAGE f {x}``] THEN 20573 ASM_SIMP_TAC std_ss [SETDIST_LINEAR_IMAGE]); 20574 20575val HAUSDIST_CLOSURE = store_thm ("HAUSDIST_CLOSURE", 20576 ``(!s t:real->bool. hausdist(closure s,t) = hausdist(s,t)) /\ 20577 (!s t:real->bool. hausdist(s,closure t) = hausdist(s,t))``, 20578 REPEAT STRIP_TAC THEN MATCH_MP_TAC HAUSDIST_EQ THEN 20579 GEN_TAC THEN BINOP_TAC THEN REWRITE_TAC[SETDIST_CLOSURE] THEN 20580 ONCE_REWRITE_TAC [METIS [] ``setdist ({x},t) <= b = (\x. setdist ({x},t) <= b) x``] THEN 20581 PURE_ONCE_REWRITE_TAC[SET_RULE 20582 ``(!x. x IN P ==> Q x) <=> (!x. x IN P ==> (\x. x) x IN {x | Q x})``] THEN 20583 MATCH_MP_TAC FORALL_IN_CLOSURE_EQ THEN 20584 SIMP_TAC std_ss [GSPEC_F, CONTINUOUS_ON_ID, CLOSED_EMPTY] THEN 20585 ONCE_REWRITE_TAC [METIS [] ``setdist ({x},t) = (\x. setdist ({x},t)) x``] THEN 20586 REWRITE_TAC[SET_RULE 20587 ``{x | (f x) <= b:real} = 20588 {x | x IN UNIV /\ (f x) IN {x | x <= b}}``] THEN 20589 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN 20590 SIMP_TAC std_ss [CLOSED_UNIV, CONTINUOUS_ON_SETDIST] THEN 20591 REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE]); 20592 20593val REAL_HAUSDIST_LE = store_thm ("REAL_HAUSDIST_LE", 20594 ``!s t:real->bool b. 20595 ~(s = {}) /\ ~(t = {}) /\ 20596 (!x. x IN s ==> setdist({x},t) <= b) /\ 20597 (!y. y IN t ==> setdist({y},s) <= b) 20598 ==> hausdist(s,t) <= b``, 20599 REPEAT STRIP_TAC THEN 20600 REWRITE_TAC[hausdist, SETDIST_SINGS] THEN 20601 ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN 20602 SIMP_TAC std_ss [FORALL_IN_UNION, FORALL_IN_GSPEC] THEN 20603 COND_CASES_TAC THENL [ALL_TAC, METIS_TAC[]] THEN 20604 MATCH_MP_TAC REAL_SUP_LE_S THEN 20605 ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN 20606 ASM_SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC]); 20607 20608val REAL_HAUSDIST_LE_SUMS = store_thm ("REAL_HAUSDIST_LE_SUMS", 20609 ``!s t:real->bool b. 20610 ~(s = {}) /\ ~(t = {}) /\ 20611 s SUBSET {y + z | y IN t /\ z IN cball(0,b)} /\ 20612 t SUBSET {y + z | y IN s /\ z IN cball(0,b)} 20613 ==> hausdist(s,t) <= b``, 20614 SIMP_TAC real_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD, IN_CBALL_0] THEN 20615 SIMP_TAC real_ss [REAL_ARITH ``(a:real = b + x) <=> (a - b = x)``, 20616 ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN 20617 REWRITE_TAC[GSYM dist] THEN REPEAT STRIP_TAC THEN 20618 MATCH_MP_TAC REAL_HAUSDIST_LE THEN 20619 METIS_TAC[SETDIST_LE_DIST, REAL_LE_TRANS, IN_SING]); 20620 20621val REAL_LE_HAUSDIST = store_thm ("REAL_LE_HAUSDIST", 20622 ``!s t:real->bool a b c z. 20623 ~(s = {}) /\ ~(t = {}) /\ 20624 (!x. x IN s ==> setdist({x},t) <= b) /\ 20625 (!y. y IN t ==> setdist({y},s) <= c) /\ 20626 (z IN s /\ a <= setdist({z},t) \/ z IN t /\ a <= setdist({z},s)) 20627 ==> a <= hausdist(s,t)``, 20628 REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN 20629 REWRITE_TAC[hausdist, SETDIST_SINGS] THEN 20630 ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN 20631 SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC] THEN COND_CASES_TAC THENL 20632 [MATCH_MP_TAC REAL_LE_SUP THEN 20633 ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN 20634 SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC], 20635 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [NOT_EXISTS_THM]) THEN 20636 ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 20637 SIMP_TAC real_ss [NOT_FORALL_THM]] THEN 20638 EXISTS_TAC ``max b c:real`` THEN 20639 ASM_SIMP_TAC real_ss [REAL_LE_MAX] THEN ASM_SET_TAC[]); 20640 20641val SETDIST_LE_HAUSDIST = store_thm ("SETDIST_LE_HAUSDIST", 20642 ``!s t:real->bool. 20643 bounded s /\ bounded t ==> setdist(s,t) <= hausdist(s,t)``, 20644 REPEAT STRIP_TAC THEN 20645 ASM_CASES_TAC ``s:real->bool = {}`` THEN 20646 ASM_SIMP_TAC real_ss [SETDIST_EMPTY, HAUSDIST_EMPTY, REAL_LE_REFL] THEN 20647 ASM_CASES_TAC ``t:real->bool = {}`` THEN 20648 ASM_SIMP_TAC real_ss [SETDIST_EMPTY, HAUSDIST_EMPTY, REAL_LE_REFL] THEN 20649 MATCH_MP_TAC REAL_LE_HAUSDIST THEN REWRITE_TAC[CONJ_ASSOC] THEN 20650 ASM_SIMP_TAC real_ss [RIGHT_EXISTS_AND_THM, LEFT_EXISTS_AND_THM] THEN 20651 CONJ_TAC THENL 20652 [ALL_TAC, METIS_TAC[SETDIST_LE_SING, MEMBER_NOT_EMPTY]] THEN 20653 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20654 ASM_REWRITE_TAC[] THEN SIMP_TAC real_ss [bounded_def, FORALL_IN_GSPEC, GSYM dist] THEN 20655 DISCH_THEN(X_CHOOSE_TAC ``b:real``) THEN 20656 CONJ_TAC THEN EXISTS_TAC ``b:real`` THEN REPEAT STRIP_TAC THEN 20657 METIS_TAC[REAL_LE_TRANS, SETDIST_LE_DIST, MEMBER_NOT_EMPTY, IN_SING, DIST_SYM]); 20658 20659val SETDIST_SING_LE_HAUSDIST = store_thm ("SETDIST_SING_LE_HAUSDIST", 20660 ``!s t x:real. 20661 bounded s /\ bounded t /\ x IN s ==> setdist({x},t) <= hausdist(s,t)``, 20662 REPEAT GEN_TAC THEN 20663 ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN 20664 ASM_CASES_TAC ``t:real->bool = {}`` THEN 20665 ASM_REWRITE_TAC[SETDIST_EMPTY, HAUSDIST_EMPTY, REAL_LE_REFL] THEN 20666 STRIP_TAC THEN MATCH_MP_TAC REAL_LE_HAUSDIST THEN 20667 ASM_SIMP_TAC real_ss [RIGHT_EXISTS_AND_THM] THEN 20668 SIMP_TAC real_ss [LEFT_EXISTS_AND_THM, EXISTS_OR_THM, CONJ_ASSOC] THEN 20669 CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[REAL_LE_REFL]] THEN CONJ_TAC THEN 20670 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20671 ASM_REWRITE_TAC[] THEN SIMP_TAC real_ss [bounded_def, FORALL_IN_GSPEC] THEN 20672 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 20673 POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM dist] THENL 20674 [ALL_TAC, 20675 KNOW_TAC ``(!y x:real. x IN s /\ y IN t ==> dist (x,y) <= a) ==> 20676 !y. y IN t ==> setdist ({y},s) <= a`` THENL 20677 [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]]] THEN 20678 DISCH_TAC THEN X_GEN_TAC ``y:real`` THEN POP_ASSUM (MP_TAC o SPEC ``y:real``) THEN 20679 REPEAT STRIP_TAC THENL 20680 [UNDISCH_TAC ``~(t:real->bool = {})``, 20681 UNDISCH_TAC ``~(s:real->bool = {})``] THEN 20682 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN 20683 DISCH_THEN(X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN 20684 FIRST_X_ASSUM(MP_TAC o SPEC ``z:real``) THEN ASM_REWRITE_TAC[] THEN 20685 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] REAL_LE_TRANS) THENL 20686 [ALL_TAC, ONCE_REWRITE_TAC[DIST_SYM]] THEN 20687 MATCH_MP_TAC SETDIST_LE_DIST THEN ASM_REWRITE_TAC[IN_SING]); 20688 20689val SETDIST_HAUSDIST_TRIANGLE = store_thm ("SETDIST_HAUSDIST_TRIANGLE", 20690 ``!s t u:real->bool. 20691 ~(t = {}) /\ bounded t /\ bounded u 20692 ==> setdist(s,u) <= setdist(s,t) + hausdist(t,u)``, 20693 REPEAT STRIP_TAC THEN 20694 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``u:real->bool = {}``] THEN 20695 ASM_SIMP_TAC real_ss [SETDIST_EMPTY, REAL_LE_ADD, REAL_ADD_LID, 20696 SETDIST_POS_LE, HAUSDIST_POS_LE] THEN 20697 ONCE_REWRITE_TAC[REAL_ARITH ``a <= b + c <=> a - c <= b:real``] THEN 20698 ASM_SIMP_TAC real_ss [REAL_LE_SETDIST_EQ, NOT_INSERT_EMPTY, IN_SING] THEN 20699 MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN 20700 REWRITE_TAC[REAL_LE_SUB_RADD] THEN 20701 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``setdist({x:real},u)`` THEN 20702 ASM_SIMP_TAC real_ss [SETDIST_LE_SING] THEN 20703 MP_TAC(ISPECL [``u:real->bool``, ``x:real``, ``y:real``] 20704 SETDIST_SING_TRIANGLE) THEN 20705 MATCH_MP_TAC(REAL_ARITH 20706 ``yu <= z ==> abs(xu - yu) <= d ==> xu <= d + z:real``) THEN 20707 MATCH_MP_TAC SETDIST_SING_LE_HAUSDIST THEN ASM_REWRITE_TAC[]); 20708 20709val HAUSDIST_SETDIST_TRIANGLE = store_thm ("HAUSDIST_SETDIST_TRIANGLE", 20710 ``!s t u:real->bool. 20711 ~(t = {}) /\ bounded s /\ bounded t 20712 ==> setdist(s,u) <= hausdist(s,t) + setdist(t,u)``, 20713 ONCE_REWRITE_TAC[SETDIST_SYM, HAUSDIST_SYM] THEN 20714 ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN 20715 SIMP_TAC real_ss [SETDIST_HAUSDIST_TRIANGLE]); 20716 20717val REAL_LT_HAUSDIST_POINT_EXISTS = store_thm ("REAL_LT_HAUSDIST_POINT_EXISTS", 20718 ``!s t x:real d. 20719 bounded s /\ bounded t /\ ~(t = {}) /\ hausdist(s,t) < d /\ x IN s 20720 ==> ?y. y IN t /\ dist(x,y) < d``, 20721 REPEAT STRIP_TAC THEN 20722 MP_TAC(ISPECL [``{x:real}``, ``t:real->bool``, ``d:real``] 20723 REAL_SETDIST_LT_EXISTS) THEN 20724 SIMP_TAC real_ss [IN_SING, RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN 20725 DISCH_THEN MATCH_MP_TAC THEN 20726 ASM_REWRITE_TAC[NOT_INSERT_EMPTY] THEN 20727 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``hausdist(s:real->bool,t)`` THEN 20728 ASM_SIMP_TAC real_ss [] THEN MATCH_MP_TAC SETDIST_SING_LE_HAUSDIST THEN 20729 ASM_REWRITE_TAC[]); 20730 20731val UPPER_LOWER_HEMICONTINUOUS = store_thm ("UPPER_LOWER_HEMICONTINUOUS", 20732 ``!f:real->real->bool t s. 20733 (!x. x IN s ==> f(x) SUBSET t) /\ 20734 (!u. open_in (subtopology euclidean t) u 20735 ==> open_in (subtopology euclidean s) 20736 {x | x IN s /\ f(x) SUBSET u}) /\ 20737 (!u. closed_in (subtopology euclidean t) u 20738 ==> closed_in (subtopology euclidean s) 20739 {x | x IN s /\ f(x) SUBSET u}) 20740 ==> !x e. x IN s /\ &0 < e /\ bounded(f x) 20741 ==> ?d. &0 < d /\ 20742 !x'. x' IN s /\ dist(x,x') < d 20743 ==> hausdist(f x,f x') < e``, 20744 REPEAT GEN_TAC THEN DISCH_TAC THEN REPEAT STRIP_TAC THEN 20745 ASM_CASES_TAC ``(f:real->real->bool) x = {}`` THENL 20746 [ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN METIS_TAC[REAL_LT_01], ALL_TAC] THEN 20747 FIRST_ASSUM(MP_TAC o SPECL [``x:real``, ``e / &2:real``] o MATCH_MP 20748 UPPER_LOWER_HEMICONTINUOUS_EXPLICIT) THEN 20749 ASM_REWRITE_TAC[REAL_HALF] THEN 20750 DISCH_THEN(X_CHOOSE_THEN ``d1:real`` STRIP_ASSUME_TAC) THEN 20751 FIRST_ASSUM(MP_TAC o SPEC ``0:real`` o MATCH_MP BOUNDED_SUBSET_BALL) THEN 20752 DISCH_THEN(X_CHOOSE_THEN ``r:real`` STRIP_ASSUME_TAC) THEN 20753 FIRST_ASSUM(MP_TAC o SPEC ``t INTER ball(0:real,r)`` o 20754 CONJUNCT1 o CONJUNCT2) THEN 20755 SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN REWRITE_TAC[open_in] THEN 20756 DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN 20757 ASM_SIMP_TAC std_ss [SUBSET_INTER, GSPECIFICATION] THEN 20758 DISCH_THEN(X_CHOOSE_THEN ``d2:real`` STRIP_ASSUME_TAC) THEN 20759 EXISTS_TAC ``min d1 d2:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 20760 X_GEN_TAC ``x':real`` THEN STRIP_TAC THEN 20761 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC ``x':real``)) THEN 20762 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN ASM_SIMP_TAC std_ss [] THEN 20763 STRIP_TAC THEN STRIP_TAC THEN 20764 ASM_CASES_TAC ``(f:real->real->bool) x' = {}`` THEN 20765 ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN 20766 KNOW_TAC ``0 < e / 2:real`` THENL [ASM_REWRITE_TAC [REAL_HALF], DISCH_TAC] THEN 20767 GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN 20768 MATCH_MP_TAC(REAL_ARITH ``&0 < e / 2 /\ x <= e / &2 ==> x < e / 2 + e / 2:real``) THEN 20769 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_HAUSDIST_LE THEN 20770 METIS_TAC[SETDIST_LE_DIST, DIST_SYM, REAL_LE_TRANS, 20771 IN_SING, REAL_LT_IMP_LE]); 20772 20773val HAUSDIST_NONTRIVIAL = store_thm ("HAUSDIST_NONTRIVIAL", 20774 ``!s t:real->bool. 20775 bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {}) 20776 ==> (hausdist(s,t) = 20777 sup({setdist ({x},t) | x IN s} UNION {setdist ({y},s) | y IN t}))``, 20778 REPEAT STRIP_TAC THEN REWRITE_TAC[hausdist] THEN 20779 COND_CASES_TAC THEN ASM_SIMP_TAC real_ss [] THEN 20780 FIRST_X_ASSUM(MP_TAC o SIMP_RULE real_ss [DE_MORGAN_THM]) THEN 20781 ASM_SIMP_TAC real_ss [EMPTY_UNION, GSYM IMAGE_DEF, IMAGE_EQ_EMPTY] THEN 20782 REWRITE_TAC [METIS [] ``(!b. ?d. d IN P /\ ~(d <= b)) = 20783 ~(?b. !d. d IN P ==> d <= b:real)``] THEN 20784 MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN 20785 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20786 ASM_SIMP_TAC real_ss [bounded_def, FORALL_IN_UNION, FORALL_IN_IMAGE, GSYM dist] THEN 20787 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN POP_ASSUM MP_TAC THEN 20788 SIMP_TAC real_ss [FORALL_IN_GSPEC] THEN 20789 METIS_TAC[SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS, 20790 MEMBER_NOT_EMPTY, IN_SING]); 20791 20792val HAUSDIST_NONTRIVIAL_ALT = store_thm ("HAUSDIST_NONTRIVIAL_ALT", 20793 ``!s t:real->bool. 20794 bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {}) 20795 ==> (hausdist(s,t) = max (sup {setdist ({x},t) | x IN s}) 20796 (sup {setdist ({y},s) | y IN t}))``, 20797 REPEAT STRIP_TAC THEN ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL] THEN 20798 MATCH_MP_TAC SUP_UNION THEN 20799 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, IMAGE_EQ_EMPTY] THEN 20800 CONJ_TAC THEN 20801 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20802 ASM_SIMP_TAC real_ss [bounded_def, FORALL_IN_UNION, FORALL_IN_IMAGE, GSYM dist] THEN 20803 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 20804 POP_ASSUM MP_TAC THEN SIMP_TAC real_ss [FORALL_IN_GSPEC, GSYM dist] THEN 20805 METIS_TAC [SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS, 20806 MEMBER_NOT_EMPTY, IN_SING]); 20807 20808val REAL_HAUSDIST_LE_EQ = store_thm ("REAL_HAUSDIST_LE_EQ", 20809 ``!s t:real->bool b. 20810 ~(s = {}) /\ ~(t = {}) /\ bounded s /\ bounded t 20811 ==> (hausdist(s,t) <= b <=> 20812 (!x. x IN s ==> setdist({x},t) <= b) /\ 20813 (!y. y IN t ==> setdist({y},s) <= b))``, 20814 REPEAT STRIP_TAC THEN 20815 ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL_ALT, REAL_MAX_LE] THEN 20816 BINOP_TAC THEN 20817 ONCE_REWRITE_TAC [METIS [] ``setdist ({x},t) = (\x. setdist ({x},t)) x:real``] THEN 20818 ONCE_REWRITE_TAC [SET_RULE ``(!x. x IN s ==> f x <= b) <=> 20819 (!y. y IN {f x | x IN s} ==> y <= b:real)``] THEN 20820 MATCH_MP_TAC REAL_SUP_LE_EQ THEN 20821 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, IMAGE_EQ_EMPTY, FORALL_IN_IMAGE] THEN 20822 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20823 ASM_SIMP_TAC real_ss [bounded_def, FORALL_IN_UNION, FORALL_IN_IMAGE, GSYM dist] THEN 20824 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 20825 POP_ASSUM MP_TAC THEN SIMP_TAC real_ss [FORALL_IN_GSPEC, GSYM dist] THEN 20826 METIS_TAC[SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS, 20827 MEMBER_NOT_EMPTY, IN_SING]); 20828 20829val HAUSDIST_UNION_LE = store_thm ("HAUSDIST_UNION_LE", 20830 ``!s t u:real->bool. 20831 bounded s /\ bounded t /\ bounded u /\ ~(t = {}) /\ ~(u = {}) 20832 ==> hausdist(s UNION t,s UNION u) <= hausdist(t,u)``, 20833 REPEAT STRIP_TAC THEN 20834 ASM_SIMP_TAC real_ss [REAL_HAUSDIST_LE_EQ, BOUNDED_UNION, EMPTY_UNION] THEN 20835 SIMP_TAC real_ss [FORALL_IN_UNION] THEN 20836 SIMP_TAC real_ss [SETDIST_SING_IN_SET, IN_UNION, HAUSDIST_POS_LE] THEN 20837 ASM_SIMP_TAC real_ss [GSYM REAL_HAUSDIST_LE_EQ, BOUNDED_UNION, EMPTY_UNION] THEN 20838 CONJ_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THENL 20839 [MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``setdist({x:real},u)``, 20840 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``setdist({x:real},t)``] THEN 20841 ASM_SIMP_TAC real_ss [SETDIST_SUBSET_RIGHT, SUBSET_UNION] THENL 20842 [ALL_TAC, ONCE_REWRITE_TAC[HAUSDIST_SYM]] THEN 20843 MATCH_MP_TAC SETDIST_SING_LE_HAUSDIST THEN ASM_REWRITE_TAC[]); 20844 20845val HAUSDIST_INSERT_LE = store_thm ("HAUSDIST_INSERT_LE", 20846 ``!s t a:real. 20847 bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {}) 20848 ==> hausdist(a INSERT s,a INSERT t) <= hausdist(s,t)``, 20849 ONCE_REWRITE_TAC[SET_RULE ``a INSERT s = {a} UNION s``] THEN 20850 ASM_SIMP_TAC real_ss [HAUSDIST_UNION_LE, NOT_INSERT_EMPTY, BOUNDED_SING]); 20851 20852val HAUSDIST_COMPACT_EXISTS = store_thm ("HAUSDIST_COMPACT_EXISTS", 20853 ``!s t:real->bool. 20854 bounded s /\ compact t /\ ~(t = {}) 20855 ==> !x. x IN s ==> ?y. y IN t /\ dist(x,y) <= hausdist(s,t)``, 20856 REPEAT STRIP_TAC THEN 20857 ASM_CASES_TAC ``s:real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN 20858 MP_TAC(ISPECL [``{x:real}``, ``t:real->bool``] 20859 SETDIST_COMPACT_CLOSED) THEN 20860 ASM_SIMP_TAC real_ss [COMPACT_SING, COMPACT_IMP_CLOSED, NOT_INSERT_EMPTY] THEN 20861 SIMP_TAC real_ss [IN_SING, UNWIND_THM2, RIGHT_EXISTS_AND_THM, UNWIND_THM1] THEN 20862 DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN POP_ASSUM MP_TAC THEN 20863 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 20864 MATCH_MP_TAC REAL_LE_HAUSDIST THEN 20865 ASM_SIMP_TAC real_ss [LEFT_EXISTS_AND_THM, RIGHT_EXISTS_AND_THM] THEN 20866 REWRITE_TAC[CONJ_ASSOC] THEN 20867 CONJ_TAC THENL [CONJ_TAC, METIS_TAC[REAL_LE_REFL]] THEN 20868 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN 20869 ASM_SIMP_TAC real_ss [COMPACT_IMP_BOUNDED] THEN 20870 SIMP_TAC real_ss [bounded_def, FORALL_IN_GSPEC, GSYM dist] THEN 20871 DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN 20872 METIS_TAC[SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS, 20873 MEMBER_NOT_EMPTY, IN_SING]); 20874 20875val HAUSDIST_TRIANGLE = store_thm ("HAUSDIST_TRIANGLE", 20876 ``!s t u:real->bool. 20877 bounded s /\ bounded t /\ bounded u /\ ~(t = {}) 20878 ==> hausdist(s,u) <= hausdist(s,t) + hausdist(t,u)``, 20879 ONCE_REWRITE_TAC[GSYM(CONJUNCT1 HAUSDIST_CLOSURE)] THEN 20880 ONCE_REWRITE_TAC[GSYM(CONJUNCT2 HAUSDIST_CLOSURE)] THEN 20881 ONCE_REWRITE_TAC[GSYM COMPACT_CLOSURE, GSYM CLOSURE_EQ_EMPTY] THEN 20882 REPEAT GEN_TAC THEN MAP_EVERY 20883 (fn t => SPEC_TAC(mk_comb(``closure:(real->bool)->real->bool``,t),t)) 20884 [``u:real->bool``, ``t:real->bool``, ``s:real->bool``] THEN 20885 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN 20886 ASM_REWRITE_TAC[HAUSDIST_EMPTY, HAUSDIST_POS_LE, REAL_ADD_LID] THEN 20887 ASM_CASES_TAC ``u:real->bool = {}`` THEN 20888 ASM_REWRITE_TAC[HAUSDIST_EMPTY, HAUSDIST_POS_LE, REAL_ADD_RID] THEN 20889 ASM_SIMP_TAC real_ss [REAL_HAUSDIST_LE_EQ, COMPACT_IMP_BOUNDED] THEN 20890 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [HAUSDIST_SYM] THEN 20891 GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [REAL_ADD_SYM] THEN 20892 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN 20893 MAP_EVERY (fn t => SPEC_TAC(t,t)) 20894 [``u:real->bool``, ``t:real->bool``, ``s:real->bool``] THEN 20895 ONCE_REWRITE_TAC [METIS [] ``(~(u = {}) /\ ~(s = {}) /\ ~(t = {}) /\ 20896 compact u /\ compact t /\ compact s) = 20897 (\s t u. ~(u = {}) /\ ~(s = {}) /\ ~(t = {}) /\ 20898 compact u /\ compact t /\ compact s) s t u``] THEN 20899 ONCE_REWRITE_TAC [METIS [] ``(!x. x IN s ==> setdist ({x},u) <= 20900 hausdist (s,t) + hausdist (t,u)) = 20901 (\s t u. !x. x IN s ==> setdist ({x},u) <= 20902 hausdist (s,t) + hausdist (t,u)) s t u ``] THEN 20903 MATCH_MP_TAC(METIS[] 20904 ``(!s t u. P s t u ==> P u t s) /\ 20905 (!s t u. P s t u ==> Q s t u) 20906 ==> (!s t u. P s t u ==> Q s t u /\ Q u t s)``) THEN BETA_TAC THEN 20907 CONJ_TAC THENL [METIS_TAC[CONJ_ACI], REPEAT GEN_TAC THEN STRIP_TAC] THEN 20908 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 20909 SUBGOAL_THEN ``?y:real. y IN t /\ dist(x,y) <= hausdist(s,t)`` 20910 STRIP_ASSUME_TAC THENL 20911 [METIS_TAC[HAUSDIST_COMPACT_EXISTS, COMPACT_IMP_BOUNDED], ALL_TAC] THEN 20912 SUBGOAL_THEN ``?z:real. z IN u /\ dist(y,z) <= hausdist(t,u)`` 20913 STRIP_ASSUME_TAC THENL 20914 [METIS_TAC[HAUSDIST_COMPACT_EXISTS, COMPACT_IMP_BOUNDED], ALL_TAC] THEN 20915 RULE_ASSUM_TAC (REWRITE_RULE [dist]) THEN 20916 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH 20917 ``abs(y - z) <= b ==> abs(x - y) <= a /\ s <= abs(x - z) ==> s <= a + b:real``)) THEN 20918 ASM_REWRITE_TAC[GSYM dist] THEN MATCH_MP_TAC SETDIST_LE_DIST THEN 20919 ASM_REWRITE_TAC[IN_SING]); 20920 20921val HAUSDIST_COMPACT_SUMS = store_thm ("HAUSDIST_COMPACT_SUMS", 20922 ``!s t:real->bool. 20923 bounded s /\ compact t /\ ~(t = {}) 20924 ==> s SUBSET {y + z | y IN t /\ z IN cball(0,hausdist(s,t))}``, 20925 SIMP_TAC real_ss [SUBSET_DEF, GSPECIFICATION, IN_CBALL_0, EXISTS_PROD] THEN 20926 SIMP_TAC real_ss [REAL_ARITH ``(a:real = b + x) <=> (a - b = x)``, 20927 ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN 20928 SIMP_TAC real_ss [GSYM dist, HAUSDIST_COMPACT_EXISTS]); 20929 20930val lemma = prove ( 20931 ``!s t u:real->bool. 20932 bounded s /\ bounded t /\ bounded u /\ 20933 ~(s = {}) /\ ~(t = {}) /\ ~(u = {}) 20934 ==> !x. x IN s ==> setdist({x},u) <= hausdist(s,t) + hausdist(t,u)``, 20935 REPEAT STRIP_TAC THEN 20936 MP_TAC(ISPECL [``closure s:real->bool``, ``closure t:real->bool``] 20937 HAUSDIST_COMPACT_EXISTS) THEN 20938 ASM_SIMP_TAC real_ss [COMPACT_CLOSURE, BOUNDED_CLOSURE, CLOSURE_EQ_EMPTY] THEN 20939 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 20940 ASM_SIMP_TAC real_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET, HAUSDIST_CLOSURE] THEN 20941 DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN 20942 MP_TAC(ISPECL [``closure t:real->bool``, ``closure u:real->bool``] 20943 HAUSDIST_COMPACT_EXISTS) THEN 20944 ASM_SIMP_TAC real_ss [COMPACT_CLOSURE, BOUNDED_CLOSURE, CLOSURE_EQ_EMPTY] THEN 20945 DISCH_THEN(MP_TAC o SPEC ``y:real``) THEN 20946 ASM_SIMP_TAC real_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET, HAUSDIST_CLOSURE] THEN 20947 DISCH_THEN(X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN 20948 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(x:real,z)`` THEN CONJ_TAC THENL 20949 [METIS_TAC[SETDIST_CLOSURE, SETDIST_LE_DIST, IN_SING], ALL_TAC] THEN 20950 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(x:real,y) + dist(y,z)`` THEN 20951 REWRITE_TAC[DIST_TRIANGLE] THEN ASM_REAL_ARITH_TAC); 20952 20953val HAUSDIST_TRANS = store_thm ("HAUSDIST_TRANS", 20954 ``!s t u:real->bool. 20955 bounded s /\ bounded t /\ bounded u /\ ~(t = {}) 20956 ==> hausdist(s,u) <= hausdist(s,t) + hausdist(t,u)``, 20957 REPEAT STRIP_TAC THEN 20958 ASM_CASES_TAC ``s:real->bool = {}`` THEN 20959 ASM_REWRITE_TAC[HAUSDIST_EMPTY, REAL_ADD_LID, HAUSDIST_POS_LE] THEN 20960 ASM_CASES_TAC ``u:real->bool = {}`` THEN 20961 ASM_REWRITE_TAC[HAUSDIST_EMPTY, REAL_ADD_RID, HAUSDIST_POS_LE] THEN 20962 ASM_SIMP_TAC real_ss [REAL_HAUSDIST_LE_EQ] THEN 20963 ASM_MESON_TAC[lemma, HAUSDIST_SYM, SETDIST_SYM, REAL_ADD_SYM]); 20964 20965val HAUSDIST_EQ_0 = store_thm ("HAUSDIST_EQ_0", 20966 ``!s t:real->bool. 20967 bounded s /\ bounded t 20968 ==> ((hausdist(s,t) = &0) <=> (s = {}) \/ (t = {}) \/ (closure s = closure t))``, 20969 REPEAT STRIP_TAC THEN 20970 MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN 20971 ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN 20972 ASM_SIMP_TAC real_ss [GSYM REAL_LE_ANTISYM, HAUSDIST_POS_LE, REAL_HAUSDIST_LE_EQ] THEN 20973 SIMP_TAC real_ss [SETDIST_POS_LE, REAL_ARITH ``&0 <= x ==> (x <= &0 <=> (x = &0:real))``] THEN 20974 ASM_SIMP_TAC real_ss [SETDIST_EQ_0_SING, GSYM SUBSET_ANTISYM_EQ, SUBSET_DEF] THEN 20975 SIMP_TAC std_ss [FORALL_IN_CLOSURE_EQ, CLOSED_CLOSURE, CONTINUOUS_ON_ID]); 20976 20977val HAUSDIST_COMPACT_NONTRIVIAL = store_thm ("HAUSDIST_COMPACT_NONTRIVIAL", 20978 ``!s t:real->bool. 20979 compact s /\ compact t /\ ~(s = {}) /\ ~(t = {}) 20980 ==> (hausdist(s,t) = 20981 inf {e | &0 <= e /\ 20982 s SUBSET {x + y | x IN t /\ abs y <= e} /\ 20983 t SUBSET {x + y | x IN s /\ abs y <= e}})``, 20984 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN 20985 MATCH_MP_TAC REAL_INF_UNIQUE THEN 20986 SIMP_TAC real_ss [FORALL_IN_GSPEC, EXISTS_IN_GSPEC] THEN 20987 SIMP_TAC real_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN 20988 SIMP_TAC real_ss [REAL_ARITH ``(a:real = b + x) <=> (a - b = x)``, 20989 ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN 20990 REWRITE_TAC[GSYM dist] THEN CONJ_TAC THENL 20991 [REPEAT STRIP_TAC THEN 20992 MATCH_MP_TAC REAL_HAUSDIST_LE THEN 20993 METIS_TAC[SETDIST_LE_DIST, DIST_SYM, REAL_LE_TRANS, 20994 IN_SING, REAL_LT_IMP_LE], 20995 REPEAT STRIP_TAC THEN EXISTS_TAC ``hausdist(s:real->bool,t)`` THEN 20996 ASM_REWRITE_TAC[HAUSDIST_POS_LE] THEN 20997 METIS_TAC[DIST_SYM, HAUSDIST_SYM, 20998 HAUSDIST_COMPACT_EXISTS, COMPACT_IMP_BOUNDED]]); 20999 21000(* TODO: 21001val HAUSDIST_BALLS = store_thm ("HAUSDIST_BALLS", 21002 ``(!a b:real r s. 21003 hausdist(ball(a,r),ball(b,s)) = 21004 if r <= &0 \/ s <= &0 then &0 else dist(a,b) + abs(r - s)) /\ 21005 (!a b:real r s. 21006 hausdist(ball(a,r),cball(b,s)) = 21007 if r <= &0 \/ s < &0 then &0 else dist(a,b) + abs(r - s)) /\ 21008 (!a b:real r s. 21009 hausdist(cball(a,r),ball(b,s)) = 21010 if r < &0 \/ s <= &0 then &0 else dist(a,b) + abs(r - s)) /\ 21011 (!a b:real r s. 21012 hausdist(cball(a,r),cball(b,s)) = 21013 if r < &0 \/ s < &0 then &0 else dist(a,b) + abs(r - s))``, 21014 REWRITE_TAC[METIS[] 21015 ``(x = if p then y else z) <=> (p ==> (x = y)) /\ (~p ==> (x = z))``] THEN 21016 SIMP_TAC real_ss [TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN 21017 SIMP_TAC real_ss [BALL_EMPTY, CBALL_EMPTY, HAUSDIST_EMPTY, DE_MORGAN_THM] THEN 21018 ONCE_REWRITE_TAC[METIS[HAUSDIST_CLOSURE] 21019 ``hausdist(s,t) = hausdist(closure s,closure t)``] THEN 21020 SIMP_TAC real_ss [REAL_NOT_LE, REAL_NOT_LT, CLOSURE_BALL] THEN 21021 REWRITE_TAC[HAUSDIST_CLOSURE] THEN 21022 MATCH_MP_TAC(TAUT `(s ==> p /\ q /\ r) /\ s ==> p /\ q /\ r /\ s`) THEN 21023 CONJ_TAC THENL [MESON_TAC[REAL_LT_IMP_LE], REPEAT STRIP_TAC] THEN 21024 ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL, BOUNDED_CBALL, CBALL_EQ_EMPTY, 21025 REAL_NOT_LT] THEN 21026 MATCH_MP_TAC SUP_UNIQUE THEN 21027 SIMP_TAC real_ss [FORALL_IN_GSPEC, FORALL_IN_UNION] THEN 21028 REWRITE_TAC[MESON[CBALL_SING] ``{a} = cball(a:real,&0)``] THEN 21029 ASM_REWRITE_TAC[SETDIST_BALLS, REAL_LT_REFL] THEN 21030 X_GEN_TAC ``c:real`` THEN REWRITE_TAC[IN_CBALL] THEN 21031 EQ_TAC THENL [ALL_TAC, REWRITE_TAC [dist, max_def] THEN REAL_ARITH_TAC] THEN 21032 ASM_CASES_TAC ``b:real = a`` THENL 21033 [ONCE_ASM_REWRITE_TAC [DIST_SYM] THEN ASM_REWRITE_TAC[DIST_REFL, REAL_MAX_LE] THEN 21034 DISCH_THEN(CONJUNCTS_THEN2 21035 (MP_TAC o SPEC ``a + r * 1:real``) 21036 (MP_TAC o SPEC ``a + s * 1:real``)) THEN 21037 REWRITE_TAC[dist, REAL_ARITH ``abs(a:real - (a + x)) = abs x``] THEN 21038 SIMP_TAC real_ss [ABS_MUL, LESS_EQ_REFL, max_def] THEN ASM_REAL_ARITH_TAC, 21039 DISCH_THEN(CONJUNCTS_THEN2 21040 (MP_TAC o SPEC ``a - r / dist(a,b) * (b - a):real``) 21041 (MP_TAC o SPEC ``b - s / dist(a,b) * (a - b):real``)) THEN 21042 REWRITE_TAC[dist, REAL_ARITH ``abs(a:real - (a - x)) = abs x``] THEN 21043 REWRITE_TAC[dist, ABS_MUL, REAL_ARITH 21044 ``b - e * (a - b) - a:real = (&1 + e) * (b - a)``] THEN 21045 ONCE_REWRITE_TAC [METIS [ABS_ABS] ``abs x * abs (a - b) = 21046 abs x * abs (abs (a - b:real))``] THEN 21047 REWRITE_TAC[GSYM ABS_MUL] THEN REWRITE_TAC[ABS_ABS] THEN 21048 ONCE_REWRITE_TAC [METIS [ABS_SUB] ``r / abs (a - b) * abs (b - a) = 21049 r / abs (a - b) * abs (a - b:real)``] THEN 21050 REWRITE_TAC[REAL_ADD_RDISTRIB, REAL_MUL_LID] THEN 21051 RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``(b <> a) = (abs (a - b) <> 0:real)``]) THEN 21052 ONCE_REWRITE_TAC [METIS [ABS_SUB] ``r / abs (a - b) * abs (b - a) = 21053 r / abs (a - b) * abs (a - b:real)``] THEN 21054 ASM_SIMP_TAC real_ss [REAL_DIV_RMUL, ABS_ZERO, REAL_SUB_0, max_def] THEN 21055 ASM_REAL_ARITH_TAC]); 21056 *) 21057 21058val HAUSDIST_ALT = store_thm ("HAUSDIST_ALT", 21059 ``!s t:real->bool. 21060 bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {}) 21061 ==> (hausdist(s,t) = 21062 sup {abs(setdist({x},s) - setdist({x},t)) | x IN univ(:real)})``, 21063 REPEAT GEN_TAC THEN 21064 ONCE_REWRITE_TAC[GSYM COMPACT_CLOSURE, GSYM(CONJUNCT2 SETDIST_CLOSURE), 21065 GSYM CLOSURE_EQ_EMPTY, METIS[HAUSDIST_CLOSURE] 21066 ``hausdist(s:real->bool,t) = hausdist(closure s,closure t)``] THEN 21067 SPEC_TAC(``closure t:real->bool``,``t:real->bool``) THEN 21068 SPEC_TAC(``closure s:real->bool``,``s:real->bool``) THEN 21069 REPEAT STRIP_TAC THEN 21070 ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL, COMPACT_IMP_BOUNDED] THEN 21071 MATCH_MP_TAC SUP_EQ THEN 21072 SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC, IN_UNIV] THEN 21073 REWRITE_TAC[REAL_ARITH ``abs(y - x) <= b <=> x <= y + b /\ y <= x + b:real``] THEN 21074 GEN_TAC THEN SIMP_TAC real_ss [FORALL_AND_THM] THEN BINOP_TAC THEN 21075 (EQ_TAC THENL [ALL_TAC, METIS_TAC[SETDIST_SING_IN_SET, REAL_ADD_LID]]) THEN 21076 DISCH_TAC THEN X_GEN_TAC ``z:real`` THENL 21077 [MP_TAC(ISPECL[``{z:real}``, ``s:real->bool``] SETDIST_CLOSED_COMPACT), 21078 MP_TAC(ISPECL[``{z:real}``, ``t:real->bool``] SETDIST_CLOSED_COMPACT)] THEN 21079 ASM_REWRITE_TAC[CLOSED_SING, NOT_INSERT_EMPTY] THEN 21080 SIMP_TAC real_ss [IN_SING, RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN 21081 DISCH_THEN(X_CHOOSE_THEN ``y:real`` (STRIP_ASSUME_TAC o GSYM)) THEN 21082 FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN ASM_REWRITE_TAC[] THENL 21083 [MP_TAC(ISPECL[``{y:real}``, ``t:real->bool``] SETDIST_CLOSED_COMPACT), 21084 MP_TAC(ISPECL[``{y:real}``, ``s:real->bool``] SETDIST_CLOSED_COMPACT)] THEN 21085 ASM_REWRITE_TAC[CLOSED_SING, NOT_INSERT_EMPTY] THEN 21086 SIMP_TAC real_ss [IN_SING, RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN 21087 DISCH_THEN(X_CHOOSE_THEN ``x:real`` (STRIP_ASSUME_TAC o GSYM)) THEN 21088 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 21089 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(z:real,x)`` THEN 21090 ASM_SIMP_TAC real_ss [SETDIST_LE_DIST, IN_SING] THEN 21091 UNDISCH_TAC ``dist(y:real,x) <= b`` THEN REWRITE_TAC [dist] THEN REAL_ARITH_TAC); 21092 21093val CONTINUOUS_DIAMETER = store_thm ("CONTINUOUS_DIAMETER", 21094 ``!s:real->bool e. 21095 bounded s /\ ~(s = {}) /\ &0 < e 21096 ==> ?d. &0 < d /\ 21097 !t. bounded t /\ ~(t = {}) /\ hausdist(s,t) < d 21098 ==> abs(diameter s - diameter t) < e``, 21099 REPEAT STRIP_TAC THEN EXISTS_TAC ``e / &2:real`` THEN 21100 ASM_REWRITE_TAC[REAL_HALF] THEN REPEAT STRIP_TAC THEN 21101 SUBGOAL_THEN ``diameter(s:real->bool) - diameter(t:real->bool) = 21102 diameter(closure s) - diameter(closure t)`` 21103 SUBST1_TAC THENL [ASM_MESON_TAC[DIAMETER_CLOSURE], ALL_TAC] THEN 21104 MATCH_MP_TAC REAL_LET_TRANS THEN 21105 EXISTS_TAC ``&2 * hausdist(s:real->bool,t)`` THEN 21106 CONJ_TAC THENL [ALL_TAC, 21107 FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 21108 ASM_REAL_ARITH_TAC] THEN 21109 MP_TAC(ISPECL [``0:real``, ``hausdist(s:real->bool,t)``] 21110 DIAMETER_CBALL) THEN 21111 ASM_SIMP_TAC real_ss [HAUSDIST_POS_LE, GSYM REAL_NOT_LE] THEN 21112 DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC(REAL_ARITH 21113 ``x <= y + e /\ y <= x + e ==> abs(x - y) <= e:real``) THEN 21114 CONJ_TAC THEN 21115 W(MP_TAC o PART_MATCH (rand o rand) DIAMETER_SUMS o rand o snd) THEN 21116 ASM_SIMP_TAC real_ss [BOUNDED_CBALL, BOUNDED_CLOSURE] THEN 21117 MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] REAL_LE_TRANS) THEN 21118 MATCH_MP_TAC DIAMETER_SUBSET THEN 21119 ASM_SIMP_TAC real_ss [BOUNDED_SUMS, BOUNDED_CBALL, BOUNDED_CLOSURE] THEN 21120 ONCE_REWRITE_TAC[METIS[HAUSDIST_CLOSURE] 21121 ``hausdist(s:real->bool,t) = hausdist(closure s,closure t)``] 21122 THENL [ALL_TAC, ONCE_REWRITE_TAC[HAUSDIST_SYM]] THEN 21123 MATCH_MP_TAC HAUSDIST_COMPACT_SUMS THEN 21124 ASM_SIMP_TAC real_ss [COMPACT_CLOSURE, BOUNDED_CLOSURE, CLOSURE_EQ_EMPTY]); 21125 21126(* ------------------------------------------------------------------------- *) 21127(* Isometries are embeddings, and even surjective in the compact case. *) 21128(* ------------------------------------------------------------------------- *) 21129 21130val ISOMETRY_IMP_OPEN_MAP = store_thm ("ISOMETRY_IMP_OPEN_MAP", 21131 ``!f:real->real s t u. 21132 (IMAGE f s = t) /\ 21133 (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y))) /\ 21134 open_in (subtopology euclidean s) u 21135 ==> open_in (subtopology euclidean t) (IMAGE f u)``, 21136 SIMP_TAC std_ss [open_in, FORALL_IN_IMAGE] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN 21137 CONJ_TAC THENL [ASM_SET_TAC[], X_GEN_TAC ``x:real`` THEN DISCH_TAC] THEN 21138 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 21139 STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[CONJ_EQ_IMP] THEN 21140 SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN 21141 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF]) THEN 21142 ASM_SIMP_TAC std_ss [IN_IMAGE] THEN ASM_MESON_TAC[]); 21143 21144val ISOMETRY_IMP_EMBEDDING = store_thm ("ISOMETRY_IMP_EMBEDDING", 21145 ``!f:real->real s t. 21146 (IMAGE f s = t) /\ (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y))) 21147 ==> ?g. homeomorphism (s,t) (f,g)``, 21148 REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN 21149 ASM_SIMP_TAC std_ss [ISOMETRY_ON_IMP_CONTINUOUS_ON] THEN 21150 CONJ_TAC THENL [ASM_MESON_TAC[DIST_EQ_0], REPEAT STRIP_TAC] THEN 21151 MATCH_MP_TAC ISOMETRY_IMP_OPEN_MAP THEN ASM_MESON_TAC[]); 21152 21153val ISOMETRY_IMP_HOMEOMORPHISM_COMPACT = store_thm ("ISOMETRY_IMP_HOMEOMORPHISM_COMPACT", 21154 ``!f s:real->bool. 21155 compact s /\ IMAGE f s SUBSET s /\ 21156 (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y))) 21157 ==> ?g. homeomorphism (s,s) (f,g)``, 21158 REPEAT STRIP_TAC THEN 21159 SUBGOAL_THEN ``IMAGE (f:real->real) s = s`` 21160 (fn th => ASM_MESON_TAC[th, ISOMETRY_IMP_EMBEDDING]) THEN 21161 FIRST_ASSUM(ASSUME_TAC o MATCH_MP ISOMETRY_ON_IMP_CONTINUOUS_ON) THEN 21162 ASM_REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN REWRITE_TAC[SUBSET_DEF] THEN 21163 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 21164 SUBGOAL_THEN ``setdist({x},IMAGE (f:real->real) s) = &0`` MP_TAC THENL 21165 [MATCH_MP_TAC(REAL_ARITH ``&0 <= x /\ ~(&0 < x) ==> (x = &0:real)``) THEN 21166 REWRITE_TAC[SETDIST_POS_LE] THEN DISCH_TAC THEN 21167 KNOW_TAC ``?z. (z 0 = (x:real)) /\ !n. z(SUC n) = f(z n)`` THENL 21168 [RW_TAC std_ss [num_Axiom], STRIP_TAC] THEN 21169 SUBGOAL_THEN ``!n. (z:num->real) n IN s`` ASSUME_TAC THENL 21170 [INDUCT_TAC THEN ASM_SET_TAC[], ALL_TAC] THEN 21171 UNDISCH_TAC ``compact s`` THEN DISCH_TAC THEN 21172 FIRST_ASSUM(MP_TAC o REWRITE_RULE [compact]) THEN 21173 DISCH_THEN(MP_TAC o SPEC ``z:num->real``) THEN 21174 ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN 21175 MAP_EVERY X_GEN_TAC [``l:real``, ``r:num->num``] THEN CCONTR_TAC THEN 21176 FULL_SIMP_TAC std_ss [] THEN 21177 FIRST_ASSUM(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN 21178 REWRITE_TAC[cauchy] THEN 21179 DISCH_THEN(MP_TAC o SPEC ``setdist({x},IMAGE (f:real->real) s)``) THEN 21180 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN ``N:num`` 21181 (MP_TAC o SPECL [``N:num``, ``N + 1:num``])) THEN 21182 KNOW_TAC ``N >= N /\ N + 1 >= N:num`` THENL 21183 [ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 21184 POP_ASSUM K_TAC THEN REWRITE_TAC[REAL_NOT_LT, o_THM]] THEN 21185 SUBGOAL_THEN ``(r:num->num) N < r (N + 1)`` MP_TAC THENL 21186 [RULE_ASSUM_TAC (REWRITE_RULE [METIS [] ``(~a \/ b) = (a ==> b)``]) THEN 21187 FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC, 21188 SIMP_TAC std_ss [LT_EXISTS, LEFT_IMP_EXISTS_THM]] THEN 21189 X_GEN_TAC ``d:num`` THEN DISCH_THEN SUBST1_TAC THEN 21190 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(x:real,z(SUC d))`` THEN CONJ_TAC THENL 21191 [MATCH_MP_TAC SETDIST_LE_DIST THEN ASM_SET_TAC[], ALL_TAC] THEN 21192 MATCH_MP_TAC REAL_EQ_IMP_LE THEN 21193 SPEC_TAC(``(r:num->num) N``,``m:num``) THEN 21194 INDUCT_TAC THEN ASM_MESON_TAC[ADD_CLAUSES], 21195 REWRITE_TAC[SETDIST_EQ_0_SING, IMAGE_EQ_EMPTY] THEN 21196 ASM_MESON_TAC[COMPACT_IMP_CLOSED, NOT_IN_EMPTY, 21197 COMPACT_CONTINUOUS_IMAGE, CLOSURE_CLOSED]]); 21198 21199(* ------------------------------------------------------------------------- *) 21200(* Urysohn's lemma (for real, where the proof is easy using distances). *) 21201(* ------------------------------------------------------------------------- *) 21202 21203val lemma = prove ( 21204 ``!s t u a b. 21205 closed_in (subtopology euclidean u) s /\ 21206 closed_in (subtopology euclidean u) t /\ 21207 (s INTER t = {}) /\ ~(s = {}) /\ ~(t = {}) /\ ~(a = b) 21208 ==> ?f:real->real. 21209 f continuous_on u /\ 21210 (!x. x IN u ==> f(x) IN segment[a,b]) /\ 21211 (!x. x IN u ==> ((f x = a) <=> x IN s)) /\ 21212 (!x. x IN u ==> ((f x = b) <=> x IN t))``, 21213 REPEAT STRIP_TAC THEN EXISTS_TAC 21214 ``\x:real. a + setdist({x},s) / (setdist({x},s) + setdist({x},t)) * 21215 (b - a:real)`` THEN SIMP_TAC std_ss [] THEN 21216 SUBGOAL_THEN 21217 ``(!x:real. x IN u ==> ((setdist({x},s) = &0) <=> x IN s)) /\ 21218 (!x:real. x IN u ==> ((setdist({x},t) = &0) <=> x IN t))`` 21219 STRIP_ASSUME_TAC THENL 21220 [ASM_REWRITE_TAC[SETDIST_EQ_0_SING] THEN CONJ_TAC THENL 21221 [MP_TAC(ISPEC ``s:real->bool`` CLOSED_IN_CLOSED), 21222 MP_TAC(ISPEC ``t:real->bool`` CLOSED_IN_CLOSED)] THEN 21223 DISCH_THEN(MP_TAC o SPEC ``u:real->bool``) THEN 21224 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN ``v:real->bool`` 21225 (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN 21226 ASM_MESON_TAC[CLOSURE_CLOSED, INTER_SUBSET, SUBSET_CLOSURE, SUBSET_DEF, 21227 IN_INTER, CLOSURE_SUBSET], 21228 ALL_TAC] THEN 21229 SUBGOAL_THEN ``!x:real. x IN u ==> &0 < setdist({x},s) + setdist({x},t)`` 21230 ASSUME_TAC THENL 21231 [REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH 21232 ``&0 <= x /\ &0 <= y /\ ~((x = &0) /\ (y = &0)) ==> &0 < x + y:real``) THEN 21233 REWRITE_TAC[SETDIST_POS_LE] THEN ASM_SET_TAC[], 21234 ALL_TAC] THEN 21235 REPEAT CONJ_TAC THENL 21236 [ONCE_REWRITE_TAC [METIS [] ``(\x. a + 21237 setdist ({x},s) / (setdist ({x},s) + setdist ({x},t)) * (b - a)) = 21238 (\x. (\x. a) x + 21239 (\x. setdist ({x},s) / (setdist ({x},s) + setdist ({x},t)) * (b - a)) x)``] THEN 21240 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN 21241 REWRITE_TAC[real_div, GSYM REAL_MUL_ASSOC] THEN 21242 ONCE_REWRITE_TAC [METIS [] ``(\x. setdist ({x},s) * 21243 (inv (setdist ({x},s) + setdist ({x},t)) * (b - a))) = 21244 (\x. (\x. setdist ({x},s)) x * 21245 (\x. (inv (setdist ({x},s) + setdist ({x},t)) * (b - a))) x)``] THEN 21246 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN CONJ_TAC THENL 21247 [REWRITE_TAC[CONTINUOUS_ON_SETDIST], ALL_TAC] THEN 21248 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (setdist ({x},s) + setdist ({x},t)) * (b - a)) = 21249 (\x. (\x. inv (setdist ({x},s) + setdist ({x},t))) x * (\x. (b - a)) x)``] THEN 21250 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_CONST, o_DEF] THEN 21251 REWRITE_TAC[CONTINUOUS_ON_SETDIST] THEN 21252 ONCE_REWRITE_TAC [METIS [] ``(\x. inv (setdist ({x},s) + setdist ({x},t))) = 21253 (\x. inv ((\x. setdist ({x},s) + setdist ({x},t)) x))``] THEN 21254 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN 21255 ASM_SIMP_TAC std_ss [REAL_LT_IMP_NE] THEN 21256 ONCE_REWRITE_TAC [METIS [] ``(\x. setdist ({x},s) + setdist ({x},t)) = 21257 (\x. (\x. setdist ({x},s)) x + (\x. setdist ({x},t)) x)``] THEN 21258 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN 21259 REWRITE_TAC[CONTINUOUS_ON_SETDIST], 21260 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 21261 SIMP_TAC std_ss[segment, GSPECIFICATION] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN 21262 SIMP_TAC real_ss [REAL_ENTIRE, LEFT_AND_OVER_OR, REAL_ARITH 21263 ``(a + x * (b - a):real = (&1 - u) * a + u * b) <=> 21264 ((x - u) * (b - a) = 0)``, EXISTS_OR_THM] THEN 21265 DISJ1_TAC THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN 21266 REWRITE_TAC[REAL_SUB_0, UNWIND_THM1] THEN 21267 ASM_SIMP_TAC std_ss [REAL_LE_DIV, REAL_LE_ADD, SETDIST_POS_LE, REAL_LE_LDIV_EQ, 21268 REAL_ARITH ``a <= &1 * (a + b) <=> &0 <= b:real``], 21269 SIMP_TAC real_ss [REAL_ARITH ``(a + x:real = a) <=> (x = 0)``], 21270 REWRITE_TAC[REAL_ARITH ``(a + x * (b - a):real = b) <=> 21271 ((x - &1) * (b - a) = 0)``]] THEN 21272 ASM_REWRITE_TAC[REAL_ENTIRE, REAL_SUB_0] THEN 21273 ASM_SIMP_TAC std_ss [REAL_SUB_0, REAL_EQ_LDIV_EQ, 21274 REAL_MUL_LZERO, REAL_MUL_LID] THEN 21275 REWRITE_TAC[REAL_ARITH ``(x:real = x + y) <=> (y = &0)``] THEN 21276 ASM_REWRITE_TAC[]); 21277 21278val URYSOHN_LOCAL_STRONG = store_thm ("URYSOHN_LOCAL_STRONG", 21279 ``!s t u a b. 21280 closed_in (subtopology euclidean u) s /\ 21281 closed_in (subtopology euclidean u) t /\ 21282 (s INTER t = {}) /\ ~(a = b) 21283 ==> ?f:real->real. 21284 f continuous_on u /\ 21285 (!x. x IN u ==> f(x) IN segment[a,b]) /\ 21286 (!x. x IN u ==> ((f x = a) <=> x IN s)) /\ 21287 (!x. x IN u ==> ((f x = b) <=> x IN t))``, 21288 KNOW_TAC ``!(s :real -> bool) (t :real -> bool). 21289 (\s t. !(u :real -> bool) (a :real) (b :real). 21290 closed_in (subtopology euclidean u) s /\ 21291 closed_in (subtopology euclidean u) t /\ 21292 (s INTER t = ({} :real -> bool)) /\ a <> b ==> 21293 ?(f :real -> real). 21294 f continuous_on u /\ 21295 (!(x :real). x IN u ==> f x IN segment [(a,b)]) /\ 21296 (!(x :real). x IN u ==> ((f x = a) <=> x IN s)) /\ 21297 !(x :real). x IN u ==> ((f x = b) <=> x IN t)) s t`` THENL 21298 [ALL_TAC, SIMP_TAC std_ss []] THEN 21299 MATCH_MP_TAC(MESON[] 21300 ``(!s t. P s t <=> P t s) /\ 21301 (!s t. ~(s = {}) /\ ~(t = {}) ==> P s t) /\ 21302 P {} {} /\ (!t. ~(t = {}) ==> P {} t) 21303 ==> !s t. P s t``) THEN 21304 SIMP_TAC std_ss [] THEN REPEAT CONJ_TAC THENL 21305 21306 [REPEAT GEN_TAC THEN 21307 KNOW_TAC ``(!(u :real -> bool) (a :real) (b :real). 21308 closed_in (subtopology euclidean u) (s :real -> bool) /\ 21309 closed_in (subtopology euclidean u) (t :real -> bool) /\ 21310 (s INTER t = ({} :real -> bool)) /\ a <> b ==> 21311 ?(f :real -> real). 21312 f continuous_on u /\ 21313 (!(x :real). x IN u ==> f x IN segment [(a,b)]) /\ 21314 (!(x :real). x IN u ==> ((f x = a) <=> x IN s)) /\ 21315 !(x :real). x IN u ==> ((f x = b) <=> x IN t)) <=> 21316 !(u :real -> bool) (b :real) (a :real). 21317 closed_in (subtopology euclidean u) t /\ 21318 closed_in (subtopology euclidean u) s /\ 21319 (t INTER s = ({} :real -> bool)) /\ a <> b ==> 21320 ?(f :real -> real). 21321 f continuous_on u /\ 21322 (!(x :real). x IN u ==> f x IN segment [(a,b)]) /\ 21323 (!(x :real). x IN u ==> ((f x = a) <=> x IN t)) /\ 21324 !(x :real). x IN u ==> ((f x = b) <=> x IN s)`` THENL 21325 [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 21326 EQ_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THENL 21327 [POP_ASSUM (MP_TAC o SPECL [``u:real->bool``,``b:real``,``a:real``]), 21328 POP_ASSUM (MP_TAC o SPECL [``u:real->bool``,``a:real``,``b:real``])] THEN 21329 SIMP_TAC std_ss []] THEN 21330 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN 21331 METIS_TAC[SEGMENT_SYM, INTER_COMM, CONJ_ACI, EQ_SYM_EQ], 21332 SIMP_TAC real_ss [lemma], 21333 REPEAT STRIP_TAC THEN EXISTS_TAC ``(\x. midpoint(a,b)):real->real`` THEN 21334 ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, CONTINUOUS_ON_CONST, MIDPOINT_IN_SEGMENT] THEN 21335 REWRITE_TAC[midpoint] THEN CONJ_TAC THEN GEN_TAC THEN DISCH_TAC THEN 21336 UNDISCH_TAC ``~(a:real = b)`` THEN REWRITE_TAC[GSYM MONO_NOT_EQ] THEN 21337 ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN 21338 SIMP_TAC std_ss [REAL_EQ_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 21339 REAL_ARITH_TAC, 21340 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``t:real->bool = u`` THENL 21341 [EXISTS_TAC ``(\x. b):real->real`` THEN 21342 ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, ENDS_IN_SEGMENT, IN_UNIV, 21343 CONTINUOUS_ON_CONST], 21344 SUBGOAL_THEN ``?c:real. c IN u /\ ~(c IN t)`` STRIP_ASSUME_TAC THENL 21345 [REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN 21346 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM_SET_TAC[], 21347 ALL_TAC] THEN 21348 MP_TAC(ISPECL [``{c:real}``, ``t:real->bool``, ``u:real->bool``, 21349 ``midpoint(a,b):real``, ``b:real``] lemma) THEN 21350 ASM_REWRITE_TAC[CLOSED_IN_SING, MIDPOINT_EQ_ENDPOINT] THEN 21351 KNOW_TAC ``({(c :real)} INTER (t :real -> bool) = ({} :real -> bool)) /\ 21352 {c} <> ({} :real -> bool)`` THENL 21353 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 21354 DISCH_THEN (X_CHOOSE_TAC ``f:real->real``) THEN EXISTS_TAC ``f:real->real`` THEN 21355 POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IN_EMPTY] THEN 21356 STRIP_TAC THEN CONJ_TAC THENL 21357 [SUBGOAL_THEN 21358 ``segment[midpoint(a,b):real,b] SUBSET segment[a,b]`` MP_TAC 21359 THENL 21360 [REWRITE_TAC[SUBSET_DEF, IN_SEGMENT, midpoint] THEN GEN_TAC THEN 21361 DISCH_THEN(X_CHOOSE_THEN ``u:real`` STRIP_ASSUME_TAC) THEN 21362 EXISTS_TAC ``(&1 + u) / &2:real`` THEN ASM_REWRITE_TAC[] THEN 21363 SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN 21364 CONJ_TAC THENL [UNDISCH_TAC ``0 <= u:real`` THEN REAL_ARITH_TAC, ALL_TAC] THEN 21365 CONJ_TAC THENL [UNDISCH_TAC ``u <= 1:real`` THEN REAL_ARITH_TAC, ALL_TAC] THEN 21366 ONCE_REWRITE_TAC [REAL_ARITH ``a * (b * c) = (a * c) * b:real``] THEN 21367 GEN_REWR_TAC (LAND_CONV o RAND_CONV) [GSYM REAL_MUL_RID] THEN 21368 ONCE_REWRITE_TAC [METIS [REAL_DIV_REFL, REAL_ARITH ``2 <> 0:real``] 21369 ``u * b * 1 = u * b * (2 / 2:real)``] THEN REWRITE_TAC [real_div] THEN 21370 ONCE_REWRITE_TAC [REAL_ARITH ``u * b * (2 * inv 2) = (u * b * 2) * inv 2:real``] THEN 21371 REWRITE_TAC [GSYM REAL_ADD_RDISTRIB] THEN REWRITE_TAC [GSYM real_div] THEN 21372 SIMP_TAC real_ss [REAL_EQ_LDIV_EQ] THEN REWRITE_TAC [REAL_ADD_RDISTRIB] THEN 21373 REWRITE_TAC [real_div, REAL_SUB_RDISTRIB] THEN 21374 REWRITE_TAC [REAL_ARITH 21375 ``(1 + u) * inv 2 * a * 2 = (1 + u) * a * (inv 2 * 2:real)``] THEN 21376 SIMP_TAC real_ss [REAL_MUL_LINV] THEN REAL_ARITH_TAC, 21377 ASM_SET_TAC[]], 21378 SUBGOAL_THEN ``~(a IN segment[midpoint(a,b):real,b])`` MP_TAC THENL 21379 [ALL_TAC, ASM_MESON_TAC[]] THEN 21380 DISCH_THEN(MP_TAC o CONJUNCT2 o MATCH_MP DIST_IN_CLOSED_SEGMENT) THEN 21381 REWRITE_TAC[DIST_MIDPOINT] THEN 21382 UNDISCH_TAC ``~(a:real = b)`` THEN REWRITE_TAC [dist] THEN 21383 SIMP_TAC real_ss [REAL_LE_RDIV_EQ] THEN REWRITE_TAC [REAL_NOT_LE] THEN 21384 REWRITE_TAC [abs] THEN COND_CASES_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC]]]); 21385 21386val URYSOHN_LOCAL = store_thm ("URYSOHN_LOCAL", 21387 ``!s t u a b. 21388 closed_in (subtopology euclidean u) s /\ 21389 closed_in (subtopology euclidean u) t /\ 21390 (s INTER t = {}) 21391 ==> ?f:real->real. 21392 f continuous_on u /\ 21393 (!x. x IN u ==> f(x) IN segment[a,b]) /\ 21394 (!x. x IN s ==> (f x = a)) /\ 21395 (!x. x IN t ==> (f x = b))``, 21396 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``a:real = b`` THENL 21397 [EXISTS_TAC ``(\x. b):real->real`` THEN 21398 ASM_REWRITE_TAC[ENDS_IN_SEGMENT, CONTINUOUS_ON_CONST], 21399 MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``, ``u:real->bool``, 21400 ``a:real``, ``b:real``] URYSOHN_LOCAL_STRONG) THEN 21401 ASM_REWRITE_TAC[] THEN DISCH_THEN (X_CHOOSE_TAC ``f:real->real``) THEN 21402 EXISTS_TAC ``f:real->real`` THEN POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [] THEN 21403 REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN 21404 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN SET_TAC[]]); 21405 21406val URYSOHN_STRONG = store_thm ("URYSOHN_STRONG", 21407 ``!s t a b. 21408 closed s /\ closed t /\ (s INTER t = {}) /\ ~(a = b) 21409 ==> ?f:real->real. 21410 f continuous_on univ(:real) /\ (!x. f(x) IN segment[a,b]) /\ 21411 (!x. (f x = a) <=> x IN s) /\ (!x. (f x = b) <=> x IN t)``, 21412 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN 21413 ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN 21414 DISCH_THEN(MP_TAC o MATCH_MP URYSOHN_LOCAL_STRONG) THEN 21415 REWRITE_TAC[IN_UNIV]); 21416 21417val URYSOHN = store_thm ("URYSOHN", 21418 ``!s t a b. 21419 closed s /\ closed t /\ (s INTER t = {}) 21420 ==> ?f:real->real. 21421 f continuous_on univ(:real) /\ (!x. f(x) IN segment[a,b]) /\ 21422 (!x. x IN s ==> (f x = a)) /\ (!x. x IN t ==> (f x = b))``, 21423 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN 21424 ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN DISCH_THEN 21425 (MP_TAC o ISPECL [``a:real``, ``b:real``] o MATCH_MP URYSOHN_LOCAL) THEN 21426 REWRITE_TAC[IN_UNIV]); 21427 21428(* ------------------------------------------------------------------------- *) 21429(* Basics about "local" properties in general. *) 21430(* ------------------------------------------------------------------------- *) 21431 21432val locally = new_definition ("locally", 21433 ``locally P (s:real->bool) <=> 21434 !w x. open_in (subtopology euclidean s) w /\ x IN w 21435 ==> ?u v. open_in (subtopology euclidean s) u /\ P v /\ 21436 x IN u /\ u SUBSET v /\ v SUBSET w``); 21437 21438val LOCALLY_MONO = store_thm ("LOCALLY_MONO", 21439 ``!P Q s. (!t. P t ==> Q t) /\ locally P s ==> locally Q s``, 21440 REWRITE_TAC[locally] THEN MESON_TAC[]); 21441 21442val LOCALLY_OPEN_SUBSET = store_thm ("LOCALLY_OPEN_SUBSET", 21443 ``!P s t:real->bool. 21444 locally P s /\ open_in (subtopology euclidean s) t 21445 ==> locally P t``, 21446 REPEAT GEN_TAC THEN REWRITE_TAC[locally] THEN STRIP_TAC THEN 21447 MAP_EVERY X_GEN_TAC [``w:real->bool``, ``x:real``] THEN STRIP_TAC THEN 21448 FIRST_X_ASSUM(MP_TAC o SPECL [``w:real->bool``, ``x:real``]) THEN 21449 KNOW_TAC ``open_in (subtopology euclidean s) w /\ x IN w`` THENL 21450 [ASM_MESON_TAC[OPEN_IN_TRANS], 21451 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 21452 STRIP_TAC THEN EXISTS_TAC ``u:real->bool`` THEN EXISTS_TAC ``v:real->bool`` THEN 21453 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC OPEN_IN_SUBSET_TRANS THEN 21454 EXISTS_TAC ``s:real->bool`` THEN ASM_MESON_TAC[open_in, SUBSET_DEF]); 21455 21456val LOCALLY_DIFF_CLOSED = store_thm ("LOCALLY_DIFF_CLOSED", 21457 ``!P s t:real->bool. 21458 locally P s /\ closed_in (subtopology euclidean s) t 21459 ==> locally P (s DIFF t)``, 21460 REPEAT STRIP_TAC THEN 21461 MATCH_MP_TAC LOCALLY_OPEN_SUBSET THEN 21462 EXISTS_TAC ``s:real->bool`` THEN ASM_REWRITE_TAC[] THEN 21463 MATCH_MP_TAC OPEN_IN_DIFF THEN 21464 ASM_REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL, SUBSET_UNIV, TOPSPACE_EUCLIDEAN]); 21465 21466val LOCALLY_EMPTY = store_thm ("LOCALLY_EMPTY", 21467 ``!P. locally P {}``, 21468 REWRITE_TAC[locally] THEN MESON_TAC[open_in, SUBSET_DEF, NOT_IN_EMPTY]); 21469 21470val LOCALLY_SING = store_thm ("LOCALLY_SING", 21471 ``!P a. locally P {a} <=> P {a}``, 21472 REWRITE_TAC[locally, open_in] THEN 21473 REWRITE_TAC[SET_RULE 21474 ``(w SUBSET {a} /\ P) /\ x IN w <=> (w = {a}) /\ (x = a) /\ P``] THEN 21475 SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2, IN_SING] THEN 21476 REWRITE_TAC[SET_RULE 21477 ``(u SUBSET {a} /\ P) /\ Q /\ a IN u /\ u SUBSET v /\ v SUBSET {a} <=> 21478 (u = {a}) /\ (v = {a}) /\ P /\ Q``] THEN 21479 SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM, UNWIND_THM2, IN_SING] THEN 21480 REWRITE_TAC[UNWIND_FORALL_THM2, MESON[REAL_LT_01] ``?x:real. &0 < x``]); 21481 21482val LOCALLY_INTER = store_thm ("LOCALLY_INTER", 21483 ``!P:(real->bool)->bool. 21484 (!s t. P s /\ P t ==> P(s INTER t)) 21485 ==> !s t. locally P s /\ locally P t ==> locally P (s INTER t)``, 21486 GEN_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THEN 21487 REWRITE_TAC[locally, OPEN_IN_OPEN] THEN 21488 SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM] THEN 21489 REWRITE_TAC [GSYM CONJ_ASSOC] THEN 21490 ONCE_REWRITE_TAC [METIS [] ``( ?v t. 21491 open t /\ P v /\ x IN s INTER t /\ s INTER t SUBSET v /\ 21492 v SUBSET w) = (\w x. ?v t. 21493 open t /\ P v /\ x IN s INTER t /\ s INTER t SUBSET v /\ 21494 v SUBSET w) w x``] THEN 21495 ONCE_REWRITE_TAC [METIS [] ``s INTER t = (\t. s INTER t:real->bool) t``] THEN 21496 ONCE_REWRITE_TAC [METIS [] ``x IN w = (\w x. x IN w) w x``] THEN 21497 ONCE_REWRITE_TAC [METIS[] 21498 ``(!w x. (?t. P t /\ (w = f t) /\ Q w x) ==> R w x) <=> 21499 (!t x. P t /\ Q (f t) x ==> R (f t) x)``] THEN 21500 SIMP_TAC std_ss [] THEN 21501 SIMP_TAC std_ss [GSYM FORALL_AND_THM, UNWIND_THM2, IN_INTER] THEN 21502 DISCH_TAC THEN X_GEN_TAC ``w:real->bool`` THEN X_GEN_TAC ``x:real`` THEN 21503 POP_ASSUM (MP_TAC o SPECL [``w:real->bool``,``x:real``]) THEN 21504 DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN 21505 ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 21506 (X_CHOOSE_THEN ``u1:real->bool`` (X_CHOOSE_THEN ``v1:real->bool`` 21507 STRIP_ASSUME_TAC)) 21508 (X_CHOOSE_THEN ``u2:real->bool`` (X_CHOOSE_THEN ``v2:real->bool`` 21509 STRIP_ASSUME_TAC))) THEN 21510 EXISTS_TAC ``u1 INTER u2:real->bool`` THEN 21511 EXISTS_TAC ``v1 INTER v2:real->bool`` THEN 21512 ASM_SIMP_TAC std_ss [OPEN_INTER] THEN ASM_SET_TAC[]); 21513 21514val lemma = prove ( 21515 ``!P Q f g. (!s t. P s /\ homeomorphism (s,t) (f,g) ==> Q t) 21516 ==> (!s:real->bool t:real->bool. 21517 locally P s /\ homeomorphism (s,t) (f,g) ==> locally Q t)``, 21518 REPEAT GEN_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THEN 21519 REWRITE_TAC[locally] THEN STRIP_TAC THEN 21520 FIRST_X_ASSUM(STRIP_ASSUME_TAC o REWRITE_RULE [homeomorphism]) THEN 21521 MAP_EVERY X_GEN_TAC [``w:real->bool``, ``y:real``] THEN STRIP_TAC THEN 21522 FIRST_X_ASSUM(MP_TAC o SPECL 21523 [``IMAGE (g:real->real) w``, ``(g:real->real) y``]) THEN 21524 KNOW_TAC ``open_in (subtopology euclidean (s :real -> bool)) 21525 (IMAGE (g :real -> real) (w :real -> bool)) /\ 21526 g (y :real) IN IMAGE g w`` THENL 21527 [CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 21528 SUBGOAL_THEN ``IMAGE (g:real->real) w = 21529 {x | x IN s /\ f(x) IN w}`` 21530 SUBST1_TAC THENL 21531 [RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM_SET_TAC[], 21532 MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]], 21533 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM]] THEN 21534 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21535 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 21536 [``IMAGE (f:real->real) u``, ``IMAGE (f:real->real) v``] THEN 21537 CONJ_TAC THENL 21538 [SUBGOAL_THEN ``IMAGE (f:real->real) u = 21539 {x | x IN t /\ g(x) IN u}`` 21540 SUBST1_TAC THENL 21541 [RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM_SET_TAC[], 21542 MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]], 21543 ALL_TAC] THEN 21544 CONJ_TAC THENL 21545 [FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC ``v:real->bool`` THEN 21546 ASM_REWRITE_TAC[homeomorphism] THEN 21547 REWRITE_TAC[homeomorphism] THEN REPEAT CONJ_TAC THEN 21548 TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] 21549 CONTINUOUS_ON_SUBSET))), 21550 ALL_TAC] THEN 21551 RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM_SET_TAC[]); 21552 21553val HOMEOMORPHISM_LOCALLY = store_thm ("HOMEOMORPHISM_LOCALLY", 21554 ``!P Q f:real->real g. 21555 (!s t. homeomorphism (s,t) (f,g) ==> (P s <=> Q t)) 21556 ==> (!s t. homeomorphism (s,t) (f,g) 21557 ==> (locally P s <=> locally Q t))``, 21558 REPEAT STRIP_TAC THEN EQ_TAC THEN 21559 MATCH_MP_TAC(SIMP_RULE std_ss [RIGHT_IMP_FORALL_THM, 21560 TAUT `p ==> q /\ r ==> s <=> p /\ r ==> q ==> s`] lemma) THEN 21561 ASM_MESON_TAC[HOMEOMORPHISM_SYM]); 21562 21563val HOMEOMORPHIC_LOCALLY = store_thm ("HOMEOMORPHIC_LOCALLY", 21564 ``!P Q. (!s:real->bool t:real->bool. s homeomorphic t ==> (P s <=> Q t)) 21565 ==> (!s t. s homeomorphic t ==> (locally P s <=> locally Q t))``, 21566 REPEAT GEN_TAC THEN STRIP_TAC THEN 21567 SIMP_TAC std_ss [homeomorphic, LEFT_IMP_EXISTS_THM] THEN 21568 ONCE_REWRITE_TAC [METIS [] ``(homeomorphism (s,t) (f,g) ==> 21569 (locally P s <=> locally Q t)) = 21570 (\s t f g. homeomorphism (s,t) (f,g) ==> 21571 (locally P s <=> locally Q t)) s t f g``] THEN 21572 ONCE_REWRITE_TAC[METIS[] 21573 ``(!a b c d. P a b c d) <=> (!c d a b. P a b c d)``] THEN 21574 GEN_TAC THEN GEN_TAC THEN BETA_TAC THEN MATCH_MP_TAC HOMEOMORPHISM_LOCALLY THEN 21575 ASM_MESON_TAC[homeomorphic]); 21576 21577val LOCALLY_TRANSLATION = store_thm ("LOCALLY_TRANSLATION", 21578 ``!P:(real->bool)->bool. 21579 (!a s. P (IMAGE (\x. a + x) s) <=> P s) 21580 ==> (!a s. locally P (IMAGE (\x. a + x) s) <=> locally P s)``, 21581 GEN_TAC THEN 21582 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``a:real``) THEN 21583 MP_TAC(ISPECL 21584 [``P:(real->bool)->bool``, ``P:(real->bool)->bool``, 21585 ``\x:real. a + x``, ``\x:real. -a + x``] 21586 HOMEOMORPHISM_LOCALLY) THEN 21587 SIMP_TAC real_ss [homeomorphism] THEN 21588 SIMP_TAC real_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID] THEN 21589 SIMP_TAC real_ss [UNWIND_FORALL_THM1, CONJ_EQ_IMP, GSYM IMAGE_COMPOSE, o_DEF] THEN 21590 REWRITE_TAC [REAL_ARITH ``(-a + (a + x:real) = x) /\ (a + (-a + x) = x:real)``] THEN 21591 REWRITE_TAC [IMAGE_ID] THEN METIS_TAC[]); 21592 21593val LOCALLY_INJECTIVE_LINEAR_IMAGE = store_thm ("LOCALLY_INJECTIVE_LINEAR_IMAGE", 21594 ``!P:(real->bool)->bool Q:(real->bool)->bool. 21595 (!f s. linear f /\ (!x y. (f x = f y) ==> (x = y)) 21596 ==> (P (IMAGE f s) <=> Q s)) 21597 ==> (!f s. linear f /\ (!x y. (f x = f y) ==> (x = y)) 21598 ==> (locally P (IMAGE f s) <=> locally Q s))``, 21599 GEN_TAC THEN GEN_TAC THEN 21600 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``f:real->real``) THEN 21601 ASM_CASES_TAC ``linear(f:real->real) /\ (!x y. (f x = f y) ==> (x = y))`` THEN 21602 ASM_REWRITE_TAC[] THEN 21603 FIRST_ASSUM(MP_TAC o MATCH_MP LINEAR_INJECTIVE_LEFT_INVERSE) THEN 21604 REWRITE_TAC[FUN_EQ_THM, o_THM, I_THM] THEN 21605 DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN 21606 MP_TAC(ISPECL 21607 [``Q:(real->bool)->bool``, ``P:(real->bool)->bool``, 21608 ``f:real->real``, ``g:real->real``] 21609 HOMEOMORPHISM_LOCALLY) THEN 21610 ASM_SIMP_TAC std_ss [homeomorphism, LINEAR_CONTINUOUS_ON] THEN 21611 ASM_SIMP_TAC std_ss [UNWIND_FORALL_THM1, CONJ_EQ_IMP, FORALL_IN_IMAGE] THEN 21612 ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID] THEN MESON_TAC[]); 21613 21614val LOCALLY_OPEN_MAP_IMAGE = store_thm ("LOCALLY_OPEN_MAP_IMAGE", 21615 ``!P Q f:real->real s. 21616 f continuous_on s /\ 21617 (!t. open_in (subtopology euclidean s) t 21618 ==> open_in (subtopology euclidean (IMAGE f s)) (IMAGE f t)) /\ 21619 (!t. t SUBSET s /\ P t ==> Q(IMAGE f t)) /\ 21620 locally P s 21621 ==> locally Q (IMAGE f s)``, 21622 REPEAT GEN_TAC THEN 21623 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 21624 REWRITE_TAC[locally] THEN DISCH_TAC THEN 21625 MAP_EVERY X_GEN_TAC [``w:real->bool``, ``y:real``] THEN 21626 STRIP_TAC THEN 21627 FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o REWRITE_RULE [open_in]) THEN 21628 UNDISCH_TAC ``f continuous_on s`` THEN DISCH_TAC THEN 21629 FIRST_ASSUM(MP_TAC o SPEC ``w:real->bool`` o 21630 REWRITE_RULE [CONTINUOUS_ON_OPEN]) THEN 21631 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN 21632 SUBGOAL_THEN ``?x. x IN s /\ ((f:real->real) x = y)`` STRIP_ASSUME_TAC THENL 21633 [ASM_SET_TAC[], ALL_TAC] THEN 21634 FIRST_X_ASSUM(MP_TAC o SPECL 21635 [``{x | x IN s /\ (f:real->real) x IN w}``, ``x:real``]) THEN 21636 ASM_SIMP_TAC real_ss [GSPECIFICATION, LEFT_IMP_EXISTS_THM] THEN 21637 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21638 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 21639 [``IMAGE (f:real->real) u``, ``IMAGE (f:real->real) v``] THEN 21640 ASM_SIMP_TAC real_ss [] THEN CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 21641 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SET_TAC[]); 21642 21643(* ------------------------------------------------------------------------- *) 21644(* F_sigma and G_delta sets. *) 21645(* ------------------------------------------------------------------------- *) 21646 21647val gdelta = new_definition ("gdelta", 21648 ``gdelta(s:real->bool) <=> 21649 ?g. COUNTABLE g /\ (!u. u IN g ==> open u) /\ (BIGINTER g = s)``); 21650 21651val fsigma = new_definition ("fsigma", 21652 ``fsigma(s:real->bool) <=> 21653 ?g. COUNTABLE g /\ (!c. c IN g ==> closed c) /\ (BIGUNION g = s)``); 21654 21655val GDELTA_COMPLEMENT = store_thm ("GDELTA_COMPLEMENT", 21656 ``!s. gdelta(univ(:real) DIFF s) <=> fsigma s``, 21657 GEN_TAC THEN REWRITE_TAC[gdelta, fsigma] THEN EQ_TAC THEN 21658 DISCH_THEN(X_CHOOSE_THEN ``g:(real->bool)->bool`` STRIP_ASSUME_TAC) THEN 21659 EXISTS_TAC ``IMAGE (\s. univ(:real) DIFF s) g`` THEN 21660 ASM_SIMP_TAC real_ss [COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN 21661 ASM_REWRITE_TAC[GSYM OPEN_CLOSED, GSYM closed_def] THEN 21662 ONCE_REWRITE_TAC[BIGINTER_BIGUNION, BIGUNION_BIGINTER] THEN 21663 SIMP_TAC real_ss [SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN 21664 ASM_SIMP_TAC real_ss [SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``, 21665 SET_RULE ``{x | x IN s} = s``]); 21666 21667val FSIGMA_COMPLEMENT = store_thm ("FSIGMA_COMPLEMENT", 21668 ``!s. fsigma(univ(:real) DIFF s) <=> gdelta s``, 21669 ONCE_REWRITE_TAC[GSYM GDELTA_COMPLEMENT] THEN 21670 REWRITE_TAC[SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``]); 21671 21672val CLOSED_AS_GDELTA = store_thm ("CLOSED_AS_GDELTA", 21673 ``!s:real->bool. closed s ==> gdelta s``, 21674 REPEAT STRIP_TAC THEN REWRITE_TAC[gdelta] THEN EXISTS_TAC 21675 ``{ BIGUNION { ball(x:real,inv(&n + &1)) | x IN s} | n IN univ(:num)}`` THEN 21676 SIMP_TAC real_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, NUM_COUNTABLE] THEN 21677 SIMP_TAC real_ss [FORALL_IN_IMAGE, OPEN_BIGUNION, OPEN_BALL] THEN 21678 MATCH_MP_TAC(SET_RULE 21679 ``(closure s = s) /\ s SUBSET t /\ t SUBSET closure s 21680 ==> (t = s)``) THEN 21681 ASM_REWRITE_TAC[CLOSURE_EQ] THEN CONJ_TAC THENL 21682 [SIMP_TAC real_ss [SUBSET_BIGINTER, FORALL_IN_IMAGE, IN_UNIV] THEN 21683 X_GEN_TAC ``n:num`` THEN SIMP_TAC real_ss [BIGUNION_IMAGE, SUBSET_DEF, GSPECIFICATION] THEN 21684 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN EXISTS_TAC ``x:real`` THEN 21685 ASM_REWRITE_TAC[CENTRE_IN_BALL, REAL_LT_INV_EQ] THEN 21686 SIMP_TAC arith_ss [REAL_LT], 21687 REWRITE_TAC[SUBSET_DEF, CLOSURE_APPROACHABLE, BIGINTER_IMAGE, IN_UNIV] THEN 21688 X_GEN_TAC ``x:real`` THEN SIMP_TAC real_ss [GSPECIFICATION, BIGUNION_IMAGE] THEN 21689 DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 21690 FIRST_ASSUM(MP_TAC o ONCE_REWRITE_RULE [REAL_ARCH_INV]) THEN 21691 DISCH_THEN(X_CHOOSE_THEN ``n:num`` STRIP_ASSUME_TAC) THEN 21692 FIRST_X_ASSUM(MP_TAC o SPEC ``n:num``) THEN REWRITE_TAC[IN_BALL] THEN 21693 DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN 21694 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN 21695 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LT_TRANS) THEN 21696 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] 21697 REAL_LT_TRANS)) THEN 21698 MATCH_MP_TAC REAL_LT_INV2 THEN 21699 SIMP_TAC arith_ss [REAL_OF_NUM_ADD, REAL_LT] THEN ASM_ARITH_TAC]); 21700 21701(* ------------------------------------------------------------------------- *) 21702(* Local compactness. *) 21703(* ------------------------------------------------------------------------- *) 21704 21705val LOCALLY_COMPACT = store_thm ("LOCALLY_COMPACT", 21706 ``!s:real->bool. 21707 locally compact s <=> 21708 !x. x IN s ==> ?u v. x IN u /\ u SUBSET v /\ v SUBSET s /\ 21709 open_in (subtopology euclidean s) u /\ 21710 compact v``, 21711 GEN_TAC THEN REWRITE_TAC[locally] THEN EQ_TAC THEN DISCH_TAC THENL 21712 [X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN FIRST_X_ASSUM 21713 (MP_TAC o SPECL [``s INTER ball(x:real,&1)``, ``x:real``]) THEN 21714 ASM_SIMP_TAC real_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN 21715 ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, REAL_LT_01] THEN 21716 MESON_TAC[SUBSET_INTER], 21717 MAP_EVERY X_GEN_TAC [``w:real->bool``, ``x:real``] THEN 21718 REWRITE_TAC[CONJ_EQ_IMP] THEN GEN_REWR_TAC LAND_CONV [OPEN_IN_OPEN] THEN 21719 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 21720 ASM_REWRITE_TAC[IN_INTER] THEN STRIP_TAC THEN 21721 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN 21722 ASM_SIMP_TAC real_ss [LEFT_IMP_EXISTS_THM] THEN 21723 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21724 STRIP_TAC THEN 21725 UNDISCH_TAC ``open t`` THEN DISCH_TAC THEN 21726 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN 21727 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 21728 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 21729 EXISTS_TAC ``(s INTER ball(x:real,e)) INTER u`` THEN 21730 EXISTS_TAC ``cball(x:real,e) INTER v`` THEN 21731 ASM_SIMP_TAC real_ss [OPEN_IN_INTER, OPEN_IN_OPEN_INTER, OPEN_BALL, CENTRE_IN_BALL, 21732 COMPACT_INTER, COMPACT_CBALL, IN_INTER] THEN 21733 MP_TAC(ISPECL [``x:real``, ``e:real``] BALL_SUBSET_CBALL) THEN 21734 ASM_SET_TAC[]]); 21735 21736val LOCALLY_COMPACT_ALT = store_thm ("LOCALLY_COMPACT_ALT", 21737 ``!s:real->bool. 21738 locally compact s <=> 21739 !x. x IN s 21740 ==> ?u. x IN u /\ 21741 open_in (subtopology euclidean s) u /\ 21742 compact(closure u) /\ closure u SUBSET s``, 21743 GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN EQ_TAC THEN 21744 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 21745 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 21746 DISCH_THEN (X_CHOOSE_TAC ``u:real->bool``) THEN EXISTS_TAC ``u:real->bool`` THEN 21747 POP_ASSUM MP_TAC THEN 21748 METIS_TAC[CLOSURE_SUBSET, SUBSET_TRANS, CLOSURE_MINIMAL, 21749 COMPACT_CLOSURE, BOUNDED_SUBSET, COMPACT_EQ_BOUNDED_CLOSED]); 21750 21751val LOCALLY_COMPACT_INTER_CBALL = store_thm ("LOCALLY_COMPACT_INTER_CBALL", 21752 ``!s:real->bool. 21753 locally compact s <=> 21754 !x. x IN s ==> ?e. &0 < e /\ closed(cball(x,e) INTER s)``, 21755 GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT, OPEN_IN_CONTAINS_CBALL] THEN 21756 EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``x:real``) THEN 21757 ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_SIMP_TAC real_ss [LEFT_IMP_EXISTS_THM] THENL 21758 [ MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21759 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN 21760 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN 21761 ASM_REWRITE_TAC[] THEN 21762 SUBGOAL_THEN ``cball(x:real,e) INTER s = cball (x,e) INTER v`` 21763 SUBST1_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 21764 ASM_SIMP_TAC real_ss [COMPACT_CBALL, COMPACT_INTER, COMPACT_IMP_CLOSED], 21765 21766 X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN 21767 EXISTS_TAC ``ball(x:real,e) INTER s`` THEN 21768 EXISTS_TAC ``cball(x:real,e) INTER s`` THEN 21769 REWRITE_TAC[GSYM OPEN_IN_CONTAINS_CBALL] THEN 21770 ASM_SIMP_TAC real_ss [IN_INTER, CENTRE_IN_BALL, INTER_SUBSET] THEN 21771 ASM_SIMP_TAC real_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTER, BOUNDED_CBALL] THEN 21772 ONCE_REWRITE_TAC[INTER_COMM] THEN 21773 SIMP_TAC real_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN 21774 REWRITE_TAC [SUBSET_DEF, IN_INTER] THEN GEN_TAC THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN 21775 METIS_TAC[SUBSET_DEF, BALL_SUBSET_CBALL]]); 21776 21777val LOCALLY_COMPACT_INTER_CBALLS = store_thm ("LOCALLY_COMPACT_INTER_CBALLS", 21778 ``!s:real->bool. 21779 locally compact s <=> 21780 !x. x IN s ==> ?e. &0 < e /\ !d. d <= e ==> closed(cball(x,d) INTER s)``, 21781 GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_INTER_CBALL] THEN 21782 EQ_TAC THENL [ALL_TAC, METIS_TAC[REAL_LE_REFL]] THEN 21783 DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN POP_ASSUM (MP_TAC o SPEC ``x:real``) THEN 21784 ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_REWRITE_TAC[] THEN 21785 STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN 21786 GEN_TAC THEN DISCH_TAC THEN 21787 SUBGOAL_THEN 21788 ``cball(x:real,d) INTER s = cball(x,d) INTER cball(x,e) INTER s`` 21789 SUBST1_TAC THENL 21790 [ REWRITE_TAC[INTER_ASSOC, GSYM CBALL_MIN_INTER] THEN 21791 AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN 21792 BINOP_TAC THEN REWRITE_TAC[min_def] THEN PROVE_TAC [], 21793 ASM_SIMP_TAC real_ss [GSYM INTER_ASSOC, CLOSED_INTER, CLOSED_CBALL] ]); 21794 21795val LOCALLY_COMPACT_COMPACT = store_thm ("LOCALLY_COMPACT_COMPACT", 21796 ``!s:real->bool. 21797 locally compact s <=> 21798 !k. k SUBSET s /\ compact k 21799 ==> ?u v. k SUBSET u /\ 21800 u SUBSET v /\ 21801 v SUBSET s /\ 21802 open_in (subtopology euclidean s) u /\ 21803 compact v``, 21804 GEN_TAC THEN GEN_REWR_TAC LAND_CONV [LOCALLY_COMPACT] THEN EQ_TAC THEN 21805 REPEAT STRIP_TAC THENL 21806 [ALL_TAC, METIS_TAC[SING_SUBSET, COMPACT_SING]] THEN 21807 UNDISCH_TAC ``!x. x IN s ==> 21808 ?u v. x IN u /\ u SUBSET v /\ v SUBSET s /\ 21809 open_in (subtopology euclidean s) u /\ compact v`` THEN DISCH_TAC THEN 21810 FIRST_X_ASSUM(MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 21811 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 21812 MAP_EVERY X_GEN_TAC [``u:real->real->bool``, ``v:real->real->bool``] THEN 21813 DISCH_TAC THEN UNDISCH_TAC ``compact k`` THEN DISCH_TAC THEN 21814 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE 21815 [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN 21816 DISCH_THEN(MP_TAC o SPEC ``IMAGE (\x:real. k INTER u x) k``) THEN 21817 ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE, BIGUNION_IMAGE] THEN 21818 KNOW_TAC ``(!(x :real). 21819 x IN (k :real -> bool) ==> 21820 open_in (subtopology euclidean k) 21821 (k INTER (u :real -> real -> bool) x)) /\ 21822 k SUBSET {y | ?(x :real). x IN k /\ y IN k INTER u x}`` THENL 21823 [CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 21824 REPEAT STRIP_TAC THEN MATCH_MP_TAC OPEN_IN_SUBTOPOLOGY_INTER_SUBSET THEN 21825 EXISTS_TAC ``s:real->bool`` THEN ASM_REWRITE_TAC[] THEN 21826 MATCH_MP_TAC OPEN_IN_INTER THEN REWRITE_TAC[OPEN_IN_REFL] THEN 21827 ASM_SET_TAC[], 21828 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 21829 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN 21830 SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE, BIGUNION_IMAGE] THEN 21831 DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN 21832 EXISTS_TAC ``BIGUNION(IMAGE (u:real->real->bool) t)`` THEN 21833 EXISTS_TAC ``BIGUNION(IMAGE (v:real->real->bool) t)`` THEN 21834 REPEAT CONJ_TAC THENL 21835 [ALL_TAC, ALL_TAC, ALL_TAC, MATCH_MP_TAC OPEN_IN_BIGUNION, 21836 MATCH_MP_TAC COMPACT_BIGUNION THEN ASM_SIMP_TAC std_ss [IMAGE_FINITE]] THEN 21837 ASM_SET_TAC[]]); 21838 21839val LOCALLY_COMPACT_COMPACT_ALT = store_thm ("LOCALLY_COMPACT_COMPACT_ALT", 21840 ``!s:real->bool. 21841 locally compact s <=> 21842 !k. k SUBSET s /\ compact k 21843 ==> ?u. k SUBSET u /\ 21844 open_in (subtopology euclidean s) u /\ 21845 compact(closure u) /\ closure u SUBSET s``, 21846 GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_COMPACT] THEN EQ_TAC THEN 21847 DISCH_TAC THEN X_GEN_TAC ``k:real->bool`` THEN DISCH_TAC THEN 21848 FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN ASM_REWRITE_TAC[] THEN 21849 DISCH_THEN (X_CHOOSE_TAC ``u:real->bool``) THEN EXISTS_TAC ``u:real->bool`` THEN 21850 POP_ASSUM MP_TAC THEN 21851 METIS_TAC[CLOSURE_SUBSET, SUBSET_TRANS, CLOSURE_MINIMAL, 21852 COMPACT_CLOSURE, BOUNDED_SUBSET, COMPACT_EQ_BOUNDED_CLOSED]); 21853 21854val LOCALLY_COMPACT_COMPACT_SUBOPEN = store_thm ("LOCALLY_COMPACT_COMPACT_SUBOPEN", 21855 ``!s:real->bool. 21856 locally compact s <=> 21857 !k t. k SUBSET s /\ compact k /\ open t /\ k SUBSET t 21858 ==> ?u v. k SUBSET u /\ u SUBSET v /\ u SUBSET t /\ v SUBSET s /\ 21859 open_in (subtopology euclidean s) u /\ 21860 compact v``, 21861 GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_COMPACT] THEN 21862 EQ_TAC THEN DISCH_TAC THEN REPEAT STRIP_TAC THENL 21863 [FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN 21864 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 21865 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21866 STRIP_TAC THEN MAP_EVERY EXISTS_TAC 21867 [``u INTER t:real->bool``, ``closure(u INTER t:real->bool)``] THEN 21868 REWRITE_TAC[CLOSURE_SUBSET, INTER_SUBSET] THEN REPEAT CONJ_TAC THENL 21869 [ASM_SET_TAC[], 21870 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC ``closure(u:real->bool)`` THEN 21871 SIMP_TAC std_ss [SUBSET_CLOSURE, INTER_SUBSET] THEN 21872 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC ``v:real->bool`` THEN ASM_REWRITE_TAC[] THEN 21873 MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED], 21874 ASM_SIMP_TAC std_ss [OPEN_IN_INTER_OPEN], 21875 REWRITE_TAC[COMPACT_CLOSURE] THEN 21876 ASM_MESON_TAC[BOUNDED_SUBSET, INTER_SUBSET, SUBSET_TRANS, 21877 COMPACT_IMP_BOUNDED]], 21878 FIRST_X_ASSUM(MP_TAC o SPECL [``k:real->bool``, ``univ(:real)``]) THEN 21879 ASM_REWRITE_TAC[OPEN_UNIV, SUBSET_UNIV]]); 21880 21881val OPEN_IMP_LOCALLY_COMPACT = store_thm ("OPEN_IMP_LOCALLY_COMPACT", 21882 ``!s:real->bool. open s ==> locally compact s``, 21883 REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN 21884 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 21885 UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN FIRST_ASSUM 21886 (MP_TAC o REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN 21887 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 21888 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 21889 MAP_EVERY EXISTS_TAC [``ball(x:real,e)``, ``cball(x:real,e)``] THEN 21890 ASM_REWRITE_TAC[BALL_SUBSET_CBALL, CENTRE_IN_BALL, COMPACT_CBALL] THEN 21891 MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN ASM_REWRITE_TAC[OPEN_BALL] THEN 21892 MATCH_MP_TAC SUBSET_TRANS THEN METIS_TAC [BALL_SUBSET_CBALL]); 21893 21894val CLOSED_IMP_LOCALLY_COMPACT = store_thm ("CLOSED_IMP_LOCALLY_COMPACT", 21895 ``!s:real->bool. closed s ==> locally compact s``, 21896 REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN 21897 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN MAP_EVERY EXISTS_TAC 21898 [``s INTER ball(x:real,&1)``, ``s INTER cball(x:real,&1)``] THEN 21899 ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, INTER_SUBSET, REAL_LT_01] THEN 21900 ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN 21901 ASM_SIMP_TAC std_ss [CLOSED_INTER_COMPACT, COMPACT_CBALL] THEN 21902 MP_TAC(ISPECL [``x:real``, ``&1:real``] BALL_SUBSET_CBALL) THEN ASM_SET_TAC[]); 21903 21904val IS_INTERVAL_IMP_LOCALLY_COMPACT = store_thm ("IS_INTERVAL_IMP_LOCALLY_COMPACT", 21905 ``!s:real->bool. is_interval s ==> locally compact s``, 21906 REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN 21907 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 21908 MP_TAC(ISPECL [``s:real->bool``, ``x:real``] 21909 INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD) THEN 21910 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 21911 MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``, ``d:real``] THEN STRIP_TAC THEN 21912 MAP_EVERY EXISTS_TAC 21913 [``s INTER ball(x:real,d)``, ``interval[a:real,b]``] THEN 21914 ASM_SIMP_TAC std_ss [COMPACT_INTERVAL, OPEN_IN_OPEN_INTER, OPEN_BALL] THEN 21915 ASM_REWRITE_TAC[CENTRE_IN_BALL, IN_INTER] THEN ASM_SET_TAC[]); 21916 21917val LOCALLY_COMPACT_UNIV = store_thm ("LOCALLY_COMPACT_UNIV", 21918 ``locally compact univ(:real)``, 21919 SIMP_TAC std_ss [OPEN_IMP_LOCALLY_COMPACT, OPEN_UNIV]); 21920 21921val LOCALLY_COMPACT_INTER = store_thm ("LOCALLY_COMPACT_INTER", 21922 ``!s t:real->bool. 21923 locally compact s /\ locally compact t 21924 ==> locally compact (s INTER t)``, 21925 MATCH_MP_TAC LOCALLY_INTER THEN REWRITE_TAC[COMPACT_INTER]); 21926 21927val LOCALLY_COMPACT_OPEN_IN = store_thm ("LOCALLY_COMPACT_OPEN_IN", 21928 ``!s t:real->bool. 21929 open_in (subtopology euclidean s) t /\ locally compact s 21930 ==> locally compact t``, 21931 REWRITE_TAC[OPEN_IN_OPEN] THEN REPEAT STRIP_TAC THEN 21932 ASM_SIMP_TAC std_ss [LOCALLY_COMPACT_INTER, OPEN_IMP_LOCALLY_COMPACT]); 21933 21934val LOCALLY_COMPACT_CLOSED_IN = store_thm ("LOCALLY_COMPACT_CLOSED_IN", 21935 ``!s t:real->bool. 21936 closed_in (subtopology euclidean s) t /\ locally compact s 21937 ==> locally compact t``, 21938 REWRITE_TAC[CLOSED_IN_CLOSED] THEN REPEAT STRIP_TAC THEN 21939 ASM_SIMP_TAC std_ss [LOCALLY_COMPACT_INTER, CLOSED_IMP_LOCALLY_COMPACT]); 21940 21941val LOCALLY_COMPACT_DELETE = store_thm ("LOCALLY_COMPACT_DELETE", 21942 ``!s a:real. locally compact s ==> locally compact (s DELETE a)``, 21943 REPEAT STRIP_TAC THEN MATCH_MP_TAC LOCALLY_COMPACT_OPEN_IN THEN 21944 EXISTS_TAC ``s:real->bool`` THEN 21945 ASM_SIMP_TAC std_ss [OPEN_IN_DELETE, OPEN_IN_REFL]); 21946 21947val HOMEOMORPHIC_LOCAL_COMPACTNESS = store_thm ("HOMEOMORPHIC_LOCAL_COMPACTNESS", 21948 ``!s t:real->bool. 21949 s homeomorphic t ==> (locally compact s <=> locally compact t)``, 21950 MATCH_MP_TAC HOMEOMORPHIC_LOCALLY THEN 21951 REWRITE_TAC[HOMEOMORPHIC_COMPACTNESS]); 21952 21953val LOCALLY_COMPACT_TRANSLATION_EQ = store_thm ("LOCALLY_COMPACT_TRANSLATION_EQ", 21954 ``!a:real s. locally compact (IMAGE (\x. a + x) s) <=> 21955 locally compact s``, 21956 MATCH_MP_TAC LOCALLY_TRANSLATION THEN 21957 REWRITE_TAC[COMPACT_TRANSLATION_EQ]); 21958 21959val LOCALLY_CLOSED = store_thm ("LOCALLY_CLOSED", 21960 ``!s:real->bool. locally closed s <=> locally compact s``, 21961 GEN_TAC THEN EQ_TAC THENL 21962 [ALL_TAC, MESON_TAC[LOCALLY_MONO, COMPACT_IMP_CLOSED]] THEN 21963 REWRITE_TAC[locally] THEN DISCH_TAC THEN 21964 MAP_EVERY X_GEN_TAC [``w:real->bool``, ``x:real``] THEN STRIP_TAC THEN 21965 FIRST_X_ASSUM(MP_TAC o SPECL [``w:real->bool``, ``x:real``]) THEN 21966 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 21967 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 21968 STRIP_TAC THEN 21969 EXISTS_TAC ``u INTER ball(x:real,&1)`` THEN 21970 EXISTS_TAC ``v INTER cball(x:real,&1)`` THEN 21971 ASM_SIMP_TAC std_ss [OPEN_IN_INTER_OPEN, OPEN_BALL] THEN 21972 ASM_SIMP_TAC std_ss [CLOSED_INTER_COMPACT, COMPACT_CBALL] THEN 21973 ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, REAL_LT_01] THEN 21974 MP_TAC(ISPEC ``x:real`` BALL_SUBSET_CBALL) THEN ASM_SET_TAC[]); 21975 21976val LOCALLY_COMPACT_OPEN_UNION = store_thm ("LOCALLY_COMPACT_OPEN_UNION", 21977 ``!s t:real->bool. 21978 locally compact s /\ locally compact t /\ 21979 open_in (subtopology euclidean (s UNION t)) s /\ 21980 open_in (subtopology euclidean (s UNION t)) t 21981 ==> locally compact (s UNION t)``, 21982 REPEAT GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_INTER_CBALL, IN_UNION] THEN 21983 STRIP_TAC THEN X_GEN_TAC ``x:real`` THEN STRIP_TAC THENL 21984 [UNDISCH_TAC ``!x. x IN s ==> ?e. 0 < e /\ closed (cball (x,e) INTER s)`` THEN 21985 DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``x:real``) THEN 21986 UNDISCH_TAC ``open_in (subtopology euclidean (s UNION t)) s`` THEN DISCH_TAC THEN 21987 FIRST_ASSUM (MP_TAC o REWRITE_RULE [OPEN_IN_CONTAINS_CBALL]), 21988 UNDISCH_TAC ``!x. x IN t ==> ?e. 0 < e /\ closed (cball (x,e) INTER t)`` THEN 21989 DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``x:real``) THEN 21990 UNDISCH_TAC ``open_in (subtopology euclidean (s UNION t)) t`` THEN DISCH_TAC THEN 21991 FIRST_ASSUM (MP_TAC o REWRITE_RULE [OPEN_IN_CONTAINS_CBALL])] THEN 21992 DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN 21993 UNDISCH_TAC ``!x. x IN s ==> ?e. 0 < e /\ closed (cball (x,e) INTER s)`` THEN 21994 DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN 21995 UNDISCH_TAC `` !x. x IN t ==> ?e. 0 < e /\ closed (cball (x,e) INTER t)`` THEN 21996 DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC [] THENL 21997 [DISCH_TAC THEN DISCH_THEN (X_CHOOSE_TAC ``e:real``), 21998 DISCH_THEN (X_CHOOSE_TAC ``e:real``) THEN DISCH_TAC] THEN 21999 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 22000 EXISTS_TAC ``min d e:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 22001 REWRITE_TAC[CBALL_MIN_INTER, INTER_ASSOC] THEN 22002 FIRST_ASSUM(MP_TAC o MATCH_MP (SET_RULE 22003 ``u INTER st SUBSET s ==> s SUBSET st ==> (u INTER st = u INTER s)``)) THEN 22004 REWRITE_TAC[SUBSET_UNION] THEN 22005 ONCE_REWRITE_TAC [SET_RULE ``a INTER b INTER c = b INTER (a INTER c)``] THEN 22006 DISCH_THEN SUBST1_TAC THEN 22007 ONCE_REWRITE_TAC [SET_RULE ``a INTER (b INTER c) = b INTER (a INTER c)``] THEN 22008 METIS_TAC[CLOSED_INTER, CLOSED_CBALL, INTER_ACI]); 22009 22010val LOCALLY_COMPACT_CLOSED_UNION = store_thm ("LOCALLY_COMPACT_CLOSED_UNION", 22011 ``!s t:real->bool. 22012 locally compact s /\ locally compact t /\ 22013 closed_in (subtopology euclidean (s UNION t)) s /\ 22014 closed_in (subtopology euclidean (s UNION t)) t 22015 ==> locally compact (s UNION t)``, 22016 REPEAT GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_INTER_CBALL, IN_UNION] THEN 22017 STRIP_TAC THEN X_GEN_TAC ``x:real`` THEN 22018 DISCH_THEN(STRIP_ASSUME_TAC o MATCH_MP (TAUT 22019 `p \/ q ==> p /\ q \/ p /\ ~q \/ q /\ ~p`)) 22020 THENL 22021 [FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN 22022 FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN 22023 ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN 22024 X_GEN_TAC ``d:real`` THEN STRIP_TAC THEN 22025 X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN 22026 EXISTS_TAC ``min d e:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN 22027 SIMP_TAC std_ss [SET_RULE ``u INTER (s UNION t) = u INTER s UNION u INTER t``] THEN 22028 MATCH_MP_TAC CLOSED_UNION THEN REWRITE_TAC[CBALL_MIN_INTER] THEN CONJ_TAC THENL 22029 [ONCE_REWRITE_TAC [SET_RULE ``a INTER b INTER c = b INTER (a INTER c)``], 22030 REWRITE_TAC [GSYM INTER_ASSOC]] THEN 22031 METIS_TAC[CLOSED_CBALL, CLOSED_INTER, INTER_ACI], 22032 UNDISCH_TAC ``!x. x IN s ==> ?e. 0 < e /\ closed (cball (x,e) INTER s)`` THEN 22033 DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 22034 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 22035 UNDISCH_TAC ``closed_in (subtopology euclidean (s UNION t)) t`` THEN DISCH_TAC THEN 22036 FIRST_X_ASSUM (STRIP_ASSUME_TAC o REWRITE_RULE [closed_in]), 22037 FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 22038 DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN 22039 UNDISCH_TAC ``closed_in (subtopology euclidean (s UNION t)) s`` THEN DISCH_TAC THEN 22040 FIRST_X_ASSUM (STRIP_ASSUME_TAC o REWRITE_RULE [closed_in])] THEN 22041 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_CONTAINS_CBALL]) THEN 22042 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, IN_DIFF, IN_UNION] THEN 22043 DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN ASM_SIMP_TAC std_ss [] THEN 22044 DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN 22045 EXISTS_TAC ``min d e:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THENL 22046 [SUBGOAL_THEN ``cball (x:real,min d e) INTER (s UNION t) = 22047 cball(x,d) INTER cball (x,e) INTER s`` SUBST1_TAC 22048 THENL [REWRITE_TAC[CBALL_MIN_INTER] THEN ASM_SET_TAC[], ALL_TAC], 22049 SUBGOAL_THEN ``cball (x:real,min d e) INTER (s UNION t) = 22050 cball(x,d) INTER cball (x,e) INTER t`` SUBST1_TAC 22051 THENL [REWRITE_TAC[CBALL_MIN_INTER] THEN ASM_SET_TAC[], ALL_TAC]] THEN 22052 ASM_MESON_TAC[GSYM INTER_ASSOC, CLOSED_INTER, CLOSED_CBALL]); 22053 22054val OPEN_IN_LOCALLY_COMPACT = store_thm ("OPEN_IN_LOCALLY_COMPACT", 22055 ``!s t:real->bool. 22056 locally compact s 22057 ==> (open_in (subtopology euclidean s) t <=> 22058 t SUBSET s /\ 22059 !k. compact k /\ k SUBSET s 22060 ==> open_in (subtopology euclidean k) (k INTER t))``, 22061 REPEAT(STRIP_TAC ORELSE EQ_TAC) THENL 22062 [ASM_MESON_TAC[OPEN_IN_IMP_SUBSET], 22063 UNDISCH_TAC ``open_in (subtopology euclidean s) t`` THEN DISCH_TAC THEN 22064 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN]) THEN 22065 REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN (X_CHOOSE_TAC ``t':real->bool``) THEN 22066 EXISTS_TAC ``t':real->bool`` THEN ASM_SET_TAC[], 22067 ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN 22068 X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN 22069 UNDISCH_TAC ``locally compact s`` THEN DISCH_TAC THEN 22070 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LOCALLY_COMPACT]) THEN 22071 DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN 22072 KNOW_TAC ``a IN s:real->bool`` THENL 22073 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 22074 SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM]] THEN 22075 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 22076 STRIP_TAC THEN EXISTS_TAC ``t INTER u:real->bool`` THEN 22077 ASM_REWRITE_TAC[IN_INTER, INTER_SUBSET] THEN 22078 MATCH_MP_TAC OPEN_IN_TRANS THEN EXISTS_TAC ``u:real->bool`` THEN 22079 ASM_REWRITE_TAC[] THEN 22080 FIRST_X_ASSUM(MP_TAC o SPEC ``closure u:real->bool``) THEN 22081 KNOW_TAC ``compact (closure u) /\ closure u SUBSET s`` THENL 22082 [SUBGOAL_THEN ``(closure u:real->bool) SUBSET v`` MP_TAC THENL 22083 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED], 22084 REWRITE_TAC[COMPACT_CLOSURE] THEN 22085 ASM_MESON_TAC[SUBSET_TRANS, BOUNDED_SUBSET, COMPACT_IMP_BOUNDED]], 22086 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 22087 REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN (X_CHOOSE_TAC ``t':real->bool``) THEN 22088 EXISTS_TAC ``t':real->bool`` THEN ASM_REWRITE_TAC [] THEN 22089 MP_TAC(ISPEC ``u:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[]]]); 22090 22091val LOCALLY_COMPACT_PROPER_IMAGE_EQ = store_thm ("LOCALLY_COMPACT_PROPER_IMAGE_EQ", 22092 ``!f:real->real s. 22093 f continuous_on s /\ 22094 (!k. k SUBSET (IMAGE f s) /\ compact k 22095 ==> compact {x | x IN s /\ f x IN k}) 22096 ==> (locally compact s <=> locally compact (IMAGE f s))``, 22097 REPEAT STRIP_TAC THEN 22098 MP_TAC(ISPECL [``f:real->real``, ``s:real->bool``, 22099 ``IMAGE (f:real->real) s``] PROPER_MAP) THEN 22100 ASM_REWRITE_TAC[SUBSET_REFL] THEN STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL 22101 [REWRITE_TAC[LOCALLY_COMPACT_ALT] THEN X_GEN_TAC ``y:real`` THEN 22102 DISCH_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``y:real``) THEN 22103 ASM_REWRITE_TAC[] THEN UNDISCH_TAC ``locally compact s`` THEN DISCH_TAC THEN 22104 FIRST_ASSUM(MP_TAC o REWRITE_RULE [LOCALLY_COMPACT_COMPACT_ALT]) THEN 22105 DISCH_THEN(MP_TAC o SPEC ``{x | x IN s /\ ((f:real->real) x = y)}``) THEN 22106 ONCE_REWRITE_TAC [METIS [] ``(f x = y) = (\x. (f x = y)) x``] THEN 22107 ASM_SIMP_TAC std_ss [SUBSET_RESTRICT] THEN 22108 DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN 22109 SUBGOAL_THEN 22110 ``?v. open_in (subtopology euclidean (IMAGE f s)) v /\ 22111 y IN v /\ 22112 {x | x IN s /\ (f:real->real) x IN v} SUBSET u`` 22113 MP_TAC THENL 22114 [GEN_REWR_TAC (BINDER_CONV o RAND_CONV o LAND_CONV) 22115 [GSYM SING_SUBSET] THEN 22116 MATCH_MP_TAC CLOSED_MAP_OPEN_SUPERSET_PREIMAGE THEN 22117 ASM_REWRITE_TAC[SING_SUBSET, IN_SING], 22118 DISCH_THEN (X_CHOOSE_TAC ``v:real->bool``) THEN EXISTS_TAC ``v:real->bool`` THEN 22119 POP_ASSUM MP_TAC THEN 22120 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN 22121 SUBGOAL_THEN ``closure v SUBSET IMAGE (f:real->real) (closure u)`` 22122 ASSUME_TAC THENL 22123 [MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC ``closure(IMAGE (f:real->real) u)`` THEN 22124 CONJ_TAC THENL 22125 [MATCH_MP_TAC SUBSET_CLOSURE THEN 22126 REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET)) THEN 22127 ASM_SET_TAC[], 22128 MATCH_MP_TAC CLOSURE_MINIMAL THEN 22129 SIMP_TAC std_ss [CLOSURE_SUBSET, IMAGE_SUBSET] THEN 22130 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN 22131 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 22132 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]], 22133 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 22134 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE] THEN 22135 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] 22136 BOUNDED_SUBSET)) THEN 22137 MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN 22138 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN 22139 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]], 22140 REWRITE_TAC[LOCALLY_COMPACT_ALT] THEN 22141 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22142 UNDISCH_TAC ``locally compact (IMAGE (f :real -> real) (s :real -> bool))`` THEN 22143 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LOCALLY_COMPACT_ALT]) THEN 22144 DISCH_THEN(MP_TAC o SPEC ``(f:real->real) x``) THEN 22145 ASM_SIMP_TAC std_ss [FUN_IN_IMAGE] THEN 22146 DISCH_THEN(X_CHOOSE_THEN ``v:real->bool`` STRIP_ASSUME_TAC) THEN 22147 FIRST_X_ASSUM(MP_TAC o SPEC ``closure v:real->bool``) THEN 22148 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN 22149 EXISTS_TAC ``{x | x IN s /\ (f:real->real) x IN v}`` THEN 22150 ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN CONJ_TAC THENL 22151 [MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN 22152 ASM_MESON_TAC[SUBSET_REFL], 22153 ALL_TAC] THEN 22154 SUBGOAL_THEN 22155 ``closure {x | x IN s /\ f x IN v} SUBSET 22156 {x | x IN s /\ (f:real->real) x IN closure v}`` 22157 ASSUME_TAC THENL 22158 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED] THEN 22159 MP_TAC(ISPEC ``v:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[], 22160 CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN 22161 SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE] THEN 22162 METIS_TAC[COMPACT_IMP_BOUNDED, BOUNDED_SUBSET]]]); 22163 22164val LOCALLY_COMPACT_PROPER_IMAGE = store_thm ("LOCALLY_COMPACT_PROPER_IMAGE", 22165 ``!f:real->real s. 22166 f continuous_on s /\ 22167 (!k. k SUBSET (IMAGE f s) /\ compact k 22168 ==> compact {x | x IN s /\ f x IN k}) /\ 22169 locally compact s 22170 ==> locally compact (IMAGE f s)``, 22171 METIS_TAC[LOCALLY_COMPACT_PROPER_IMAGE_EQ]); 22172 22173val MUMFORD_LEMMA = store_thm ("MUMFORD_LEMMA", 22174 ``!f:real->real s t y. 22175 f continuous_on s /\ IMAGE f s SUBSET t /\ locally compact s /\ 22176 y IN t /\ compact {x | x IN s /\ (f x = y)} 22177 ==> ?u v. open_in (subtopology euclidean s) u /\ 22178 open_in (subtopology euclidean t) v /\ 22179 {x | x IN s /\ (f x = y)} SUBSET u /\ y IN v /\ 22180 IMAGE f u SUBSET v /\ 22181 (!k. k SUBSET v /\ compact k 22182 ==> compact {x | x IN u /\ f x IN k})``, 22183 REPEAT STRIP_TAC THEN 22184 FIRST_ASSUM(MP_TAC o SPEC ``{x | x IN s /\ ((f:real->real) x = y)}`` o 22185 REWRITE_RULE [LOCALLY_COMPACT_COMPACT]) THEN 22186 ASM_SIMP_TAC std_ss [SUBSET_RESTRICT, LEFT_IMP_EXISTS_THM] THEN 22187 MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN 22188 STRIP_TAC THEN 22189 SUBGOAL_THEN ``(closure u:real->bool) SUBSET v`` ASSUME_TAC THENL 22190 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED], 22191 ALL_TAC] THEN 22192 SUBGOAL_THEN ``compact(closure u:real->bool)`` ASSUME_TAC THENL 22193 [ASM_REWRITE_TAC[COMPACT_CLOSURE] THEN 22194 ASM_MESON_TAC[BOUNDED_SUBSET, COMPACT_IMP_BOUNDED], 22195 ALL_TAC] THEN 22196 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN 22197 SUBGOAL_THEN 22198 ``!b. open_in (subtopology euclidean t) b /\ y IN b 22199 ==> u INTER {x | x IN s /\ (f:real->real) x IN b} PSUBSET 22200 closure u INTER {x | x IN s /\ (f:real->real) x IN b}`` 22201 MP_TAC THENL 22202 [REPEAT STRIP_TAC THEN REWRITE_TAC[PSUBSET_DEF] THEN 22203 SIMP_TAC std_ss [CLOSURE_SUBSET, 22204 SET_RULE ``s SUBSET t ==> s INTER u SUBSET t INTER u``] THEN 22205 MATCH_MP_TAC(MESON[] ``!P. ~P s /\ P t ==> ~(s = t)``) THEN 22206 EXISTS_TAC 22207 ``\a. !k. k SUBSET b /\ compact k 22208 ==> compact {x | x IN a /\ (f:real->real) x IN k}`` THEN 22209 SIMP_TAC std_ss [] THEN CONJ_TAC THENL 22210 [KNOW_TAC ``(open_in (subtopology euclidean s) (u INTER {x | x IN s /\ f x IN b}) 22211 ==> {x | x IN s /\ (f x = y)} SUBSET u INTER {x | x IN s /\ f x IN b} 22212 ==> IMAGE f (u INTER {x | x IN s /\ f x IN b}) SUBSET b 22213 ==> ~(!k. k SUBSET b /\ compact k 22214 ==> compact 22215 {x | x IN u INTER {x | x IN s /\ f x IN b} /\ f x IN k})) 22216 ==> ~(!k. k SUBSET b /\ compact k 22217 ==> compact 22218 {x | x IN u INTER {x | x IN s /\ f x IN b} /\ f x IN k})`` THENL 22219 [ALL_TAC, METIS_TAC []] THEN 22220 KNOW_TAC ``open_in (subtopology euclidean s) 22221 (u INTER {x | x IN s /\ (f:real->real) x IN b})`` THENL 22222 [MATCH_MP_TAC OPEN_IN_INTER THEN ASM_SIMP_TAC std_ss [] THEN 22223 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN ASM_SET_TAC[], 22224 ASM_SET_TAC[]], 22225 X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN 22226 SUBGOAL_THEN 22227 ``{x | x IN closure u INTER {x | x IN s /\ f x IN b} /\ f x IN k} = 22228 v INTER {x | x IN closure u /\ (f:real->real) x IN k}`` 22229 SUBST1_TAC THENL [ASM_SET_TAC[], MATCH_MP_TAC COMPACT_INTER_CLOSED] THEN 22230 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN 22231 ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED, CLOSED_CLOSURE] THEN 22232 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, SUBSET_TRANS]], 22233 DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC 22234 ``t INTER ball(y:real,inv(&n + &1))``) THEN 22235 SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL, IN_INTER, CENTRE_IN_BALL] THEN 22236 ASM_REWRITE_TAC[REAL_LT_INV_EQ, 22237 METIS [REAL_LT, REAL_OF_NUM_ADD, GSYM ADD1, LESS_0] ``&0 < &n + &1:real``] THEN 22238 KNOW_TAC ``~(!n. ?x. x IN closure u /\ 22239 ~(x IN u) /\ 22240 x IN {x | x IN s /\ f x IN t /\ f x IN ball (y,inv (&n + &1))})`` THENL 22241 [ALL_TAC, 22242 METIS_TAC [CLOSURE_SUBSET, REAL_OF_NUM_ADD, SET_RULE 22243 ``u SUBSET u' 22244 ==> (u INTER t PSUBSET u' INTER t <=> 22245 ?x. x IN u' /\ ~(x IN u) /\ x IN t)``]] THEN 22246 KNOW_TAC ``~(?x. (!n. x n IN closure u) /\ 22247 (!n. ~(x n IN u)) /\ 22248 (!n. x n IN s) /\ 22249 (!n. f (x n) IN t) /\ 22250 (!n. dist (y,f (x n)) < inv (&n + &1)))`` THENL 22251 [ALL_TAC, 22252 SIMP_TAC std_ss [SKOLEM_THM, GSPECIFICATION, IN_BALL, FORALL_AND_THM] THEN 22253 METIS_TAC [SKOLEM_THM]] THEN 22254 DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN 22255 MP_TAC(ISPEC ``closure u:real->bool`` compact) THEN 22256 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``x:num->real``) THEN 22257 ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN 22258 MAP_EVERY X_GEN_TAC [``l:real``, ``r:num->num``] THEN 22259 CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN 22260 SUBGOAL_THEN ``(f:real->real) l = y`` ASSUME_TAC THENL 22261 [MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN 22262 EXISTS_TAC ``(f:real->real) o x o (r:num->num)`` THEN 22263 ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN CONJ_TAC THENL 22264 [SUBGOAL_THEN ``(f:real->real) continuous_on closure u`` MP_TAC THENL 22265 [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, SUBSET_TRANS], ALL_TAC] THEN 22266 REWRITE_TAC[CONTINUOUS_ON_SEQUENTIALLY] THEN 22267 DISCH_THEN MATCH_MP_TAC THEN ASM_SIMP_TAC std_ss [o_THM], 22268 REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC LIM_SUBSEQUENCE THEN 22269 ASM_SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN 22270 CONJ_TAC THENL [METIS_TAC [], ALL_TAC] THEN 22271 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN 22272 MP_TAC(SPEC ``e:real`` REAL_ARCH_INV) THEN 22273 ASM_REWRITE_TAC[] THEN DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN 22274 EXISTS_TAC ``N:num`` THEN X_GEN_TAC ``n:num`` THEN 22275 DISCH_TAC THEN ONCE_REWRITE_TAC[DIST_SYM] THEN 22276 MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC ``inv(&n + &1:real)`` THEN 22277 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_TRANS THEN 22278 EXISTS_TAC ``inv(&N:real)`` THEN ASM_REWRITE_TAC[] THEN 22279 MATCH_MP_TAC REAL_LT_INV2 THEN 22280 ASM_SIMP_TAC arith_ss [REAL_OF_NUM_ADD, REAL_LT]], 22281 UNDISCH_TAC ``open_in (subtopology euclidean s) u`` THEN DISCH_TAC THEN 22282 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [open_in]) THEN 22283 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC ``l:real``)) THEN 22284 SIMP_TAC std_ss [NOT_IMP, NOT_EXISTS_THM] THEN 22285 CONJ_TAC THENL [ASM_SET_TAC[], X_GEN_TAC ``e:real`` THEN 22286 CCONTR_TAC THEN FULL_SIMP_TAC std_ss []] THEN 22287 UNDISCH_TAC ``(((x :num -> real) o (r :num -> num) --> (l :real)) 22288 sequentially :bool)`` THEN DISCH_TAC THEN 22289 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LIM_SEQUENTIALLY]) THEN 22290 DISCH_THEN(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN 22291 DISCH_THEN(X_CHOOSE_THEN ``n:num`` (MP_TAC o SPEC ``n:num``)) THEN 22292 ASM_SIMP_TAC std_ss [LESS_EQ_REFL, o_THM] THEN ASM_SET_TAC[]]]); 22293 22294(* ------------------------------------------------------------------------- *) 22295(* Locally compact sets are closed in an open set and are homeomorphic *) 22296(* to an absolutely closed set if we have one more dimension to play with. *) 22297(* ------------------------------------------------------------------------- *) 22298 22299val LOCALLY_COMPACT_OPEN_INTER_CLOSURE = store_thm ("LOCALLY_COMPACT_OPEN_INTER_CLOSURE", 22300 ``!s:real->bool. locally compact s ==> ?t. open t /\ (s = t INTER closure s)``, 22301 GEN_TAC THEN SIMP_TAC std_ss [LOCALLY_COMPACT, OPEN_IN_OPEN, CLOSED_IN_CLOSED] THEN 22302 SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM] THEN 22303 ONCE_REWRITE_TAC [METIS [] ``(x IN s INTER t /\ s INTER t SUBSET v /\ 22304 v SUBSET s /\ open t /\ compact v) = 22305 (\v t. x IN s INTER t /\ s INTER t SUBSET v /\ 22306 v SUBSET s /\ open t /\ compact v) v t``] THEN 22307 REWRITE_TAC[GSYM CONJ_ASSOC, TAUT `p /\ (x = y) /\ q <=> (x = y) /\ p /\ q`] THEN 22308 ONCE_REWRITE_TAC[MESON[] ``(?v t. P v t) <=> (?t v. P v t)``] THEN 22309 DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN 22310 SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN 22311 MAP_EVERY X_GEN_TAC [``u:real->real->bool``, ``v:real->real->bool``] THEN 22312 DISCH_TAC THEN EXISTS_TAC ``BIGUNION (IMAGE (u:real->real->bool) s)`` THEN 22313 ASM_SIMP_TAC std_ss [CLOSED_CLOSURE, OPEN_BIGUNION, FORALL_IN_IMAGE] THEN 22314 REWRITE_TAC[INTER_BIGUNION] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC 22315 ``BIGUNION {v INTER s | v | v IN IMAGE (u:real->real->bool) s}`` THEN 22316 CONJ_TAC THENL 22317 [SIMP_TAC std_ss [BIGUNION_GSPEC, EXISTS_IN_IMAGE] THEN ASM_SET_TAC[], ALL_TAC] THEN 22318 AP_TERM_TAC THEN 22319 ONCE_REWRITE_TAC [METIS [] ``v INTER s = (\v. v INTER s:real->bool) v``] THEN 22320 MATCH_MP_TAC(SET_RULE ``(!x. x IN s ==> (f(g x) = f'(g x))) 22321 ==> ({f x | x IN IMAGE g s} = {f' x | x IN IMAGE g s})``) THEN 22322 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22323 SIMP_TAC std_ss [GSYM SUBSET_ANTISYM_EQ] THEN CONJ_TAC THENL 22324 [MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[], 22325 REWRITE_TAC[SUBSET_INTER, INTER_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN 22326 EXISTS_TAC ``closure((u:real->real->bool) x INTER s)`` THEN 22327 ASM_SIMP_TAC std_ss [OPEN_INTER_CLOSURE_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN 22328 EXISTS_TAC ``(v:real->real->bool) x`` THEN 22329 ASM_SIMP_TAC std_ss [] THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN 22330 ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED] THEN ASM_SET_TAC[]]); 22331 22332val LOCALLY_COMPACT_CLOSED_IN_OPEN = store_thm ("LOCALLY_COMPACT_CLOSED_IN_OPEN", 22333 ``!s:real->bool. 22334 locally compact s ==> ?t. open t /\ closed_in (subtopology euclidean t) s``, 22335 GEN_TAC THEN 22336 DISCH_THEN(MP_TAC o MATCH_MP LOCALLY_COMPACT_OPEN_INTER_CLOSURE) THEN 22337 STRIP_TAC THEN EXISTS_TAC ``t:real->bool`` THEN ASM_SIMP_TAC std_ss [] THEN 22338 FIRST_X_ASSUM SUBST1_TAC THEN 22339 SIMP_TAC std_ss [CLOSED_IN_CLOSED_INTER, CLOSED_CLOSURE]); 22340 22341val LOCALLY_COMPACT_CLOSED_INTER_OPEN = store_thm ("LOCALLY_COMPACT_CLOSED_INTER_OPEN", 22342 ``!s:real->bool. 22343 locally compact s <=> ?t u. closed t /\ open u /\ (s = t INTER u)``, 22344 MESON_TAC[CLOSED_IMP_LOCALLY_COMPACT, OPEN_IMP_LOCALLY_COMPACT, 22345 LOCALLY_COMPACT_INTER, INTER_COMM, CLOSED_CLOSURE, 22346 LOCALLY_COMPACT_OPEN_INTER_CLOSURE]); 22347 22348(* ------------------------------------------------------------------------- *) 22349(* Forms of the Baire propery of dense sets. *) 22350(* ------------------------------------------------------------------------- *) 22351 22352val BAIRE = store_thm ("BAIRE", 22353 ``!g s:real->bool. 22354 locally compact s /\ COUNTABLE g /\ 22355 (!t. t IN g 22356 ==> open_in (subtopology euclidean s) t /\ s SUBSET closure t) 22357 ==> s SUBSET closure(BIGINTER g)``, 22358 REPEAT STRIP_TAC THEN ASM_CASES_TAC ``g:(real->bool)->bool = {}`` THEN 22359 ASM_REWRITE_TAC[BIGINTER_EMPTY, CLOSURE_UNIV, SUBSET_UNIV] THEN 22360 MP_TAC(ISPEC ``g:(real->bool)->bool`` COUNTABLE_AS_IMAGE) THEN 22361 ASM_REWRITE_TAC[] THEN 22362 MAP_EVERY (C UNDISCH_THEN (K ALL_TAC)) 22363 [``COUNTABLE(g:(real->bool)->bool)``, 22364 ``~(g:(real->bool)->bool = {})``] THEN 22365 DISCH_THEN(X_CHOOSE_THEN ``g:num->real->bool`` SUBST_ALL_TAC) THEN 22366 RULE_ASSUM_TAC(SIMP_RULE std_ss [FORALL_IN_IMAGE, IN_UNIV]) THEN 22367 REWRITE_TAC[SUBSET_DEF, CLOSURE_NONEMPTY_OPEN_INTER] THEN 22368 X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN 22369 X_GEN_TAC ``v:real->bool`` THEN STRIP_TAC THEN 22370 MP_TAC(ISPECL 22371 [``\n:num u:real->bool. 22372 open_in (subtopology euclidean s) u /\ ~(u = {}) /\ u SUBSET v``, 22373 ``\n:num u v:real->bool. 22374 ?c. compact c /\ v SUBSET c /\ c SUBSET u /\ c SUBSET (g n)``] 22375 DEPENDENT_CHOICE) THEN 22376 SIMP_TAC std_ss [] THEN 22377 KNOW_TAC ``(?(a :real -> bool). 22378 open_in (subtopology euclidean (s :real -> bool)) a /\ 22379 a <> ({} :real -> bool) /\ a SUBSET (v :real -> bool)) /\ 22380 (!(n :num) (x :real -> bool). 22381 open_in (subtopology euclidean s) x /\ x <> ({} :real -> bool) /\ 22382 x SUBSET v ==> 22383 ?(y :real -> bool). 22384 (open_in (subtopology euclidean s) y /\ y <> ({} :real -> bool) /\ 22385 y SUBSET v) /\ 22386 ?(c :real -> bool). 22387 compact c /\ y SUBSET c /\ c SUBSET x /\ 22388 c SUBSET (g :num -> real -> bool) n)`` THENL 22389 [CONJ_TAC THENL 22390 [EXISTS_TAC ``s INTER v:real->bool`` THEN 22391 ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER] THEN ASM_SET_TAC[], 22392 ALL_TAC] THEN 22393 MAP_EVERY X_GEN_TAC [``n:num``, ``w:real->bool``] THEN STRIP_TAC THEN 22394 FIRST_X_ASSUM(STRIP_ASSUME_TAC o SPEC ``n:num``) THEN 22395 SUBGOAL_THEN ``?b:real. b IN w /\ b IN g(n:num)`` 22396 STRIP_ASSUME_TAC THENL 22397 [UNDISCH_TAC ``open_in (subtopology euclidean s) (w:real->bool)`` THEN 22398 SIMP_TAC std_ss [OPEN_IN_OPEN, LEFT_IMP_EXISTS_THM] THEN 22399 X_GEN_TAC ``t:real->bool`` THEN 22400 STRIP_TAC THEN ASM_REWRITE_TAC[IN_INTER] THEN 22401 UNDISCH_TAC ``s SUBSET closure((g:num->real->bool) n)`` THEN 22402 REWRITE_TAC[SUBSET_DEF, CLOSURE_NONEMPTY_OPEN_INTER] THEN 22403 FIRST_X_ASSUM(X_CHOOSE_TAC ``x:real`` o 22404 REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN 22405 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN 22406 KNOW_TAC ``x:real IN s`` THENL [ASM_SET_TAC[], DISCH_TAC THEN 22407 ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 22408 DISCH_THEN(MP_TAC o SPEC ``t:real->bool``) THEN 22409 KNOW_TAC ``x:real IN t /\ open t`` THENL 22410 [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN 22411 FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN SET_TAC[], 22412 UNDISCH_TAC ``locally compact s`` THEN DISCH_TAC THEN 22413 FIRST_ASSUM(MP_TAC o REWRITE_RULE [locally]) THEN 22414 DISCH_THEN(MP_TAC o SPECL 22415 [``w INTER (g:num->real->bool) n``, ``b:real``]) THEN 22416 ASM_SIMP_TAC std_ss [OPEN_IN_INTER, OPEN_IN_REFL, IN_INTER] THEN 22417 SIMP_TAC std_ss [GSYM RIGHT_EXISTS_AND_THM] THEN 22418 STRIP_TAC THEN MAP_EVERY EXISTS_TAC [``u:real->bool``,``v':real->bool``] THEN 22419 ASM_SET_TAC[]], 22420 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN 22421 SIMP_TAC std_ss [SKOLEM_THM, GSYM RIGHT_EXISTS_AND_THM, LEFT_IMP_EXISTS_THM] THEN 22422 MAP_EVERY X_GEN_TAC [``u:num->real->bool``, ``c:num->real->bool``] THEN 22423 SIMP_TAC std_ss [FORALL_AND_THM] THEN STRIP_TAC THEN 22424 MATCH_MP_TAC(SET_RULE ``!s. s SUBSET t /\ ~(s = {}) ==> ~(t = {})``) THEN 22425 EXISTS_TAC ``BIGINTER {c n:real->bool | n IN univ(:num)}`` THEN 22426 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 22427 MATCH_MP_TAC COMPACT_NEST THEN ASM_REWRITE_TAC[] THEN 22428 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 22429 ONCE_REWRITE_TAC [METIS [] ``(c n SUBSET c m) = (\m n. c n SUBSET c m) m n``] THEN 22430 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SET_TAC[]]); 22431 22432val BAIRE_ALT = store_thm ("BAIRE_ALT", 22433 ``!g s:real->bool. 22434 locally compact s /\ ~(s = {}) /\ COUNTABLE g /\ (BIGUNION g = s) 22435 ==> ?t u. t IN g /\ open_in (subtopology euclidean s) u /\ 22436 u SUBSET (closure t)``, 22437 REPEAT STRIP_TAC THEN MP_TAC(ISPECL 22438 [``IMAGE (\t:real->bool. s DIFF closure t) g``, ``s:real->bool``] BAIRE) THEN 22439 ASM_SIMP_TAC std_ss [COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN 22440 MATCH_MP_TAC(TAUT `~q /\ (~r ==> p) ==> (p ==> q) ==> r`) THEN 22441 CONJ_TAC THENL 22442 [MATCH_MP_TAC(SET_RULE 22443 ``~(s = {}) /\ ((t = {}) ==> (closure t = {})) /\ (t = {}) 22444 ==> ~(s SUBSET closure t)``) THEN 22445 ASM_SIMP_TAC std_ss [CLOSURE_EMPTY] THEN 22446 MATCH_MP_TAC(SET_RULE ``i SUBSET s /\ (s DIFF i = s) ==> (i = {})``) THEN 22447 CONJ_TAC THENL [SIMP_TAC std_ss [BIGINTER_IMAGE] THEN ASM_SET_TAC[], ALL_TAC] THEN 22448 REWRITE_TAC[DIFF_BIGINTER] THEN 22449 REWRITE_TAC[SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN 22450 SIMP_TAC std_ss [SET_RULE ``s DIFF (s DIFF t) = s INTER t``] THEN 22451 REWRITE_TAC[SET_RULE ``{s INTER closure t | t IN g} = 22452 {s INTER t | t IN IMAGE closure g}``] THEN 22453 SIMP_TAC std_ss [GSYM INTER_BIGUNION, SET_RULE ``(s INTER t = s) <=> s SUBSET t``] THEN 22454 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN 22455 GEN_REWR_TAC (LAND_CONV o RAND_CONV) [GSYM IMAGE_ID] THEN 22456 MATCH_MP_TAC BIGUNION_MONO_IMAGE THEN SIMP_TAC std_ss [CLOSURE_SUBSET], 22457 SIMP_TAC std_ss [NOT_EXISTS_THM] THEN STRIP_TAC THEN 22458 X_GEN_TAC ``t:real->bool`` THEN REPEAT STRIP_TAC THENL 22459 [ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s DIFF (s INTER t)``] THEN 22460 MATCH_MP_TAC OPEN_IN_DIFF THEN 22461 ASM_SIMP_TAC std_ss [CLOSED_IN_CLOSED_INTER, CLOSED_CLOSURE, OPEN_IN_REFL], 22462 REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22463 REWRITE_TAC[CLOSURE_APPROACHABLE] THEN 22464 X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL 22465 [``t:real->bool``, ``s INTER ball(x:real,e)``]) THEN 22466 ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL, SUBSET_DEF, IN_INTER, IN_BALL, 22467 IN_DIFF] THEN 22468 METIS_TAC[DIST_SYM]]]); 22469 22470val NOWHERE_DENSE_COUNTABLE_BIGUNION_CLOSED = store_thm ("NOWHERE_DENSE_COUNTABLE_BIGUNION_CLOSED", 22471 ``!g:(real->bool)->bool. 22472 COUNTABLE g /\ (!s. s IN g ==> closed s /\ (interior s = {})) 22473 ==> (interior(BIGUNION g) = {})``, 22474 REPEAT STRIP_TAC THEN 22475 MP_TAC(ISPECL [``{univ(:real) DIFF s | s IN g}``, ``univ(:real)``] 22476 BAIRE) THEN 22477 SIMP_TAC std_ss [LOCALLY_COMPACT_UNIV, GSYM OPEN_IN, SUBTOPOLOGY_UNIV] THEN 22478 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN 22479 ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN 22480 ASM_SIMP_TAC std_ss [GSYM closed_def, SET_RULE 22481 ``UNIV SUBSET s <=> (UNIV DIFF s = {})``] THEN 22482 SIMP_TAC std_ss[GSYM INTERIOR_COMPLEMENT] THEN 22483 SIMP_TAC std_ss [IMAGE_DEF, GSYM BIGUNION_BIGINTER] THEN 22484 ASM_SIMP_TAC std_ss [SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``]); 22485 22486val NOWHERE_DENSE_COUNTABLE_BIGUNION = store_thm ("NOWHERE_DENSE_COUNTABLE_BIGUNION", 22487 ``!g:(real->bool)->bool. 22488 COUNTABLE g /\ (!s. s IN g ==> (interior(closure s) = {})) 22489 ==> (interior(BIGUNION g) = {})``, 22490 REPEAT STRIP_TAC THEN 22491 MP_TAC(ISPEC ``IMAGE closure (g:(real->bool)->bool)`` 22492 NOWHERE_DENSE_COUNTABLE_BIGUNION_CLOSED) THEN 22493 ASM_SIMP_TAC std_ss [COUNTABLE_IMAGE, FORALL_IN_IMAGE, CLOSED_CLOSURE] THEN 22494 MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (t = {}) ==> (s = {})``) THEN 22495 MATCH_MP_TAC SUBSET_INTERIOR THEN MATCH_MP_TAC BIGUNION_MONO THEN 22496 SIMP_TAC std_ss [EXISTS_IN_IMAGE] THEN MESON_TAC[CLOSURE_SUBSET]); 22497 22498(* ------------------------------------------------------------------------- *) 22499(* Partitions of unity subordinate to locally finite open coverings. *) 22500(* ------------------------------------------------------------------------- *) 22501 22502val SUBORDINATE_PARTITION_OF_UNITY = store_thm ("SUBORDINATE_PARTITION_OF_UNITY", 22503 ``!c s. s SUBSET BIGUNION c /\ (!u. u IN c ==> open u) /\ 22504 (!x. x IN s 22505 ==> ?v. open v /\ x IN v /\ 22506 FINITE {u | u IN c /\ ~(u INTER v = {})}) 22507 ==> ?f:(real->bool)->real->real. 22508 (!u. u IN c 22509 ==> f u continuous_on s /\ 22510 !x. x IN s ==> &0 <= f u x) /\ 22511 (!x u. u IN c /\ x IN s /\ ~(x IN u) ==> (f u x = &0)) /\ 22512 (!x. x IN s ==> (sum c (\u. f u x) = &1)) /\ 22513 (!x. x IN s 22514 ==> ?n. open n /\ x IN n /\ 22515 FINITE {u | u IN c /\ 22516 ~(!x. x IN n ==> (f u x = &0))})``, 22517 REPEAT STRIP_TAC THEN 22518 ASM_CASES_TAC ``?u:real->bool. u IN c /\ s SUBSET u`` THENL 22519 [FIRST_X_ASSUM(CHOOSE_THEN STRIP_ASSUME_TAC) THEN 22520 EXISTS_TAC ``\v:real->bool x:real. if v = u then &1 else &0:real`` THEN 22521 SIMP_TAC arith_ss [COND_RAND, COND_RATOR, o_DEF, REAL_POS, REAL_OF_NUM_EQ, 22522 METIS [] ``(if p then q else T) <=> p ==> q``] THEN 22523 ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CONST, COND_ID, SUM_DELTA] THEN 22524 CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN 22525 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22526 EXISTS_TAC ``ball(x:real,&1)`` THEN 22527 REWRITE_TAC[OPEN_BALL, CENTRE_IN_BALL, REAL_LT_01] THEN 22528 MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``{u:real->bool}`` THEN 22529 SIMP_TAC std_ss [FINITE_SING, SUBSET_DEF, GSPECIFICATION, IN_SING] THEN 22530 X_GEN_TAC ``v:real->bool`` THEN 22531 ASM_CASES_TAC ``v:real->bool = u`` THEN ASM_REWRITE_TAC[], 22532 ALL_TAC] THEN 22533 EXISTS_TAC ``\u:real->bool x:real. 22534 if x IN s 22535 then setdist({x},s DIFF u) / sum c (\v. setdist({x},s DIFF v)) 22536 else &0`` THEN 22537 SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE] THEN 22538 SIMP_TAC std_ss [SUM_POS_LE, SETDIST_POS_LE, REAL_LE_DIV] THEN 22539 SIMP_TAC std_ss [SETDIST_SING_IN_SET, IN_DIFF, real_div, REAL_MUL_LZERO] THEN 22540 SIMP_TAC std_ss [SUM_RMUL] THEN REWRITE_TAC[GSYM real_div] THEN 22541 MATCH_MP_TAC(TAUT `r /\ p /\ q ==> p /\ q /\ r`) THEN CONJ_TAC THENL 22542 [X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22543 FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 22544 DISCH_THEN (X_CHOOSE_TAC ``n:real->bool``) THEN EXISTS_TAC ``n:real->bool`` THEN 22545 POP_ASSUM MP_TAC THEN 22546 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 22547 ASM_REWRITE_TAC[] THEN 22548 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_FINITE_I) THEN 22549 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN X_GEN_TAC ``u:real->bool`` THEN 22550 ASM_CASES_TAC ``(u:real->bool) IN c`` THENL [ALL_TAC, METIS_TAC []] THEN 22551 ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN 22552 FULL_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN X_GEN_TAC ``y:real`` THEN CCONTR_TAC THEN 22553 FULL_SIMP_TAC std_ss [] THEN POP_ASSUM MP_TAC THEN 22554 REWRITE_TAC[real_div, REAL_ENTIRE] THEN 22555 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN 22556 ASM_CASES_TAC ``(y:real) IN u`` THEN 22557 ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, IN_DIFF, REAL_MUL_LZERO] THEN 22558 ASM_SET_TAC[], ALL_TAC] THEN 22559 SUBGOAL_THEN 22560 ``!v x:real. v IN c /\ x IN s /\ x IN v ==> &0 < setdist({x},s DIFF v)`` 22561 ASSUME_TAC THENL 22562 [REPEAT STRIP_TAC THEN 22563 SIMP_TAC std_ss [SETDIST_POS_LE, REAL_ARITH ``&0 < x <=> &0 <= x /\ ~(x = &0:real)``] THEN 22564 MP_TAC(ISPECL [``s:real->bool``, ``s DIFF v:real->bool``, ``x:real``] 22565 SETDIST_EQ_0_CLOSED_IN) THEN 22566 ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN 22567 ASM_SIMP_TAC std_ss [CLOSED_IN_CLOSED_INTER, GSYM OPEN_CLOSED] THEN 22568 DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[] THEN 22569 ASM_REWRITE_TAC[IN_INTER, IN_DIFF, IN_UNION] THEN ASM_SET_TAC[], 22570 ALL_TAC] THEN 22571 SUBGOAL_THEN 22572 ``!x:real. x IN s ==> &0 < sum c (\v. setdist ({x},s DIFF v))`` 22573 ASSUME_TAC THENL 22574 [X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22575 ONCE_REWRITE_TAC[GSYM SUM_SUPPORT] THEN 22576 REWRITE_TAC[support, NEUTRAL_REAL_ADD] THEN 22577 MATCH_MP_TAC SUM_POS_LT THEN SIMP_TAC std_ss [SETDIST_POS_LE] THEN 22578 CONJ_TAC THENL 22579 [FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN 22580 DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN 22581 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 22582 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_FINITE_I) THEN 22583 SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN X_GEN_TAC ``u:real->bool`` THEN 22584 ASM_CASES_TAC ``(x:real) IN u`` THEN 22585 ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, IN_DIFF] THEN ASM_SET_TAC[], 22586 UNDISCH_TAC `` s SUBSET BIGUNION c:real->bool`` THEN DISCH_TAC THEN 22587 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN 22588 DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN REWRITE_TAC[IN_BIGUNION] THEN 22589 ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN DISCH_THEN (X_CHOOSE_TAC ``t:real->bool``) THEN 22590 EXISTS_TAC ``t:real->bool`` THEN METIS_TAC[REAL_LT_IMP_NE]], 22591 ALL_TAC] THEN 22592 ASM_SIMP_TAC std_ss [REAL_LT_IMP_NE, REAL_DIV_REFL, o_DEF] THEN 22593 X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN 22594 MATCH_MP_TAC CONTINUOUS_ON_EQ THEN 22595 EXISTS_TAC ``\x:real. 22596 setdist({x},s DIFF u) / sum c (\v. setdist({x},s DIFF v))`` THEN 22597 SIMP_TAC std_ss [] THEN REWRITE_TAC[real_div] THEN 22598 ONCE_REWRITE_TAC [METIS [] 22599 ``(\x. setdist ({x},s DIFF u) * 22600 inv (sum c (\v. setdist ({x},s DIFF v)))) = 22601 (\x. (\x. setdist ({x},s DIFF u)) x * 22602 (\x. inv (sum c (\v. setdist ({x},s DIFF v)))) x)``] THEN 22603 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN 22604 SIMP_TAC std_ss [CONTINUOUS_ON_SETDIST, o_DEF] THEN 22605 ONCE_REWRITE_TAC [METIS [] 22606 ``(\x. inv (sum c (\v. setdist ({x},s DIFF v)))) = 22607 (\x. inv ((\x. sum c (\v. setdist ({x},s DIFF v))) x))``] THEN 22608 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN 22609 ASM_SIMP_TAC std_ss [REAL_LT_IMP_NE, CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN 22610 X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN 22611 FIRST_X_ASSUM(fn th => 22612 MP_TAC(SPEC ``x:real`` th) THEN ASM_REWRITE_TAC[] THEN 22613 DISCH_THEN(X_CHOOSE_THEN ``n:real->bool`` STRIP_ASSUME_TAC)) THEN 22614 MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN_OPEN_IN THEN 22615 MAP_EVERY EXISTS_TAC 22616 [``\x:real. sum {v | v IN c /\ ~(v INTER n = {})} 22617 (\v. setdist({x},s DIFF v))``, 22618 ``s INTER n:real->bool``] THEN 22619 ASM_SIMP_TAC std_ss [IN_INTER, OPEN_IN_OPEN_INTER] THEN CONJ_TAC THENL 22620 [X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN 22621 CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_EQ_SUPERSET THEN 22622 ASM_REWRITE_TAC[SUBSET_RESTRICT] THEN STRIP_TAC THENL 22623 [ASM_SET_TAC [], ALL_TAC] THEN X_GEN_TAC ``v:real->bool`` THEN 22624 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN 22625 ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN DISCH_TAC THEN 22626 MATCH_MP_TAC SETDIST_SING_IN_SET THEN ASM_SET_TAC[], 22627 ONCE_REWRITE_TAC [METIS [] 22628 ``(\x. sum {v | v IN c /\ v INTER n <> {}} 22629 (\v. setdist ({x},s DIFF v))) = 22630 (\x. sum {v | v IN c /\ v INTER n <> {}} 22631 (\v. (\v x. setdist ({x},s DIFF v)) v x))``] THEN 22632 MATCH_MP_TAC CONTINUOUS_SUM THEN 22633 ASM_SIMP_TAC std_ss [CONTINUOUS_AT_SETDIST, CONTINUOUS_AT_WITHIN]]); 22634 22635val _ = export_theory(); 22636