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